Compare commits

...
Author SHA1 Message Date
TabishB 79a45ac043 chore: capture workspace poc follow-up direction 2026-04-30 19:18:26 +10:00
TabishB 80f61a5550 feat: add workspace poc 2026-04-24 17:39:55 +10: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
e4c32dbe07 feat: add support for Pi (pi.dev) coding agent (#735)
* feat: add support for Pi (pi.dev) coding agent

Add Pi as a supported tool in OpenSpec with full adapter implementation.

Changes:
- Create pi.ts adapter for command generation
- Register adapter in registry and export from index
- Add Pi to AI_TOOLS config with .pi skills directory
- Add tests for piAdapter following existing patterns
- Update supported-tools.md documentation

Pi uses:
- Skills: .pi/skills/ (Agent Skills standard)
- Prompts: .pi/prompts/*.md (with description frontmatter)

Closes #732

* fix: add Pi to LEGACY_SLASH_COMMAND_PATHS for test compliance

* style: add trailing newline to pi.ts

* fix: correct legacy cleanup pattern for Pi (opsx-*.md not openspec-*.md)

* fix: add YAML escaping for Pi adapter to handle special characters in descriptions

- Add escapeYamlValue() function to properly escape YAML special characters
- Apply escaping to description field in frontmatter
- Add tests for YAML special character escaping (colons, quotes, newlines)

This follows the same pattern used by cursor, claude, and windsurf adapters.

* fix: remove Pi from LEGACY_SLASH_COMMAND_PATHS

Pi was never supported in pre-1.0 versions, so no legacy cleanup is needed.
Per reviewer feedback: this is only for tools from pre-1.0 OpenSpec.

* test: relax legacy-cleanup registry coverage invariant

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
Co-authored-by: TabishB <tabishbidiwale@gmail.com>
2026-02-21 15:34:40 -08:00
Tabish Bidiwale 2d4c98e196 Simplify profile sync + strengthen commands-only coverage (#736)
* Improve profile sync flows and add coverage for commands-only edge cases

* Fix migration workflow preservation and add coverage
2026-02-21 05:48:50 -08:00
Tabish Bidiwale be6659cd39 Add OpenSpec proposals for stacking, install scope, and command surfaces (#733)
* Add OpenSpec change proposals for stacking and scope

* Address review feedback across change proposals

* Preserve legacy install-scope behavior with migration path

* Address remaining review threads across spec proposals

* Address latest review feedback on split and command-surface specs

* Clarify split and composition semantics from latest review
2026-02-21 00:42:15 -08:00
Tabish Bidiwale 4ba26902df feat: simplify skill installation with profiles and smart defaults (#726)
* feat: implement simplified skill installation with profiles and smart defaults

Introduces a profile system (core/custom) to reduce the default workflow
count from 10 to 4, auto-detects AI tools during init, adds a new
`propose` workflow combining new+ff, fixes multi-select keybindings,
and adds backwards-compatible migration for existing users.

* feat: harden update config drift, command-only detection, and init profile validation

Address post-implementation review findings: update now detects profile/delivery
drift even when template versions are current, recognizes command-only installs
as configured tools, init validates --profile values and applies delivery cleanup
on re-init. Specs and design docs updated with new scenarios and rationale.

* fix: address AI reviewer feedback on config, detection, and test cleanup

- Add error handling for execSync in config profile apply and use static import
- Fix config list showing "(explicit)" for core profile workflows misleadingly
- Add missing 'openspec-onboard' to SKILL_NAMES for parity with COMMAND_IDS
- Remove unused fsSync import in init tests
- Fix configTempDir leak in test afterEach cleanup

* docs: add qa smoke harness change proposal
2026-02-19 18:21:06 -08:00
Tabish Bidiwale 5fd8e9d66c feat: simplify skill installation with profiles and smart defaults init (#719)
* feat: add change proposal for simplified skill installation

Introduces a change proposal to simplify the init flow and skill installation:

- Zero-question init with sensible defaults (core profile, both delivery)
- Auto-detect AI tools from existing directories (.claude/, .cursor/, etc.)
- Profile system: core (4 workflows), extended (11 workflows), custom
- Delivery config: both, skills, commands
- New `propose` workflow combining new + ff
- Fix tool selection UX (space to select, enter to confirm)

Key design decisions:
- Extend existing global config (~/.config/openspec/config.json)
- Profile install/uninstall immediately mutates filesystem
- Safe deletion via SKILL_NAMES and COMMAND_IDS constant lookups
- Filesystem as truth for installed workflows

Also adds rules to openspec/config.yaml to prevent overengineering
(explicit lookups over pattern matching).

* chore: add missing .openspec.yaml metadata file

* fix: address PR review feedback

Issues fixed:
- Clarify workflow count: extended = existing 10 + new propose = 11
- Rename spec: tool-auto-detection → available-tools (matches proposal)
- Change "identical" to "functionally equivalent" in propose spec
- Add profile change notification when install/uninstall changes profile
- Specify edge case: uninstall workflow from current non-custom profile
- Specify behavior when --apply-profile confirmation is declined
- Fix section numbering in design.md (6, 6a, 6b, 8)
- Add scaffolding verification tasks (verify .openspec.yaml exists)
- Specify case sensitivity mechanism: use fs.existsSync, let OS handle it

* fix: address CodeRabbit review comments

- Add language specifiers to fenced code blocks in proposal.md
- Add COMMAND_IDS update for propose in modified files list
- Make init success message tool-aware (colon vs hyphen syntax)
- Fix grammar: "Skills-only" and "Commands-only" in delivery-config
- Specify config get delivery output when field absent: "both (default)"
- Add profile set scenarios: config-only vs --apply-profile with filesystem mutation
- Add error scenarios for invalid profile name and unknown workflow
- Add scenario for existing config without profile field
- Mark active profile in profile list output
- Enumerate artifacts in propose basic scenario
- Fix propose equivalence to use skill syntax consistently
- Specify continue/create new branches in propose
- Remove out-of-scope command assertion from skill-generation spec
- Reference SKILL_NAMES constant instead of vague "existing templates"
- Fix design.md: SKILL_NAMES AND COMMAND_IDS (not "only")
- Specify overwrite semantics for refresh/update
- Add task 6.8: propose to COMMAND_IDS
- Fix function name: getAvailableTools() not detectInstalledTools()

* refactor: simplify skill installation design based on review

- Update design to use existing CLAUDE.md mechanisms
- Add cli-update spec for managing skill updates
- Clarify profile system and user config interactions
- Add explorations directory with design notes
- Update docs with clearer concepts

* docs: rename zero-question init to smart defaults init

Clarify that init auto-detects tools and asks for confirmation,
rather than being completely question-free. Update examples to
show the tool confirmation UI.

* docs: add explore workflow tasks and UX exploration

- Add tasks to update explore.ts references to /opsx:propose
- Create exploration note for deeper explore → propose UX questions
- Captures open questions about exploration artifacts, lifecycle,
  context handoff, and transition smoothness

* fix: address PR review feedback from 1code-async

- Add ## Purpose sections to all 10 spec files (required by schema)
- Add specs/ to propose workflow's first-time user guidance scenario
- Add --tools flag scenario for interactive mode in cli-init/spec.md
- Clarify that profile changes take effect on next init/update
- Fix design snippet to use AI_TOOLS config instead of TOOL_DIRS constant
- Add explicit Windsurf detection scenario to available-tools/spec.md
- Mark tasks 10.2-10.3 as follow-up work (out of scope)
- Fix capability name: init → cli-init in proposal.md
2026-02-18 02:11:35 -08:00
Tabish Bidiwale 4108563731 Bulk archive completed changes and normalize source specs (#716)
* chore: bulk archive completed changes and normalize specs

* docs: finalize spec purposes and align init workflow scenarios

* test: guard source specs against placeholders and delta headers

* docs: resolve remaining spec review nits
2026-02-16 21:28:27 -08:00
anilkmr-a2zandTabish Bidiwale fbef555041 feat: add Kiro CLI support (#707)
Add Kiro (AWS AI IDE) as a supported tool with command adapter
that writes to .kiro/prompts/ with YAML frontmatter.

- Add Kiro to AI_TOOLS registry in config.ts
- Create kiro.ts adapter (GitHub Copilot pattern)
- Register adapter in index.ts and registry.ts
- Add legacy cleanup path for migration
- Update supported-tools.md documentation

Generated with Kiro CLI using Claude Opus 4.6

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-02-16 08:34:42 +00:00
Tabish Bidiwale 92731e2263 refactor: split skill templates into workflow modules (#698)
* refactor: split skill templates into workflow modules

* fix: align template index exports and parity docs

* fix: add standard metadata to feedback skill template

* fix: add ff command guardrail for context and rules

* spec: add unified template generation pipeline proposal
2026-02-15 23:13:52 -08:00
1code-async[bot]andClaude Opus 4.6 c574e7992d docs: clarify GitHub Copilot CLI limitation for custom prompts (#676)
* docs: clarify GitHub Copilot CLI does not support custom prompt files

GitHub Copilot's .github/prompts/*.prompt.md files are only recognized
as custom slash commands in IDE extensions (VS Code, JetBrains, Visual
Studio). The Copilot CLI does not support them (github/copilot-cli#618).
This updates the docs to clarify the limitation and point users to the
.github/agents/ workaround.

Closes #671

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

* docs: use distinct footnote markers for Codex and Copilot

Addresses review feedback: the shared `*` marker was ambiguous across
Markdown renderers. Now uses `*` for Codex and `**` for Copilot.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-06 20:07:41 -08:00
pig 62d4391268 fix: improve Windows compatibility in tests (#646)
- Replace Unix 'cat' command with fs.readFile in spec.test.ts

- Replace 'mkdir -p' and 'bash' commands with fs.mkdir/writeFile in validate.enriched-output.test.ts

- Skip symlink test on Windows (requires admin privileges) in file-system.test.ts
2026-02-01 22:57:47 -08:00
Oleksandr Kruk 4573c28048 fix(docs): Update migration guide action diagram formatting (#644) 2026-02-01 16:03:06 -08:00
Tabish Bidiwale 0541f93ddd fix(onboard): add Windows PowerShell alternatives for shell commands (#638)
* fix(onboard): replace broken preflight check and add Windows compatibility

The onboarding preflight used `openspec status --json` to detect if a
project was initialized, but that command requires an existing change
to succeed. After a fresh `openspec init` (no changes yet), it always
failed — causing the onboarding to incorrectly tell users to run init
again.

Replace with `openspec --version` to verify the CLI is installed.

Also add Windows PowerShell alternatives for all platform-specific
shell commands in the onboarding skill:
- `2>&1 ||` → `; if ($LASTEXITCODE -ne 0) {}`
- `2>/dev/null` → `2>$null`
- `mkdir -p` → `New-Item -ItemType Directory -Force`

* fix(onboard): address PR review feedback for PowerShell commands

Use Get-Command for robust CLI detection instead of $LASTEXITCODE
(which stays stale when a command isn't found), and use forward slashes
in PowerShell paths for consistency with Unix commands.
2026-01-31 19:30:43 -08:00
Tabish Bidiwale be51bcbc6a fix(onboard): replace broken preflight check with direct config file test (#637)
The onboarding preflight used `openspec status --json` to detect if a
project was initialized, but that command requires an existing change
to succeed. After a fresh `openspec init` (no changes yet), it always
failed — causing the onboarding to incorrectly tell users to run init
again.

Replace with two targeted checks:
- `openspec --version` to verify the CLI is installed
- `test -f openspec/config.yaml` to verify project initialization
2026-01-31 18:46:50 -08:00
CodingVillainandClaude Opus 4.5 1d34e72f10 fix: use Skill tool for sync invocation in archive templates (#632)
* fix: use Skill tool for sync invocation in archive templates

Update archive skill templates to properly instruct the AI to use
the Skill tool to invoke sync commands instead of executing command
logic directly.

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

* fix: use Task tool subagent for sync in archive templates

Skill tool terminates after completion and doesn't return control to the
caller, causing archive to not continue after sync. Changed to spawn a
subagent via Task tool which properly returns control after completion.

Also updated opsx:sync references to openspec-sync-specs for semantic
coherence across templates.

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 18:23:44 -08:00
openspec-release-bot[bot]andgithub-actions[bot] 36fbc898da Version Packages (#628)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-30 14:55:43 -08:00
Tabish Bidiwale afb73cf9ec Add changeset for OpenCode command reference fix (#627) 2026-01-30 14:27:05 -08:00
Rodrigo Passos 697738bc9b fix(opencode): transform command references from colon to hyphen format (#626)
* Add OpenCode files to gitignore

* docs(changes): add opencode-command-references change artifacts

* fix(opencode): transform command references from colon to hyphen format
2026-01-30 13:51:47 -08:00
openspec-release-bot[bot]andgithub-actions[bot] 37686944a9 Version Packages (#606)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-30 02:27:45 -08:00
Tabish Bidiwale 53081fb2a2 Add changeset for combined v1.0.2+ fixes (#625) 2026-01-30 02:22:17 -08:00
Tabish Bidiwale 5e2e02c090 fix: use path.resolve in Codex adapter test for Windows compatibility (#624)
The test expected path.join('/custom/codex-home', ...) but the
implementation uses path.resolve() which adds the drive letter on
Windows (e.g. D:\). Align the test expectation with the implementation.
2026-01-30 02:14:17 -08:00
Tabish Bidiwale a3cee3c2f2 Revert "feat: add openspec dashboard command for web-based project browsing (#615)" (#623)
This reverts commit f45ba73a5f.
2026-01-30 02:06:17 -08:00
Tabish Bidiwale f27e5e809a feat: support global paths for Codex command generation (#622)
* feat: support global paths for Codex command generation

Codex custom prompts live in ~/.codex/prompts/ (global, not per-project).
Update the Codex adapter to return absolute paths via os.homedir(), handle
absolute paths in init/update writers, and update docs and specs to reflect
the change.

* fix: address review feedback on Codex global paths

- Guard against empty CODEX_HOME resolving to CWD by trimming the env var
- Loosen test regex to not depend on .codex prefix (resilient to custom CODEX_HOME)
- Clarify non-goal wording in design.md to avoid contradictory phrasing
2026-01-30 01:51:00 -08:00
6b545f6ebb fix: add slash command hints in workflow completion messages (#603)
When artifacts or tasks are complete, the command templates now
suggest specific slash commands (/opsx:apply, /opsx:archive) instead
of generic guidance, helping users discover the next workflow step.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-29 20:20:28 -08:00
yangjunandTabish Bidiwale 661059b54f Update Windsurf file path from commands to workflows (#610)
* fix windsurf workrules

* fix a missing update

---------

Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2026-01-29 18:02:30 -08:00
Haven-SandTabish Bidiwale ddbfa529f4 docs: modernize opsx.md (#616)
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-29 17:38:23 -08:00
Costica Puntaru [Tica]andTabish Bidiwale d3c3d66e67 fix(archive): fall back to copy+remove on EPERM/EXDEV (fixes #197) (#605)
On Windows, fs.rename() often fails with EPERM when moving non-empty
directories. Fall back to recursive copy then rm when rename throws
EPERM or EXDEV so 'openspec archive' succeeds where Move-Item works.

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-29 17:26:58 -08:00
moe1214andTabish Bidiwale 277be194ef docs: support Trae AI (#601)
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-29 17:23:30 -08:00
Tabish Bidiwale f45ba73a5f feat: add openspec dashboard command for web-based project browsing (#615)
Implements a new `openspec dashboard` command that serves a local HTTP server with a web-based dashboard for exploring changes, specs, and archive. Features include:
- Three-tab navigation for Changes, Specifications, and Archive
- Click artifacts to view rendered markdown in a detail panel
- Domain-grouped specs with requirement counts
- Task progress tracking for active changes
- Artifact status indicators (proposal, specs, design, tasks)
- Archive pagination with reverse chronological sorting
- Zero external dependencies (Node.js built-in http module)
- Port auto-increment (3000-3010) with --port override
- Cross-platform browser opening (macOS, Linux, Windows)
- Path traversal prevention on artifact API

Includes comprehensive tests for markdown renderer, data gathering, and API security (43 tests, all passing).
2026-01-29 16:45:07 -08:00
Tabish Bidiwale 41305753b4 Fix schema listing command in migration guide (#608) 2026-01-27 19:59:47 -08:00
Jérôme BenoitandTabish Bidiwale 86d2e04cae chore(nix): improve flake with dynamic version and build optimization (#550)
* chore(nix): improve flake with dynamic version and source filtering

- Read version dynamically from package.json instead of hardcoding
- Add lib.fileset source filtering to exclude node_modules and build artifacts
- Update update-flake.sh to support dynamic version pattern
- Add hash change detection to skip unnecessary rebuilds
- Improve error handling with automatic rollback on failure
- Update specs to reflect dynamic version behavior

* chore(ci): bump Nix actions to latest versions

- nix-installer-action: v13 → v21
- magic-nix-cache-action: v8 → v13
- Update validation message for unchanged flake.nix

* chore: add changeset for Nix improvements

* fix(nix): make update-flake.sh portable to macOS

- Fix grep pattern on line 37 to include opening parenthesis
- Replace GNU grep -oP with portable sed alternatives (lines 53, 68, 70)
- Ensures script works on both Linux and macOS (BSD sed/grep)

* fix(nix): properly check build verification exit status

Fix logic bug where build failures were incorrectly reported as success.
The script now:
- Captures build exit code and output separately
- Fails fast if build returns non-zero exit code
- Only checks for 'dirty tree' warning if build succeeded

This addresses CodeRabbit review feedback on line 101-107.

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-27 14:23:11 -08:00
openspec-release-bot[bot]andgithub-actions[bot] f6b415cb9b Version Packages (#597)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-26 19:33:25 -08:00
Tabish Bidiwale e91568deb9 Add changeset for spec naming clarification (#596) 2026-01-26 19:12:01 -08:00
Tabish Bidiwale fc0d798f93 fix: clarify spec naming convention and task checkbox format (#595)
* fix: clarify spec naming convention and task checkbox format

- Update docs, schema, and templates to clarify that specs should be
  named after capabilities (specs/<capability>/spec.md), not changes
- Emphasize that tasks MUST use checkbox format for apply phase tracking

* fix: clarify delta spec location for modified capabilities

Address review feedback: explicitly state that the delta spec is created
at specs/<capability>/spec.md, not in openspec/specs/<capability>/.
2026-01-26 18:12:56 -08:00
openspec-release-bot[bot]andgithub-actions[bot] d155126235 Version Packages (#588)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-26 02:51:24 -08:00
Tabish Bidiwale 943e0d4102 Add changeset for archive path fix (#587) 2026-01-26 02:47:28 -08:00
Tabish Bidiwale 12a7224dc6 chore: remove TDD schema and all references (#586)
* chore: remove TDD schema and all references

TDD was an internal test example that should not be in user-facing docs.
This removes:
- The schemas/tdd directory and all its templates
- All TDD references from documentation
- TDD examples from skill templates and source code comments

* test: update tests to remove TDD schema references

All tests that referenced the removed TDD schema have been updated
to use spec-driven or custom-schema names instead.

* chore: remove accidentally committed files
2026-01-26 02:31:48 -08:00
Tabish Bidiwale c773ef6feb fix: correct archive path in onboarding template (#585)
The onboarding template incorrectly documented the archive path as
`openspec/archive/YYYY-MM-DD--<name>/` when the actual implementation
uses `openspec/changes/archive/YYYY-MM-DD-<name>/`.

This fixes two issues:
- Missing `changes/` directory in the path
- Double dash `--` instead of single dash `-`

Fixes discussion #583
2026-01-26 02:04:46 -08:00
Tabish Bidiwale 0bfe1d4426 docs: rewrite customization guide to document schema commands (#582)
* docs: rewrite customization guide to document schema commands

The old guide described a painful manual process for schema customization
(mkdir, npm list, cp commands) and even listed "No scaffolding" as a
limitation. But the `openspec schema` commands have existed for a while:

- `schema fork` - copy existing schema to customize
- `schema init` - create new schema from scratch
- `schema validate` - check schema structure
- `schema which` - debug resolution precedence

Rewrote the guide to:
- Lead with the actual CLI commands instead of manual steps
- Remove the misleading "Current Limitations" section
- Add practical examples (TDD workflow, adding review artifact)
- Structure progressively: config → custom schemas → global overrides

* docs: add language tags to code blocks in customization guide

Address review feedback from CodeRabbit:
- Add 'text' language tag to directory tree code blocks
- Satisfies MD040 markdown lint rule
2026-01-25 23:37:46 -08:00
openspec-release-bot[bot]andgithub-actions[bot] 0e6f42c81c Version Packages (#579)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-25 16:09:16 -08:00
Tabish Bidiwale 0cc9d9025a chore: add changeset for 1.0.0 release (#578)
* Add changeset for v0.24.0 features

* Replace changeset with 1.0.0 release notes

Update from minor to major version bump. Rewrite release notes to
properly capture the OPSX workflow changes:

- Dynamic instructions based on artifact state
- Semantic spec syncing with ADDED/MODIFIED/REMOVED parsing
- Step-through artifacts with /opsx:continue
- Skills support alongside tool commands
- Breaking: old /openspec:* commands removed

* Rewrite 1.0.0 changeset with comprehensive release notes

Based on deep research into old vs new workflow:

Old workflow:
- 3 phase-locked commands (proposal → apply → archive)
- 8+ config files scattered at project root
- Static prompts, same instructions every time
- Text-based spec merging

New OPSX workflow:
- 10 action-based commands (do any action anytime)
- Dynamic instructions (context + rules + template layers)
- Artifact graph with dependency awareness
- Semantic spec syncing (ADDED/MODIFIED/REMOVED/RENAMED)
- Agent Skills standard for cross-editor compatibility
- 21 AI tools supported
- Onboarding skill for guided first experience
2026-01-25 16:04:10 -08:00
Tabish Bidiwale 3261ccf6dc feat: onboarding skill and comprehensive documentation overhaul (#574)
* feat(skills): add opsx:onboard guided workflow skill

Add a new onboard skill that walks users through their first complete
OpenSpec workflow cycle. The skill provides interactive guidance through
task selection, change creation, artifact building, implementation, and
archiving.

Also includes:
- New README with updated branding and workflow examples
- Documentation structure placeholders
- Change artifacts for the onboard skill feature

* test(skills): update skill-generation tests for onboard skill

Update test expectations from 9 to 10 skills after adding opsx:onboard.

* docs: update README links and add doc cleanup checklist

- Replace placeholder links in README_NEW.md with actual doc paths
- Add documentation cleanup checklist to README_RENEWAL_PROMPTS.md

* docs: overhaul documentation with new workflows, getting-started, and customization guides

- Rewrite workflows.md with action-based philosophy and workflow patterns
- Rewrite getting-started.md with clearer onboarding flow
- Rewrite customization.md with schema customization guidance
- Add cross-references between docs (Commands, Customization links)
- Remove obsolete docs: artifact_poc, experimental-release-plan, project-config-demo, schema-customization, schema-workflow-gaps
- Update README_RENEWAL_PROMPTS.md checklist

* docs: continue documentation overhaul with expanded guides and restructuring

- Expand cli.md, commands.md, and concepts.md with comprehensive content
- Add installation.md, multi-language.md, and supported-tools.md
- Rename experimental-workflow.md to opsx.md
- Remove i18n.md (replaced by multi-language.md)
- Update README links and cleanup prompts

* chore(assets): consolidate logo images

* docs: enhance README with badges, usage notes, and contributing guidelines

- Update Discord badge to show member count
- Add collapsible section with stars/downloads/contributors badges
- Add OpenSpec Dashboard preview section
- Add usage notes for model selection and context hygiene
- Expand contributing section with guidelines for small/large changes
- Clarify AI-generated code policy

* docs: remove misleading mid-flight update claims

The documentation claimed users could edit artifacts mid-implementation
and seamlessly continue, but no such mechanism exists. This removes:

- "Mid-Flight Correction" section from workflows.md
- Feedback arrows and "update as you learn" from all diagrams
- Mid-flight claims from commands.md, opsx.md, concepts.md
- Example blocks showing edit-then-continue workflow

Also adds a proposal for future artifact regeneration support that
would actually make this workflow possible.

* docs: fix PR review comments (markdown linting and accuracy)

- Add language tags to fenced code blocks (MD040)
- Remove blank line between blockquotes (MD028)
- Capitalize "Markdown" as proper noun
- Update deprecated command reference (experimental -> update)
- Update skill count from 9 to 10, add openspec-onboard
- Fix typo: fix-midlight -> fix-midflight

* chore: remove polish-release-notes CI workflow

Replaced with local /polish-release skill. The claude-code-action
doesn't work well with repository_dispatch triggers (no PR context).

* docs: clarify /opsx:sync is optional (archive prompts if needed)

Remove sync from main workflow flows and diagrams since archive
already prompts to sync when needed. Most users will never need
to call sync directly.

- Remove sync from completion flow diagrams
- Remove "Sync Specs Regularly" best practice section
- Update command descriptions to note it's optional
- Update "When to sync" to "When to use manually"

* docs: redesign README with simplified content and new OPSX callout

- Simplify badges and logo presentation
- Add collapsible "most loved" section
- Replace detailed explanation with concise philosophy
- Add prominent /opsx:onboard callout for new workflow
- Remove README_NEW.md (content merged into README.md)
- Remove renewal prompts documentation

* docs: add README_OLD.md as reference backup

* docs: fix command directory paths for multiple tools

Correct commands locations for Antigravity, Codex, Crush, OpenCode,
and Qoder in the supported tools table.
2026-01-25 15:43:52 -08:00
zhing2006andClaude Opus 4.5 26ed336a16 fix: correct regex trailing whitespace and add missing projectRoot param (#575)
- Add \s* to parseTasksFile regex to handle trailing whitespace in task lines
- Add missing projectRoot argument to resolveSchema call in generateApplyInstructions

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 18:48:05 -08:00
Tabish Bidiwale 847aa81c0f revert: undo README update from init merge (premature) (#567)
Reverts the README documentation changes that were included in PR #565.
These changes document features that aren't released yet.

A separate PR will be opened to re-apply these changes when the package
is released.
2026-01-23 20:06:22 -08:00
Tabish Bidiwale 39bebefcc4 feat(cli): merge init and experimental commands (#565)
* feat(core): add legacy cleanup detection functions for init migration

Implement src/core/legacy-cleanup.ts with detection and cleanup functions
for all legacy OpenSpec artifact types:

Detection functions:
- detectLegacyConfigFiles() - checks for config files with OpenSpec markers
  (CLAUDE.md, CLINE.md, CODEBUDDY.md, COSTRICT.md, QODER.md, IFLOW.md,
  AGENTS.md, QWEN.md)
- detectLegacySlashCommands() - checks for old /openspec:* command
  directories and files across all 21 tool integrations
- detectLegacyStructureFiles() - checks for openspec/AGENTS.md and
  openspec/project.md (project.md preserved for migration hint)
- detectLegacyArtifacts() - orchestrates all detection

Utility functions:
- hasOpenSpecMarkers() - checks if content has OpenSpec markers
- isOnlyOpenSpecContent() - checks if file is 100% OpenSpec content
- removeMarkerBlock() - surgically removes marker blocks from mixed content

Cleanup functions:
- cleanupLegacyArtifacts() - orchestrates removal with proper edge cases:
  - Deletes files that are 100% OpenSpec content
  - Removes marker blocks from files with mixed content
  - Deletes legacy slash command directories and files
  - Preserves openspec/project.md (shows migration hint only)

Formatting functions:
- formatDetectionSummary() - formats what was detected before cleanup
- formatCleanupSummary() - formats what was cleaned up after

This is task 1.1 for the merge-init-experimental change.

* feat(utils): add removeMarkerBlock() for surgically removing marker blocks

- Add removeMarkerBlock() function to file-system.ts that properly handles
  inline marker mentions by using findMarkerIndex/isMarkerOnOwnLine
- Refactor legacy-cleanup.ts to use the shared utility
- Export removeMarkerBlock from utils/index.ts for reusability
- Add comprehensive tests for inline marker mention edge cases
- Add tests for shell-style markers and various whitespace scenarios

The new implementation correctly ignores markers mentioned inline within
text and only removes actual marker blocks that are on their own lines.

* feat(core): add formatProjectMdMigrationHint() for migration messaging

- Add standalone formatProjectMdMigrationHint() function for reusable
  migration hint output directing users to migrate project.md content
  to config.yaml's "context:" field
- Update formatDetectionSummary() to include the migration hint when
  project.md is detected (not just in cleanup summary)
- Refactor formatCleanupSummary() to use the new function for
  consistency
- Add unit tests for the new function and updated behavior

* test(init): rewrite init tests for experimental workflow approach

Rewrites the init command tests to verify the new experimental workflow
implementation. The new tests cover:

- OpenSpec directory structure creation (specs, changes, archive)
- config.yaml generation with default schema
- 9 Agent Skills creation for various tools (Claude, Cursor, Windsurf, etc.)
- 9 slash commands generation using tool-specific adapters
- Multi-tool support (--tools all, --tools none, specific tools)
- Extend mode (re-running init)
- Tool-specific adapters (Gemini TOML, Continue .prompt, etc.)
- Error handling for invalid tools and permissions

Removes old tests for legacy config file generation (AGENTS.md, CLAUDE.md,
project.md, etc.) as the new init command uses Agent Skills instead.

* test(update): rewrite tests for skills/commands refresh behavior

Update the update command tests to match the new implementation that
refreshes skills and opsx commands instead of config files.

Changes:
- Remove old ToolRegistry import (deleted module)
- Rewrite tests to verify skill file updates
- Rewrite tests to verify opsx command generation
- Add tests for multi-tool support (Claude, Cursor, Qwen, Windsurf)
- Add tests for error handling and tool detection
- Fix test assertions to match actual skill template names

The update command now:
- Detects configured tools by checking skill directories
- Updates SKILL.md files with latest skill templates
- Generates opsx commands using tool-specific adapters

* docs(readme): update documentation for new init behavior

- Replace tool list with simplified supported tools section (skills-based)
- Update init instructions to document --tools flag, --force, and legacy cleanup
- Replace project.md with config.yaml documentation
- Update workflow examples to use /opsx:* commands instead of /openspec:*
- Add command reference table for slash commands
- Update Team Adoption and Updating sections for new workflow
- Replace Experimental Features with Workflow Customization section

* refactor(cli): remove legacy configurators and merge experimental into workflow

- Delete src/core/configurators/ directory (ToolRegistry, all config generators)
- Delete legacy templates (agents-template, claude-template, project-template, etc.)
- Move experimental commands to src/commands/workflow/ with cleaner structure
- Remove experimental setup.ts and index.ts (functionality merged into init)
- Update CLI to register workflow commands directly instead of through experimental
- Update openspec update command to refresh skills/commands instead of config files
- Update tests for new command structure

* refactor: extract shared modules and move AGENTS.md to root

- Move AGENTS.md from openspec/ to project root
- Add shared module with tool-detection and skill-generation utilities
- Update legacy-cleanup with improved cleanup logic
- Enhance update.ts with additional functionality
- Add comprehensive tests for shared modules

* fix(ui): update welcome screen tagline

Change from experimental reference to reflect the merged workflow.

* fix: improve Windows cross-platform compatibility

- Handle both forward and backward slashes in path parsing
- Normalize paths before regex matching for legacy artifact detection
- Use regex split for both path separators in tool directory extraction
- Handle CRLF line endings when cleaning up multiple blank lines
- Add retry logic for test file cleanup to handle Windows file locking

* fix(init): use dynamic counts for skills and commands in success message

Replace hard-coded "9 skills and 9 commands" with dynamic values from
getSkillTemplates().length and getCommandContents().length to prevent
the message from diverging from reality when skills/commands change.

* fix: various small improvements across init, cleanup, and file handling

- Remove shell prompt characters from README bash examples (MD014)
- Show actual config filename (config.yaml vs config.yml) in init output
- Include hasProjectMd in hasLegacyArtifacts to show migration hint
- Add existence check before AGENTS.md deletion to avoid spurious errors
- Preserve leading whitespace and original newline style in file operations
- Use dynamic tool list from CommandAdapterRegistry in tests
2026-01-23 19:51:31 -08:00
Tabish Bidiwale cf8b6212c8 feat(cli): merge init and experimental commands (#564)
* feat(cli): add change proposal to merge init and experimental commands

This change merges `openspec init` and `openspec experimental` into a
single command that uses the skill-based workflow as the default.

Key changes:
- BREAKING: init generates skills and /opsx:* commands instead of config files
- BREAKING: Config files (CLAUDE.md, .cursorrules, etc.) no longer generated
- BREAKING: Old slash commands (/openspec:proposal, etc.) no longer generated
- BREAKING: openspec/AGENTS.md and project.md no longer generated
- Add legacy detection and cleanup with Y/N confirmation
- Keep experimental as hidden alias for backward compatibility

Artifacts:
- proposal.md: Motivation and scope
- design.md: Architecture decisions and edge case handling
- specs/legacy-cleanup/spec.md: New capability for legacy artifact cleanup
- specs/cli-init/spec.md: Modified init spec with skill-based workflow
- tasks.md: 37 implementation tasks across 7 groups

* docs(change): preserve project.md with migration hint instead of deleting

Update merge-init-experimental change artifacts to preserve openspec/project.md
during legacy cleanup instead of auto-deleting it. Users will see a migration
hint directing them to move content to config.yaml's context field.

Changes:
- design.md: Add Decision 6 documenting rationale and migration path
- spec.md: Add project.md migration hint requirement and scenarios
- tasks.md: Add task 1.7 for migration hint output

This avoids losing user-written project documentation while guiding them
to the new config.yaml approach.

* docs(change): resolve open questions about update command and experimental labels
2026-01-22 23:15:18 -08:00
Tabish Bidiwale c157483685 feat(skills): add Agent Skills spec optional metadata fields (#563)
Add optional fields to SkillTemplate interface and all skill templates
to improve compliance with the Agent Skills specification:

- license: MIT (matching project license)
- compatibility: Requires openspec CLI.
- metadata: { author: openspec, version: 1.0 }

Updates skill file generation to include these fields in YAML frontmatter.
2026-01-22 22:25:46 -08:00
Tabish Bidiwale f90c7c3354 refactor(commands): modularize artifact workflow into separate files (#562)
* refactor(commands): modularize artifact workflow into separate files

Split the monolithic artifact-workflow.ts into separate modules under
src/commands/experimental/:
- index.ts: main exports and command registration
- status.ts: status display logic
- new-change.ts: change creation logic
- schemas.ts: Zod schemas
- setup.ts: setup command logic
- templates.ts: template generation
- shared.ts: shared utilities
- instructions.ts: instruction generation

Also extracted init wizard logic to src/core/init/wizard.ts.

* fix(commands): address code review feedback from PR #562

- Fix template source detection using path.relative instead of startsWith
  to prevent misclassification of paths with shared prefixes
- Fix config file log message to show actual file name (config.yaml vs config.yml)
- Fix selectedTools option to be honored when provided programmatically
2026-01-22 21:21:05 -08:00
Tabish Bidiwale 9381bd3b24 feat(cli): improve artifact experimental setup with refresh detection (#561)
* feat(cli): improve artifact experimental setup with refresh detection

- Add functions to detect which tools already have experimental skills configured
- Pre-select configured tools in interactive mode for easy refresh
- Sort configured tools to appear first in the selection list
- Show "(refresh)" indicator for already-configured tools in selection
- Distinguish between "Created" and "Refreshed" tools in output
- Streamline success output to be more concise and scannable

* test: update experimental command test assertions for new output format

The output format changed from '.claude/skills/' to '.claude/' (showing
summary counts instead of directory paths), so update assertions to match.

* feat(cli): rename artifact-experimental-setup to experimental

Shorter command name for better usability. Updates command registration,
documentation, and README references.
2026-01-22 20:13:06 -08:00
Tabish Bidiwale ae83b4e16d feat(cli): add interactive UI for artifact experimental setup (#560)
* feat(cli): add interactive UI for artifact experimental setup

Add animated welcome screen and searchable multi-select prompt when
running `openspec artifact-experimental-setup` without the --tool flag
in interactive mode. Users can now browse and select multiple tools
for setup instead of requiring the --tool flag.

- Add welcome screen with ASCII art animation
- Add searchable multi-select prompt component
- Support multi-tool setup in single command invocation

* fix(nix): update flake version and reset hash for rebuild

- Update version from 0.20.0 to 0.23.0 to match package.json
- Set pnpmDeps hash to empty string to trigger rebuild
- Fix update-flake.sh to work on macOS (use portable grep/sed)

CI will fail with correct hash which we'll then apply.

* fix(nix): set correct pnpmDeps hash

* feat(cli): improve error handling for multi-tool setup

- Continue setup for remaining tools when one fails
- Collect and report all failures at the end
- Only throw if all tools fail
- Show partial success summary (configured vs failed)
2026-01-22 18:39:38 -08:00
Tabish Bidiwale d48528134b feat(cli): add multi-provider skill generation support (#556)
* feat(cli): add multi-provider skill generation support

Add --tool flag to artifact-experimental-setup command to generate
skills and commands for different AI tools (Claude, Cursor, Windsurf).

- Add skillsDir field to AIToolOption interface
- Create command-generation module with tool-specific adapters
- Each adapter handles tool-specific file paths and frontmatter formats
- Add CommandAdapterRegistry for adapter lookup
- Update artifact-experimental-setup to use dynamic paths

* feat(config): add skillsDir for all supported AI tools

Add skillsDir mappings for tools that were missing:
- Amazon Q Developer (.amazonq)
- Antigravity (.agent)
- Auggie (.augment)
- Cline (.cline)
- CodeBuddy Code (.codebuddy)
- Continue (.continue)
- CoStrict (.cospec)
- Crush (.crush)
- iFlow (.iflow)
- Qoder (.qoder)
- Qwen Code (.qwen)

Fix RooCode path: .roocode → .roo

* feat(adapters): add command adapters for all supported AI tools

Add 18 new command adapters covering all supported AI tools in the
multi-provider skill generation system. Each adapter implements the
correct file path and frontmatter format for its respective tool.

New adapters: amazon-q, antigravity, auggie, cline, codex, codebuddy,
continue, costrict, crush, factory, gemini, github-copilot, iflow,
kilocode, opencode, qoder, qwen, roocode.

* fix(adapters): address PR review feedback

- Change .requiredOption to .option for custom error handling with tool list
- Add YAML escaping for special characters in all command adapters
- Normalize path separators in tests for cross-platform compatibility
- Update docs: --tool flag is required, not optional with default
- Add missing Windsurf adapter scenario to spec
- Fix spec headers and language specifiers
2026-01-21 23:32:06 -08:00
Tabish Bidiwale 54bd3f1ccd fix(docs): update invalid Discord link in experimental workflow (#555) 2026-01-21 15:04:09 -08:00
QraffaandTabish Bidiwale 675e870bf1 style: remove unnecessary whitespace (#554)
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-21 14:52:27 -08:00
Alexey StepanovandTabish Bidiwale 07eaf7b691 fix(claude): replace colon with dash in slash command frontmatter names (#553)
Claude Code's YAML parser fails when the `name` field contains a colon (e.g., `name: OpenSpec: Proposal`), causing it to fall back to the first content line as the description, showing `<!-- OPENSPEC:START -->`.

Changes:
  - Replace `OpenSpec: Proposal` with `OpenSpec - Proposal` in claude.ts
  - Add `shouldRefreshFrontmatter()` hook to allow updating existing files
  - Extract `buildContent()` helper method for DRY
  - Update test expectations for Claude configurator

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-21 14:36:16 -08:00
153721d14a Add /opsx:bulk-archive to experimental workflow setup command output (#551)
* Add /opsx:bulk-archive to experimental workflow setup command

* Update src/commands/artifact-workflow.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-21 13:03:24 -08:00
mingcao-devandpengjiahan.pjh 70c2e17525 chore: rename "Qoder (CLI)" to "Qoder" (#552)
- Update tool name in config.ts
- Update README.md documentation and docs link

Co-authored-by: pengjiahan.pjh <pengjiahan.pjh@antgroup.com>
2026-01-21 13:00:43 -08:00
Tabish Bidiwale e2c333e493 fix(instructions): separate context and rules from template in JSON output (#547)
* fix(instructions): separate context and rules from template in JSON output

Previously, project config context and rules were prepended to the template
field in artifact instructions. This caused AI assistants to literally copy
these constraint blocks into generated artifact files, rather than treating
them as instructions.

Changes:
- Add `context` and `rules` as separate fields in ArtifactInstructions interface
- Update generateInstructions() to populate these as distinct fields
- Update CLI output to display context/rules with clear "do not include" comments
- Rename <context> (dependencies) to <dependencies> to avoid confusion
- Update tests for new structure

The JSON output from `openspec instructions` now clearly separates:
- `context`: Project background (constraints for AI)
- `rules`: Artifact-specific rules (constraints for AI)
- `template`: The actual structure for the output file

* fix(skills): update skill templates with separate context/rules documentation

Update generated skill templates (continue-change, ff-change) to document
that context and rules are separate JSON fields that should NOT be copied
into artifact output files.

Users running `openspec update` will get the updated skill instructions.
2026-01-20 20:52:07 -08:00
Tabish Bidiwale e137dd3981 fix(ci): use repository_dispatch for polish release notes (#545)
The GitHub App token doesn't have actions:write permission, which is
required for workflow_dispatch. Switch to repository_dispatch which
works with existing contents:write permission.

Changes:
- release-prepare.yml: Use gh api to trigger repository_dispatch
- polish-release-notes.yml: Add repository_dispatch trigger type
- Delete test workflow (validation complete)

Tested via PR #542 - both workflow_dispatch and repository_dispatch
triggers work correctly with claude-code-action.
2026-01-20 20:03:56 -08:00
Tabish Bidiwale 2beb8e77e8 test: add temporary workflow to validate repository_dispatch (#542)
This is a dry-run workflow to test repository_dispatch before modifying
the release pipeline. Will be deleted after validation.
2026-01-20 19:01:23 -08:00
openspec-release-bot[bot]andgithub-actions[bot] 3b16b13613 Version Packages (#541)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-20 17:21:29 -08:00
Tabish Bidiwale c4cfdc7c49 Add changeset for bulk-archive skill and setup simplification (#540) 2026-01-20 17:17:31 -08:00
Tabish Bidiwale e0736807b4 refactor(setup): simplify config creation and fix test hanging (#537)
* refactor(setup): simplify config creation and fix test hanging

- Replace interactive config prompts with automatic config creation using
  default schema. The generated config includes helpful comments explaining
  context and rules options.
- Remove unused promptForConfig, promptForArtifactRules, and isExitPromptError
  functions from config-prompts.ts
- Add forceExit: true to vitest config to prevent worker processes from hanging
  after tests complete

* docs: add schema-alias-support change proposal

Proposal to add schema alias support so `openspec-default` and `spec-driven`
can be used interchangeably, enabling a rename without breaking existing configs.

* fix(test): remove invalid forceExit config and add proper teardown

- Remove `forceExit: true` from vitest.config.ts (Jest option, not Vitest)
- Add actual teardown logic in vitest.setup.ts that forces exit after 1s
  grace period if processes are still hanging
2026-01-20 14:32:56 -08:00
Tabish Bidiwale fdb05a723e feat(skills): add bulk-archive skill for archiving multiple changes (#527)
Add `/opsx:bulk-archive` skill that allows archiving multiple completed
changes in a single operation. Features include:

- Multi-select change selection via AskUserQuestion
- Batch validation of artifacts, tasks, and delta specs
- Spec conflict detection when multiple changes touch same capability
- Agentic conflict resolution by checking codebase for implementation
- Consolidated status table before confirmation
- Single confirmation for entire batch operation
- Comprehensive summary showing archived/skipped/failed changes

This is useful when working on multiple changes in parallel and wanting
to archive them together after implementation is complete.
2026-01-20 11:37:33 -08:00
Tabish Bidiwale 8332a09811 fix(ci): use workflow_dispatch for polish release notes (#533)
* fix(ci): use workflow_dispatch for polish release notes

The claude-code-action doesn't support the `release` event type.
Switch to workflow_dispatch which is supported, and have
release-prepare trigger it after publishing.

* fix: get tag from package.json instead of gh release list
2026-01-20 00:36:24 -08:00
Tabish Bidiwale d61a49f6d5 fix(changelog): convert markdown headers to bold text for proper formatting (#532)
Changeset descriptions that use markdown headers (### New Features) get
nested inside list items, causing poor rendering. This converts all
affected entries to use **Bold Text** instead, which renders correctly.

Also adds a brief summary line to each entry for better readability.
2026-01-20 00:09:49 -08:00
openspec-release-bot[bot]andgithub-actions[bot] 7d1237f00d Version Packages (#531)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-20 00:01:09 -08:00
Tabish Bidiwale 33466b1e2a Add changeset for project config and schema commands (#530) 2026-01-19 23:58:09 -08:00
Tabish Bidiwale 6c8c778043 fix(config): handle null rules field in project config (#529)
* feat(config): add project-level configuration via openspec/config.yaml

Adds openspec/config.yaml support for project-level customization without
forking schemas. Teams can now:

- Set a default schema (used when --schema flag not provided)
- Inject project context into all artifact instructions
- Add per-artifact rules (e.g., proposal rules, specs rules)

Key changes:
- New `src/core/project-config.ts` with Zod schema and resilient parsing
- New `src/core/config-prompts.ts` for interactive config creation
- Updated schema resolution order: CLI → change metadata → config → default
- Updated instruction generation to inject <context> and <rules> XML sections
- Integrated config creation prompts into `artifact-experimental-setup`

Schema resolution precedence:
1. --schema CLI flag (explicit override)
2. .openspec.yaml in change directory (change-specific)
3. openspec/config.yaml schema field (project default)
4. "spec-driven" (hardcoded fallback)

* test(config): add e2e tests and performance benchmarks for project config

- Add project config integration tests in artifact-workflow.test.ts:
  - Test new change uses schema from config
  - Test CLI schema overrides config schema
  - Test context and rules injection in instructions
  - Test backwards compatibility without config file
  - Test immediate reflection of config changes

- Add performance benchmark tests in project-config.test.ts:
  - Typical config (1KB): <20ms target
  - Large config (50KB): <50ms target
  - Repeated reads consistency check
  - Missing config fast-path test

- Add project configuration documentation in experimental-workflow.md:
  - Config fields reference (schema, context, rules)
  - Schema precedence explanation
  - Artifact IDs by schema
  - Troubleshooting guide

- Mark all tasks complete in tasks.md

* refactor(config): remove benchmark tests, document decision in source

Remove performance benchmark tests from project-config.test.ts and
document the results directly in the source code instead. Benchmarks
showed config reads are fast enough (~0.5ms typical) that caching
is unnecessary.

* fix(config): resolve three issues in project config feature

- Remove nested <template> tags: generateInstructions() no longer wraps
  template content since printInstructionsText() already handles XML
  structure
- Fix schema message accuracy: newChangeCommand() now uses the resolved
  schema returned from createChange() instead of hardcoded fallback
- Add TTY check: artifact-experimental-setup skips interactive prompts
  in non-TTY environments (CI, automation) to prevent hangs

* fix(config): handle null rules field in project config

Add null check when parsing rules field since YAML `rules:` with no
value parses to null, and `typeof null === 'object'` in JavaScript.
Without this check, Object.entries(null) would throw an error.
2026-01-19 23:49:11 -08:00
Tabish Bidiwale 43b01ad374 docs: update workflow docs and mark schema commands as experimental (#526)
* docs: update workflow docs for schema management CLI

Update documentation to reflect implemented schema management features:
- Document schema CLI commands (which, validate, fork, init)
- Update gap summary to show completed phases (PR #522, #525)
- Improve custom schema examples with actual CLI usage
- Update resolution order documentation

* feat(cli): mark schema commands as experimental

Add [experimental] tag to help description and runtime warning
for schema management commands to indicate they may change.
2026-01-19 20:41:15 -08:00
Tabish Bidiwale 3cdcdfca8e feat(cli): add schema management commands (#525)
Add `openspec schema` command group with subcommands for managing
workflow schemas:

- `schema which [name]` - Show where a schema resolves from with
  shadow detection across project/user/package locations
- `schema validate [name]` - Validate schema structure, templates,
  and dependency graph
- `schema fork <source> [name]` - Copy an existing schema to project
  for customization
- `schema init <name>` - Create a new project-local schema with
  interactive or CLI-driven configuration

All commands support `--json` output for scripting. The init command
supports interactive prompts for description and artifact selection.

Implements the schema-management-cli change proposal.
2026-01-19 19:42:37 -08:00
Tabish Bidiwale 32fc19a60d fix: Windows path compatibility in resolver tests (#524)
- Use path.join() in test expectations instead of hardcoded forward slashes
- Add openspec/config.yaml with cross-platform requirements to prevent
  similar issues in future proposals

The tests were failing on Windows because path.join() uses backslashes
on Windows, but the test expectations hardcoded forward slashes.
2026-01-19 18:42:00 -08:00
Tabish Bidiwale 84f372517f change(schema-management-cli): proposal for schema management commands (#523)
* change(schema-management-cli): add proposal for schema management commands

Propose new CLI commands to improve the UX of creating and managing project schemas:

- `openspec schema init <name>` - Interactive wizard to scaffold new schemas
- `openspec schema fork <source> [name]` - Copy existing schema for customization
- `openspec schema validate [name]` - Validate schema structure before runtime
- `openspec schema which <name>` - Debug schema resolution path

* change(schema-management-cli): add design, tasks, and specs artifacts

Add implementation artifacts for the schema management CLI feature:
- Design document with decisions and rationale
- Task breakdown for implementation
- Specs for schema init, fork, validate, and which commands
2026-01-19 18:22:44 -08:00
Tabish Bidiwale adda63e17a feat(resolver): add project-local schema support (#522)
Add 3-level schema resolution: project-local → user override → package built-in.

- Add `getProjectSchemasDir(projectRoot)` to resolve project schemas at `./openspec/schemas/<name>/`
- Extend `SchemaInfo.source` type to include `'project'`
- Update `getSchemaDir()`, `resolveSchema()`, `listSchemas()`, `listSchemasWithInfo()` with optional `projectRoot` parameter
- Update CLI commands to display schema source labels (project/user/package)
- Add `projectRoot` to `ChangeContext` interface for proper resolution throughout workflow
- Add 17 new tests covering project-local schema resolution

This enables projects to define custom schemas that override user and package schemas,
while maintaining backward compatibility when projectRoot is not provided.
2026-01-19 18:01:35 -08:00
Tabish Bidiwale 90d05b7115 docs: add project-config demo guide (#521)
Add a quick-reference demo guide for the project-config feature
(openspec/config.yaml). This consolidates the demo walkthrough
into a standalone document that's easier to use when presenting
the feature.

Includes:
- Summary of what project config does
- 6 numbered demo scenarios
- Quick all-in-one demo script
- Key points to emphasize
2026-01-19 16:56:12 -08:00
Tabish Bidiwale 20714c1c28 feat(config): add project-level configuration via openspec/config.yaml (#499)
* feat(config): add project-level configuration via openspec/config.yaml

Adds openspec/config.yaml support for project-level customization without
forking schemas. Teams can now:

- Set a default schema (used when --schema flag not provided)
- Inject project context into all artifact instructions
- Add per-artifact rules (e.g., proposal rules, specs rules)

Key changes:
- New `src/core/project-config.ts` with Zod schema and resilient parsing
- New `src/core/config-prompts.ts` for interactive config creation
- Updated schema resolution order: CLI → change metadata → config → default
- Updated instruction generation to inject <context> and <rules> XML sections
- Integrated config creation prompts into `artifact-experimental-setup`

Schema resolution precedence:
1. --schema CLI flag (explicit override)
2. .openspec.yaml in change directory (change-specific)
3. openspec/config.yaml schema field (project default)
4. "spec-driven" (hardcoded fallback)

* test(config): add e2e tests and performance benchmarks for project config

- Add project config integration tests in artifact-workflow.test.ts:
  - Test new change uses schema from config
  - Test CLI schema overrides config schema
  - Test context and rules injection in instructions
  - Test backwards compatibility without config file
  - Test immediate reflection of config changes

- Add performance benchmark tests in project-config.test.ts:
  - Typical config (1KB): <20ms target
  - Large config (50KB): <50ms target
  - Repeated reads consistency check
  - Missing config fast-path test

- Add project configuration documentation in experimental-workflow.md:
  - Config fields reference (schema, context, rules)
  - Schema precedence explanation
  - Artifact IDs by schema
  - Troubleshooting guide

- Mark all tasks complete in tasks.md

* refactor(config): remove benchmark tests, document decision in source

Remove performance benchmark tests from project-config.test.ts and
document the results directly in the source code instead. Benchmarks
showed config reads are fast enough (~0.5ms typical) that caching
is unnecessary.

* fix(config): resolve three issues in project config feature

- Remove nested <template> tags: generateInstructions() no longer wraps
  template content since printInstructionsText() already handles XML
  structure
- Fix schema message accuracy: newChangeCommand() now uses the resolved
  schema returned from createChange() instead of hardcoded fallback
- Add TTY check: artifact-experimental-setup skips interactive prompts
  in non-TTY environments (CI, automation) to prevent hangs
2026-01-19 16:39:43 -08:00
Tabish Bidiwale 2e51ae26d3 fix: auto-trigger polish release notes on release publish (#519)
* perf: add path filtering to Nix validation CI job

Skip Nix flake validation when no Nix-related files change. This speeds
up CI for PRs that only touch source code, docs, or tests.

Files that trigger Nix validation:
- flake.nix, flake.lock
- package.json, pnpm-lock.yaml
- scripts/update-flake.sh
- .github/workflows/ci.yml

Uses dorny/paths-filter@v3 for change detection. Required-checks jobs
updated to handle skipped status correctly.

* fix: auto-trigger polish release notes on release publish

The workflow was only set up for manual dispatch, requiring someone to
remember to run it after each release. This change adds an automatic
trigger on `release: [published]` events while keeping the manual
trigger as a fallback.

The Claude Code Action supports any GitHub event when using the `prompt`
parameter for custom automations.
2026-01-19 01:28:45 -08:00
Tabish Bidiwale dbd4ed7bfb perf: add path filtering to Nix validation CI job (#518)
Skip Nix flake validation when no Nix-related files change. This speeds
up CI for PRs that only touch source code, docs, or tests.

Files that trigger Nix validation:
- flake.nix, flake.lock
- package.json, pnpm-lock.yaml
- scripts/update-flake.sh
- .github/workflows/ci.yml

Uses dorny/paths-filter@v3 for change detection. Required-checks jobs
updated to handle skipped status correctly.
2026-01-19 01:22:33 -08:00
openspec-release-bot[bot]andgithub-actions[bot] 473093f885 Version Packages (#517)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-19 00:59:49 -08:00
Tabish Bidiwale b5a884748b Add changeset for v0.21 release (#516) 2026-01-19 00:56:17 -08:00
Tabish Bidiwale 690c75225c fix: prevent implementation during explore mode (#515)
Add explicit instructions to both the explore skill and slash command:
- Add IMPORTANT notice clarifying explore is for thinking, not implementing
- Add "Open threads, not interrogations" stance for user-driven exploration
- Add "Don't implement" guardrail to both templates

Creating OpenSpec artifacts is still allowed since that captures thinking.
2026-01-19 00:28:45 -08:00
Tabish Bidiwale dd53fb7736 OPSX apply: infer target change (#513)
* opsx: infer change for apply

* opsx: prompt when apply ambiguous

* opsx: use AskUserQuestion when ambiguous

* Simplify opsx:apply change selection instructions

Update all change selection instructions across all opsx commands
(apply, continue, sync, archive, verify, ff) to use consistent wording:

"If omitted, check if it can be inferred from conversation context.
If vague or ambiguous you MUST prompt for available changes."

For apply specifically, also simplifies Step 1 from ~180 to ~60 words
while preserving the same behavior: infer from conversation, auto-select
if single change, prompt via AskUserQuestion if ambiguous, always announce.

Removes micromanagement details (validation commands, recommendation
markers, presentation specifics) and trusts the LLM to figure out
reasonable defaults.
2026-01-18 19:44:56 -08:00
Tabish Bidiwale 2a441c472d Refine opsx archive sync assessment (#514)
* Refine opsx archive sync assessment

* Simplify opsx archive sync instructions

Replace verbose algorithmic instructions with intent-focused guidance.
Trust the agent to figure out comparison logic rather than specifying
the exact algorithm for each delta type (ADDED, MODIFIED, etc).

Reduces section 4 from ~31 lines to ~13 lines per template.

* Add explicit paths for delta spec locations

Make it clear where agents should look for delta specs and main specs:
- Delta specs: openspec/changes/<name>/specs/
- Main specs: openspec/specs/<capability>/spec.md
2026-01-18 19:35:04 -08:00
Pim SnelandTabish Bidiwale ed4d965208 feat: add nix flake support (sorry for this duplicate) (#459)
* add nix flake support

* feat: add Nix flake maintenance automation

* Add Nix Flake CI Validation

* fix updatescript, update flake

* make update-script compatible with macos

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-16 13:00:11 -08:00
Tabish Bidiwale c86985d6ec feat: add feedback command for submitting user feedback (#509)
* feat: add feedback command for submitting user feedback

Implement `openspec feedback` command that creates GitHub Issues using the gh CLI.
Includes graceful fallback to manual submission when gh is not available or
not authenticated.

Features:
- Automatic gh CLI detection and authentication check
- Graceful fallback with pre-filled issue URLs for manual submission
- Automatic metadata inclusion (version, platform, timestamp)
- /feedback skill for agent-assisted feedback with context enrichment
- Comprehensive test coverage with mocked gh CLI calls

* fix: address PR review comments for feedback command

- Add Windows compatibility: use 'where gh' on Windows, 'which gh' on Unix/macOS
- Fix shell injection vulnerability: replace execSync with execFileSync and argument arrays
- Fix British English phrasing: "in future" → "in the future"
- Reduce code duplication: extract formatTitle/formatBody to single location
- Update tests to verify execFileSync usage and cross-platform command detection
- Add spec scenarios for safe command execution and cross-platform support
2026-01-14 15:48:29 -08:00
Tabish Bidiwale bf4bc2426f fix: add auto-approval for file writes in polish-release-notes workflow (#505)
The workflow was failing because Claude Code requested permission to write files
(release-title.txt and polished-notes.md) but there was no interactive user to approve.

Added claude_args: "--allowedTools Write,Read" to pre-approve file operations
in automation mode.
2026-01-13 23:09:37 -08:00
Tabish Bidiwale c57e421cc2 fix: update polish-release-notes workflow to use correct Claude Code action parameters (#504)
The workflow was failing due to two issues:
1. Using unsupported 'release' event trigger - Claude Code action doesn't support this event type
2. Using deprecated 'direct_prompt' parameter instead of 'prompt'

Changes:
- Switch from 'release' trigger to 'workflow_dispatch' for manual triggering
- Replace 'direct_prompt' with 'prompt' parameter (v1.0 breaking change)
- Update all tag references from github.event.release.tag_name to inputs.tag_name

The workflow now needs to be manually triggered from GitHub Actions UI after a release is published.
2026-01-13 23:02:22 -08:00
openspec-release-bot[bot]andgithub-actions[bot] ed2e832066 Version Packages (#503)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-13 22:50:11 -08:00
Tabish Bidiwale 9db74aa5ac chore: add changeset for opsx:verify skill and bug fixes (#502)
* Add changeset for opsx:verify skill and bug fixes

* Update changeset to follow template format
2026-01-13 22:45:23 -08:00
Tabish Bidiwale b5b7248610 feat(skills): implement /opsx:verify skill for validating change implementations (#501)
Add comprehensive verification skill that checks implementation completeness, correctness, and coherence against change artifacts. The skill validates task completion, spec coverage, requirement implementation, and design adherence.
2026-01-13 22:38:49 -08:00
Tabish Bidiwale 322bfd455a fix(vitest): cap worker parallelism to prevent process storms (#500)
Vitest v3 defaults to `pool: "forks"` and scales worker processes with
CPU count. This repo's tests spawn many Node processes (CLI invocations,
temp FS operations), which can cause runaway CPU/memory usage when
combined with high parallelism.

Changes:
- Explicitly set pool to 'forks' (tests rely on process isolation)
- Add resolveMaxWorkers() to cap workers at min(4, availableCPUs)
- Allow VITEST_MAX_WORKERS env override for CI/automation tuning
2026-01-13 21:41:25 -08:00
Tabish Bidiwale 08c349369a docs: add MAINTAINERS.md with core maintainers and advisors (#495) 2026-01-13 21:05:28 -08:00
Tabish Bidiwale 40afee643e chore(openspec): add feedback command change proposal (#496)
Add change proposal for `openspec feedback` CLI command that enables
users and agents to submit feedback via GitHub Issues.

Key features:
- Simple `openspec feedback <message>` command
- GitHub Device OAuth for authentication
- `/feedback` skill for agent-assisted feedback with context enrichment
- Anonymization of sensitive data before submission
- User confirmation required before submitting
2026-01-13 15:39:55 -08:00
Tabish Bidiwale 05023dab43 feat(skills): add /opsx:verify change proposal (#497)
Add change proposal for a new verification skill that validates
implementation matches change artifacts (specs, tasks, design).

The skill verifies three dimensions:
- Completeness: all tasks done, all specs addressed
- Correctness: implementation matches specs and scenarios
- Coherence: follows design decisions and project patterns

Produces prioritized report with actionable fix suggestions.
2026-01-13 15:26:31 -08:00
Tabish Bidiwale d7a928b4e9 fix(agents): add --no-interactive to validate commands in agent workflows (#494)
AI agents following OpenSpec workflows would hit interactive prompts when
running `openspec validate` because the commands in AGENTS.md and slash
command templates didn't include the --no-interactive flag.

This caused hangs in LLM tool execution since agents run in pseudo-TTY
environments where process.stdin.isTTY returns true, triggering
interactive mode.

Fixes #492
2026-01-13 14:50:43 -08:00
Nob ShinjoandTabish Bidiwale 07dd634986 fix(powershell-generator): remove trailing comma from last entry (#485)
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-13 13:50:11 -08:00
Tabish Bidiwale 36078b1947 chore: improve release notes pipeline (#481)
* chore: improve changelog generation with GitHub integration

- Switch to @changesets/changelog-github for PR/author links in CHANGELOG.md
- Add comprehensive changeset README with template and contributor guidance
- Remove release:local script (CI-only releases)

* ci: add AI-powered release notes polishing

Transforms raw changelog into user-friendly release notes when a
GitHub Release is published. Uses Claude Code Action to:
- Generate concise release title (e.g., "v0.18.0 - OPSX Workflow")
- Rewrite changelog as developer-friendly release notes
- Remove noise (commit hashes, PR numbers, internal changes)

Requires CLAUDE_CODE_OAUTH_TOKEN secret (from claude setup-token).
2026-01-10 22:33:43 -08:00
Tabish Bidiwale d0e1b076c2 chore: trigger release workflow for v0.19.0 (#480) 2026-01-10 18:20:30 -08:00
Tabish Bidiwale 2fbda520de ci: remove auto-merge to fix release triggering (#479)
GitHub's auto-merge feature uses an internal token that cannot trigger
workflows. Even with manual approval, the merge performed by auto-merge
doesn't trigger the release workflow.

Removing auto-merge means:
1. Version PR is created with CI running
2. User manually merges the PR (clicking "Merge")
3. The merge triggers the release workflow
4. Package is published

This aligns with industry standard practice for changesets.
2026-01-10 18:18:09 -08:00
github-actions[bot] 5633556b6d Version Packages (#475)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-10 18:04:55 -08:00
Tabish Bidiwale 2bb0ed36c5 ci: pass GitHub App token to checkout for CI triggering (#478)
Move the GitHub App token generation before checkout and pass it
to actions/checkout. This configures git to use the App's identity
for all operations, allowing pushes to trigger CI workflows.

Removes commitMode: github-api which doesn't support executable files.
2026-01-10 18:01:05 -08:00
Tabish Bidiwale 06097f9cb7 ci: add commitMode github-api to trigger CI on version PR (#477)
* ci: use GitHub App token to trigger CI on version PR

Replace GITHUB_TOKEN with a GitHub App token so that the version PR
can trigger CI workflows. GITHUB_TOKEN cannot trigger workflows by
design (to prevent infinite loops).

Requires APP_ID variable and APP_PRIVATE_KEY secret to be configured.

* ci: upgrade create-github-app-token to v2

* ci: add commitMode github-api to trigger CI on version PR
2026-01-10 17:50:59 -08:00
Tabish Bidiwale 8f5a526396 ci: use GitHub App token to trigger CI on version PR (#476)
* ci: use GitHub App token to trigger CI on version PR

Replace GITHUB_TOKEN with a GitHub App token so that the version PR
can trigger CI workflows. GITHUB_TOKEN cannot trigger workflows by
design (to prevent infinite loops).

Requires APP_ID variable and APP_PRIVATE_KEY secret to be configured.

* ci: upgrade create-github-app-token to v2
2026-01-10 17:38:57 -08:00
Tabish Bidiwale eb152eb2ca ci: auto-merge version PR to streamline releases (#474)
* Add changeset for Continue support, shell completions, and explore command

* ci: auto-merge version PR to streamline releases

Enable auto-merge on the changesets version PR so it merges
automatically once CI passes. This reduces the release process
from 2 manual PR merges to effectively 1.

Requires enabling "Allow auto-merge" in repository settings
and branch protection rules on main.
2026-01-10 16:22:25 -08:00
e987a5a327 Add Continue support (#402)
* OpenSpec 支持 Continue 插件

* add update

* Update spec.md

* fix: correct Continue frontmatter format and README ordering

- Fix Continue frontmatter to use proper YAML format with opening `---`
  and required `invokable: true` field for slash command availability
- Fix README table ordering: Continue should be after Codex alphabetically
- Remove unused TemplateManager import from continue.ts
- Fix trailing whitespace in update.test.ts
- Fix double blank line in init.test.ts
- Fix extra blank line in cli-init/spec.md
- Update tests to verify correct frontmatter format

---------

Co-authored-by: ajuanli <ajuanli@tencent.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2026-01-10 15:54:09 -08:00
Tabish Bidiwale 4971cda812 fix: use actionCommand for telemetry command tracking (#472)
The preAction hook receives (thisCommand, actionCommand) where thisCommand
is the root program and actionCommand is the actual subcommand being run.
Using thisCommand was incorrectly tracking the root command instead of
the actual subcommand executed by the user.
2026-01-10 15:10:12 -08:00
Tabish Bidiwale 4715138927 fix: set USERPROFILE for Windows compatibility in telemetry tests (#469)
On Windows, os.homedir() uses the USERPROFILE environment variable
instead of HOME. The telemetry config tests were only mocking HOME,
causing them to fail on Windows CI.
2026-01-09 23:36:54 -08:00
Tabish Bidiwale 940898c1c5 Add optional anonymous usage statistics (#468)
* chore: add proposal for PostHog analytics integration

Introduces the proposal artifact for adding opt-in telemetry to OpenSpec
using PostHog. Covers command tracking, feature adoption metrics, and
privacy-respecting consent management.

* feat: add optional anonymous usage statistics

Introduces privacy-first usage analytics to help understand how OpenSpec
is being used. Key privacy protections:

- Only tracks command names and version (no arguments, paths, or content)
- Opt-out via OPENSPEC_TELEMETRY=0 or DO_NOT_TRACK=1
- Auto-disabled in CI environments
- No IP address collection (explicitly disabled)
- Anonymous ID is a random UUID with no PII

Uses PostHog with a reverse proxy to avoid ad blockers. First-run shows
a one-line notice informing users about the collection.

* docs: make telemetry section collapsible and concise
2026-01-09 23:10:31 -08:00
Tabish Bidiwale d49a88c3bb feat: add /opsx:explore command for exploratory thinking (#467)
Wire up the explore skill and slash command templates to the
artifact-experimental-setup command. This adds /opsx:explore as
a thinking partner mode for exploring ideas, investigating problems,
and clarifying requirements before committing to a change.

Changes:
- Add imports for getExploreSkillTemplate and getOpsxExploreCommandTemplate
- Add explore skill to skills array (generates openspec-explore/SKILL.md)
- Add explore command to commands array (generates opsx/explore.md)
- Add /opsx:explore to CLI usage message
- Update docs/experimental-workflow.md with explore command
2026-01-09 20:15:26 -08:00
Tabish Bidiwale bb9f6ce0ea docs: add OPSX experimental workflow visibility to README (#460)
* docs: add OPSX experimental workflow visibility to README

Add a subtle banner near the top and an Experimental Features section
before Contributing to draw attention to the new OPSX workflow.

* docs: reframe OPSX messaging around fluid iteration

Update messaging to emphasize the core value proposition:
- No phases, just actions
- Dependencies are enablers, not gates
- Update artifacts as you learn during implementation

The previous "step-by-step artifact creation" framing incorrectly
suggested more bureaucracy. OPSX is about less rigidity, not more.

* docs: add architecture deep dive with ASCII diagrams

Add comprehensive comparison of standard vs OPSX workflow architecture:
- Philosophy: phases vs actions
- Component architecture diagrams
- Dependency graph model
- Information flow comparison
- Iteration model comparison
- Custom schema example

* docs: emphasize hackability and experimentation rationale

Add "Why We Built This" section explaining the meta-level motivation:
- Instructions were hardcoded, hard to improve
- Needed granular, testable artifacts
- Wanted to experiment with different workflows without code changes
- OPSX makes the instruction system itself hackable

Update README banner and experimental features section to highlight
schema-driven, hackable nature alongside fluid iteration benefits.

* docs: reframe hackability as user benefit, not just internal

OPSX isn't just for OpenSpec devs to experiment - it's for everyone:
- Teams can create workflows that match how they work
- Power users can tweak prompts to get better AI outputs
- Contributors can experiment without releases

Updated framing from "we needed" to "now anyone can".

* docs: add guidance on when to update vs. start fresh

Addresses a common question: when does "update as you learn" become
"this is different work"? Adds heuristics based on intent, scope
overlap, and completability to help users make the judgment call.
2026-01-09 20:09:53 -08:00
Tabish Bidiwale ae85a7229d fix: offer parent flags in Bash and PowerShell completions when subcommands exist (#466)
When a command has both flags and subcommands, the Bash and PowerShell
completion generators now check if the user is typing a flag (input
starts with `-`) before offering subcommand completions. This fixes the
issue where parent-level flags were never suggested.

Before: `openspec config --<TAB>` → Only showed subcommands
After: `openspec config --<TAB>` → Shows parent flags when input starts with `-`

Fixes #463
2026-01-09 19:40:13 -08:00
Tabish Bidiwale 504c93bdf1 fix: skip additional Windows-specific tests (#465)
* fix: skip additional Windows-specific tests

- fish-installer: skip uninstall permission test (chmod on directory)
- powershell-installer: skip "skip configuration when script line exists"
  test (Windows has dual profile paths so the second profile gets configured)

* refactor: use ENOTDIR approach for cross-platform install error tests

Instead of platform-specific invalid paths (Z:\ or /root), create a
temporary file and use it as homeDir. This guarantees deterministic
ENOTDIR failures when trying to create subdirectories on all platforms.
2026-01-09 16:26:26 -08:00
Tabish Bidiwale c4a54a8d54 fix: skip Windows-specific permission tests that rely on chmod() (#464)
fs.chmod() on directories doesn't restrict write access on Windows since
Windows uses ACLs that Node.js doesn't control. Additionally, admin users
and CI runners can bypass read-only attributes. Skip these tests on Windows
and use platform-specific invalid paths in cross-platform tests.

Fixes #401 (bash/pwsh completion commit breaking Windows e2e tests).
2026-01-09 16:06:15 -08:00
38d2356836 feature/bash_fish_power_shells_completions (#401)
* added CLI completions support for: bash, fish and powershell

* Add bash/fish/powershell completions

* Archive extend-shell-completions

* Archive extend-shell-completions

* Fix canWriteFile control flow and add tests

* Fix bash completion fallback and security escaping

  - Add _init_completion fallback for systems without bash-completion
  - Fix command injection escaping in Fish/PowerShell generators
  - Add Bash command name escaping for security
  - Add comprehensive security tests for all generators
  - Fix test placement issues in bash/powershell test files

* refactor: extract completion templates and standardize naming

Extract static template literals from generators into separate template files.
Standardize naming to {SHELL}_STATIC_HELPERS and {SHELL}_DYNAMIC_HELPERS.

- Create bash/fish/powershell/zsh template files
- Rename constants: BASH_HELPERS → BASH_DYNAMIC_HELPERS,
  FISH_HELPER_FUNCTIONS → FISH_STATIC_HELPERS,
  POWERSHELL_HELPERS → POWERSHELL_DYNAMIC_HELPERS
- Update generator imports
- Remove ~99 lines of boilerplate from generators

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: update spec to reflect multi-shell support

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: add all shells to zsh completion suggestions

* feat: add --yes flag to completion uninstall

* fix: remove bash-completion dependency from fallback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: use printf instead of echo for Fish tab output

Fish's echo doesn't interpret escape sequences, so \t outputs
literally instead of as a tab character. Use printf for proper
tab-separated completion output.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: make UX messages shell-aware

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: add Homebrew paths for bash-completion detection

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: support both PowerShell Core and Windows PS 5.1

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: preserve colon handling in bash completion

Add -n : option to _init_completion to prevent colons from being
treated as word separators. This is important for spec/change IDs
that may contain colons.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: update completion tests to match implementation changes

Updated bash-generator test to expect `-n :` flag in _init_completion call.
Updated powershell-installer tests to match refactored implementation that
supports both PowerShell Core and Windows PowerShell 5.1.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2026-01-09 15:49:50 -08:00
Neroyangandneroyang 3f67debf65 feat: change the frontmatter of the Codebuddy Slash Commands (#462)
* feat: change the frontmatter of the Codebuddy Slash Commands

* fix: fix the issue mentioned by coderabbitai

* feat: change the init.test

* feat: change the init.test

---------

Co-authored-by: neroyang <neroyang@tencent.com>
2026-01-09 10:08:59 -08:00
github-actions[bot]andTabish Bidiwale 533cb0fa87 chore(release): version packages (#458)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2026-01-07 00:38:00 -08:00
Tabish Bidiwale 8dfd824477 Add changeset for OPSX experimental workflow commands (#457) 2026-01-07 00:35:04 -08:00
Tabish Bidiwale 3ed1270316 docs: add experimental workflow (OPSX) user guide (#456)
Adds documentation for the experimental artifact-based workflow:
- Setup instructions (Claude Code only for now)
- Command reference for all /opsx:* commands
- Usage examples and tips
- Comparison with standard workflow
- Feedback links to Discord and GitHub
2026-01-07 00:24:14 -08:00
Tabish Bidiwale eb15cdb983 chore: archive completed changes and clean up stale ones (#455)
Archive 5 completed changes:
- opsx-archive-command (synced specs)
- add-specs-apply-command
- add-per-change-schema-metadata
- make-apply-instructions-schema-aware (synced specs)
- add-agent-schema-selection

Delete 5 stale/abandoned changes:
- add-fingerprinting (no tasks, 7 weeks old)
- add-scaffold-command (0/7 tasks, 7 weeks old)
- add-proposal-frontmatter (no tasks, 8 weeks old)
- add-interactive-proposal-command (no tasks, 8 weeks old)
- make-validation-scope-aware (0/8 tasks, 4 months old)

Sync delta specs to main:
- Add opsx-archive-skill spec (new capability)
- Update cli-artifact-workflow spec with Schema Apply Block and
  Apply Instructions Command requirements
2026-01-06 23:52:11 -08:00
Tabish Bidiwale cd172a4427 feat: add smart sync check to /opsx:archive command (#452)
Instead of blindly asking "want to sync?", archive now performs a quick
check to see if delta specs actually need syncing:

- Extracts requirement names from delta specs
- Checks if corresponding main spec exists
- Checks if ADDED requirements appear in main spec
- Only prompts if sync appears needed

Also improves archive output to always show specs status:
- ✓ Synced to main specs
- No delta specs
- ⚠️ Not synced
2026-01-06 17:41:45 -08:00
Tabish Bidiwale b7f5a429de feat: add /opsx:archive command for archiving completed changes (#451)
Add `/opsx:archive` slash command to complete the OPSX workflow lifecycle.
This command archives completed changes in the experimental workflow with:

- Change selection prompt (if not specified)
- Artifact completion check using `openspec status --json`
- Task completion check (parsing tasks.md for `- [ ]`)
- Spec sync prompt (offers `/opsx:sync` before archiving if specs exist)
- Archive to `openspec/changes/archive/YYYY-MM-DD-<name>/`
- Clear output formatting for success, warnings, and errors

This completes the OPSX command suite:
- /opsx:new - Start a change
- /opsx:continue - Create next artifact
- /opsx:ff - Fast-forward all artifacts
- /opsx:apply - Implement tasks
- /opsx:sync - Sync delta specs
- /opsx:archive - Archive completed change (NEW)
2026-01-06 17:21:37 -08:00
Tabish Bidiwale a5c10ed5e7 feat: add /opsx:sync command for syncing delta specs to main specs (#450)
* feat: add /opsx:sync command for syncing delta specs to main specs

Add a new agent-driven skill that syncs delta specs from a change to main specs
without requiring archiving. This enables:

- Updating main specs during active development
- Intelligent merging (partial updates, adding scenarios)
- Idempotent operation (safe to run multiple times)

Implementation:
- Extract shared specs-apply logic from archive.ts to specs-apply.ts
- Add getSyncSpecsSkillTemplate and getOpsxSyncCommandTemplate
- Register /opsx:sync in artifact-experimental-setup
- Add specs-sync-skill main spec

* fix: rename specs apply to specs sync throughout change artifacts

Update all references:
- /opsx:specs → /opsx:sync
- specs-apply-skill → specs-sync-skill
- Remove cli-artifact-workflow delta spec (no CLI command)
- Update proposal, design, and tasks docs
2026-01-06 16:32:22 -08:00
Tabish Bidiwale 1bc849554c feat: add /opsx:ff command for fast-forward artifact creation (#448)
Adds a new fast-forward command that creates all artifacts needed for
implementation in one go, instead of stepping through them individually.

Changes:
- Add `applyRequires` field to status JSON output (shows which artifacts
  are required before the apply phase can begin)
- Add skill template for openspec-ff-change
- Add command template for /opsx:ff slash command
- Register templates in artifact-workflow setup command

The fast-forward command uses the schema's `apply.requires` configuration
to determine when to stop creating artifacts, making it schema-agnostic.
2026-01-06 11:49:03 -08:00
Tabish Bidiwale d73705736f feat: make apply instructions schema-aware (#444)
* feat: make apply instructions schema-aware

The `generateApplyInstructions` function was hardcoded to check for
`spec-driven` artifacts. This change makes it read artifact definitions
from the schema's new `apply` block, enabling support for different
workflows like TDD.

Changes:
- Add `ApplyPhaseSchema` Zod schema with `requires`, `tracks`, and
  `instruction` fields to types.ts
- Update `SchemaYamlSchema` to include optional `apply` field
- Add `apply` block to spec-driven and tdd schemas
- Refactor `generateApplyInstructions` to:
  - Load schema via `resolveSchema()`
  - Read `apply.requires` for required artifacts
  - Check artifact existence dynamically (supports glob patterns)
  - Use `apply.tracks` for progress tracking (or skip if null)
  - Use `apply.instruction` for custom guidance
  - Build `contextFiles` from all existing artifacts in schema
- Handle fallback when schema has no `apply` block (require all artifacts)
- Add 8 new tests for schema-aware apply behavior

* fix: improve apply instructions robustness and consistency

- Fix artifactOutputExists to properly handle glob patterns cross-platform
  by using path.sep and verifying actual file matches
- Remove redundant if/else in contextFiles loop
- Distinguish between missing tracks file vs empty tracks file
- Use consistent { error: } key in ApplyPhaseSchema validation
- Rename fallback test to accurately describe what it tests

* test: add fallback behavior tests for schemas without apply block

Add two tests that verify the fallback logic when a schema lacks an
apply block:
- Blocks when not all artifacts exist (requires ALL artifacts)
- Ready state with default instruction when all artifacts exist

Uses XDG_DATA_HOME to create temporary user schemas for testing.
2026-01-05 22:45:27 -08:00
Tabish Bidiwale ed924ffcff feat: add agent schema selection to experimental artifact workflow (#445)
- Add `openspec schemas` CLI command with `--json` option for agents
- Add `listSchemasWithInfo()` helper to get schema metadata (name, description, artifacts)
- Update `openspec-new-change` skill to prompt for schema selection
- Update `openspec-continue-change` skill to read schema dynamically from status
- Update `openspec-apply-change` skill to use schema-specific context files
- Update all slash commands (/opsx:new, /opsx:continue, /opsx:apply) to be schema-agnostic
- Add documentation for when to use each schema (spec-driven vs tdd)

Agents can now create changes with different workflow schemas and the skills
dynamically adapt based on the selected schema's artifact sequence.
2026-01-05 22:32:22 -08:00
Tabish Bidiwale 1786684af6 feat: add per-change schema metadata (.openspec.yaml) (#443)
This feature enables workflow schema auto-detection for changes:

- Add ChangeMetadataSchema Zod schema to types.ts
- Create change-metadata.ts with writeChangeMetadata(), readChangeMetadata()
- Update createChange() to accept optional schema param and write metadata
- Modify loadChangeContext() to auto-detect schema from .openspec.yaml
- Add --schema option to openspec new change command
- Update status/instructions commands to auto-detect schema from metadata

Schema resolution order:
1. Explicit --schema flag (if provided)
2. Schema from .openspec.yaml in change directory
3. Default 'spec-driven'
2026-01-05 17:13:52 -08:00
Tabish Bidiwale 51fb10db5e feat: add slash commands to artifact-experimental-setup (#442)
Extend the `openspec artifact-experimental-setup` command to also generate
slash commands alongside Agent Skills.

Changes:
- Add CommandTemplate interface and template functions for /opsx:new,
  /opsx:continue, and /opsx:apply commands
- Modify artifactExperimentalSetupCommand() to create slash command files
  at .claude/commands/opsx/
- Update success message to show both skills and slash commands created

The setup command now creates:
- 3 Agent Skills (.claude/skills/)
- 3 Slash Commands (.claude/commands/opsx/)
2026-01-05 17:08:46 -08:00
Tabish Bidiwale cac54042ce feat: add Agent Skills for experimental artifact workflow (#424)
* feat: add Agent Skills for experimental artifact workflow

Implements Task #3 from the experimental release plan:
- Create skill templates for openspec-new-change and openspec-continue-change
- Add artifact-experimental-setup CLI command
- Generate Agent Skills in .claude/skills/ directory
- Support cross-editor compatibility (Claude Code, Cursor, Windsurf)

Skills follow the Agent Skills specification and provide:
- Natural language invocation by AI assistants
- Step-by-step artifact creation workflow
- Dependency-driven change management

* fix: update GitHub issues URL to correct repository

Replace placeholder `https://github.com/your-org/openspec/issues`
with correct URL `https://github.com/Fission-AI/OpenSpec/issues` in:
- docs/experimental-release-plan.md
- src/commands/artifact-workflow.ts

Verified against package.json repository.url field.

* feat: add openspec-apply-change skill for task implementation

Add the apply skill to guide agents through implementing tasks from an
OpenSpec change:

- Add `openspec instructions apply` CLI command that parses tasks.md and
  returns context files, progress tracking, and dynamic instructions
- Add `getApplyChangeSkillTemplate()` to skill-templates.ts with full
  workflow guidance for implementing tasks
- Update artifact-experimental-setup to generate all three skills:
  openspec-new-change, openspec-continue-change, openspec-apply-change

The apply skill supports the fluid "actions on a change" model:
- Can be invoked anytime (if tasks.md exists)
- Handles blocked/ready/all_done states
- Guides agents to pause on issues and suggest artifact updates
- Tracks progress via task checkboxes

* docs: mark apply skill implementation steps as complete

* feat: add Capabilities section to proposal template

Enrich the proposal template to explicitly capture capability discovery:

- Add "Capabilities" section with "New Capabilities" and "Modified
  Capabilities" subsections to proposal template
- Update proposal instruction in schema.yaml to guide agents on
  researching existing specs and listing capabilities
- Update skill instructions with detailed guidance for the Capabilities
  section

This creates a clear contract between proposal and specs phases - each
capability listed in the proposal will need a corresponding spec file.

* feat: remove redundant `openspec next` command

The `next` command was redundant with `status` - both show which artifacts
are ready to create. The status command provides more context (done/ready/blocked)
and is the single source of truth for artifact state.

Changes:
- Remove nextCommand function and CLI registration from artifact-workflow.ts
- Update skill templates to use status instead of next
- Update docs and specs to reflect removal
- Add REMOVED Requirements section to cli-artifact-workflow spec
- Remove 7 tests for the next command

Migration: Use `openspec status --change <id> --json` and filter artifacts
with `status: "ready"` to find artifacts that can be created next.

* docs: clarify kebab-case naming in proposal template

Update HTML comments in the Capabilities section to explicitly instruct
using kebab-case identifiers with examples (user-auth, data-export,
api-rate-limiting).

* feat: add change proposals for per-change schema metadata

Add two related change proposals for enabling schema selection in the
experimental artifact workflow:

1. add-per-change-schema-metadata: Store schema choice in .openspec.yaml
   per change, enabling auto-detection in workflow commands. Includes
   Zod schema design and delta specs for cli-artifact-workflow.

2. add-agent-schema-selection: Follow-up to update agent skills to
   support dynamic schema selection (depends on metadata change).

Also includes:
- Example .openspec.yaml in add-frontmatter-to-openspec-artifact-files
- Clarify "Modified Capabilities" guidance in proposal template

* remove test change

* feat: fix design.md as optional, update docs, add schema-aware apply proposal

Changes:
- Fix generateApplyInstructions to treat design.md as optional (not required)
- Update experimental-release-plan.md CLI output to match implementation
- Add openspec-apply-change skill to docs (was missing)
- Fix test flow numbering after adding apply skill verification step
- Add change proposal for making apply instructions schema-aware

The schema-aware proposal introduces an `implementation` block in schema.yaml
to define when a change becomes implementable and how to track progress.
2026-01-05 16:42:17 -08:00
Tabish Bidiwale c47cdaafe2 fix: archive add-antigravity-support and fix-cline-workflows-implementation (#423)
Archives two changes that were missing complete requirement content in their
spec deltas, which would have caused data loss during archival:

1. add-antigravity-support: Adds Antigravity IDE support to cli-init and
   cli-update with proper workflow file generation in `.agent/workflows/`

2. fix-cline-workflows-implementation: Corrects Cline paths from `.clinerules/`
   to `.clinerules/workflows/` to match Cline's official workflow conventions

Both deltas were fixed to include all 15 slash command scenarios (14 existing +
1 new Antigravity) to prevent loss of existing requirements when archived.
2025-12-31 00:12:07 +11:00
Tabish Bidiwale ea5aa0e562 feat: enhance artifact instructions with inline guidance and XML output (#422)
* feat: enhance artifact instructions with inline guidance and XML output

Schema changes:
- Add `instruction` field to artifacts for inline creation guidance
- Include detailed instructions for proposal, specs, design, and tasks

Instruction loader enhancements:
- Return `instruction` field from schema
- Include `changeDir` for full path resolution
- Enrich dependency info with `path` and `description` fields

CLI output improvements:
- New XML-style format for `openspec instructions` (better for AI parsing)
- Structured tags: <artifact>, <task>, <context>, <output>, <template>
- Dependencies now show full paths for easy file reading
- JSON output includes all new fields

* docs: add schema customization and workflow gap documentation

- schema-customization.md: Guide for customizing artifact schemas
- schema-workflow-gaps.md: Analysis of current workflow limitations

* test: fix list test for new default sort order

Update test to explicitly use sort='name' since the default
changed from alphabetical to most-recently-modified.
2025-12-30 22:28:49 +11:00
Tabish Bidiwale 48b5ed9657 feat: enhance list command with last modified timestamps and sorting (#421)
- Add lastModified field showing when each change was last modified
- Default sort order is now "recent" (most recently modified first)
- Add --sort option to choose between "recent" and "name" ordering
- Add --json option for programmatic access with structured output
- Fall back to directory mtime for empty change directories
- Display relative time (e.g., "2h ago", "3d ago") in human output
2025-12-30 22:06:17 +11:00
Tabish Bidiwale fb7ff527a6 proposal: add artifact workflow CLI commands (Slice 4) (#415)
* proposal: add artifact workflow CLI commands (Slice 4)

Add CLI commands for artifact workflow operations:
- `openspec status --change <id>` - Show artifact completion state
- `openspec next --change <id>` - Show ready artifacts
- `openspec instructions <artifact> --change <id>` - Get enriched template
- `openspec templates --change <id>` - Show template paths
- `openspec new change <name>` - Create new change

Commands are top-level for fluid UX and implemented in isolation
for easy removal (experimental feature).

* fix: remove --change from templates command

Templates are schema-level, not change-level. The command now uses
--schema instead of --change for consistency with how templates
are actually resolved.

* rename: cli-workflow -> cli-artifact-workflow

More specific capability name that clarifies which workflow the CLI
commands are for.

* feat: implement artifact workflow CLI commands (Slice 4)

Add experimental CLI commands for artifact-based workflow management:
- `openspec status --change <id>` - display artifact completion status
- `openspec next --change <id>` - show artifacts ready to create
- `openspec instructions <artifact> --change <id>` - output enriched template
- `openspec templates [--schema <name>]` - show resolved template paths
- `openspec new change <name>` - create new change directory

Features:
- JSON output support (--json flag) for all commands
- Color-coded status indicators (green/yellow/red)
- Progress spinners during loading
- --no-color and NO_COLOR env support
- --schema option for custom schema selection
- Comprehensive error handling with helpful messages

All commands are isolated in src/commands/artifact-workflow.ts for easy
removal if the feature doesn't work out. Help text marks them as experimental.

* fix: update specs glob to match nested directory structure

The schema used specs/*.md but specs are stored as specs/<capability>/spec.md.
Updated to specs/**/*.md so openspec status/next correctly detect spec completion.

* test: update test to match new specs glob pattern

* chore: archive add-artifact-workflow-cli change

- Move change to archive/2025-12-28-add-artifact-workflow-cli
- Create cli-artifact-workflow spec

* feat: unify change state model for scaffolded changes

- Update artifact workflow commands to work with scaffolded changes
- Add draft changes section to dashboard view
- Fix completed changes to require tasks.total > 0
- Archive unify-change-state-model change

* fix: validate change name format to prevent path traversal

Add validation in validateChangeExists() to ensure --change parameter
is a valid kebab-case ID before constructing file paths. This prevents
path traversal attacks like --change "../foo" or --change "/etc/passwd".

- Reuses existing validateChangeName() from change-utils.ts
- Adds 3 tests for path traversal, absolute paths, and slashes
2025-12-29 16:55:56 +11:00
Tabish Bidiwale 11e195575f feat: add instruction loader for template loading and change context (#414)
* feat: add instruction loader for template loading and change context

Add the instruction-loader module that provides:
- loadTemplate: Load templates from schema directories
- loadChangeContext: Combine artifact graph with completion state
- generateInstructions: Enrich templates with change-specific context
- formatChangeStatus: Format change status as readable output

This is Slice 3 of the artifact-graph system, building on the graph
operations (Slice 1) and change creation utilities (Slice 2).

* chore: archive add-instruction-loader change

- Move change to archive as 2025-12-28-add-instruction-loader
- Create instruction-loader spec with 4 requirements

* docs: add purpose description to instruction-loader spec
2025-12-28 17:44:05 +11:00
Tabish Bidiwale ab47cc6b00 feat: restructure schemas as directories with templates (#411)
* feat: restructure schemas as directories with templates

Move built-in schemas from embedded TypeScript objects to a file-based
directory structure. This enables co-located templates alongside schemas.

Changes:
- Remove builtin-schemas.ts (replaced by file-based schemas)
- Add schemas/ directory at package root with spec-driven and tdd schemas
- Update resolveSchema() to load from directory structure
- Resolution checks user dir → package dir

* chore: archive restructure-schema-directories change

* docs: update artifact_poc.md for directory-based schema structure

Update documentation to reflect the new schema structure where schemas
are directories containing schema.yaml and co-located templates/ rather
than single .yaml files with separate template directories.
2025-12-28 17:00:15 +11:00
Tabish Bidiwale 8dcd1707ee proposal: add instruction loader and schema restructure (Slice 3) (#410)
* proposal: add instruction loader and schema restructure (Slice 3)

Adds two change proposals for implementing Slice 3 of the artifact POC:

1. restructure-schema-directories
   - Move schemas from embedded TS objects to self-contained directories
   - Each schema becomes a directory with schema.yaml + templates/
   - Enables co-located templates for user extensibility
   - 2-level resolution: user override → package built-in

2. add-instruction-loader (depends on #1)
   - Load templates from schema directories
   - Enrich templates with change context (dependencies, next steps)
   - Format change status for CLI output
   - New instruction-loader capability

These proposals complete Slice 3 from docs/artifact_poc.md.

* fix: include full requirement block in MODIFIED spec

Update the Schema Loading requirement to include all original scenarios
(modified as needed) per the MODIFIED requirement guidelines. The archiver
replaces the entire requirement with the provided content.
2025-12-26 23:45:36 +11:00
Tabish Bidiwale 4f4af5708d feat: add change creation utilities (#408)
* proposal: add change manager - extract + new functionality

Slice 2 of the artifact tracker POC. Creates ChangeManager module that:

**Extracts existing functionality:**
- `listChanges()` from ListCommand + ChangeCommand.getActiveChanges()
- `changeExists()` from inline fs.access() checks
- `getChangePath()` from inline path.join() calls
- `isInitialized()` from ListCommand directory check

**Adds new functionality:**
- `createChange(name, description?)` - create change directory + README
- `validateName(name)` - enforce kebab-case naming

**Refactors CLI commands to be thin wrappers:**
- ListCommand delegates to ChangeManager
- ChangeCommand delegates to ChangeManager

Also updates docs/artifact_poc.md to reflect XDG decisions from Slice 1.

* proposal: simplify to utility functions only

Remove extraction/refactor scope. Just add:
- createChange(projectRoot, name, description?)
- validateChangeName(name)

Simple utility functions in src/utils/change-utils.ts.
No class, no abstraction layer.

* docs: update artifact_poc.md for simplified Slice 2

- Rename ChangeManager to change-utils (simple utility functions)
- Remove extracted methods (listChanges, getChangePath, etc.)
- Keep only new functionality: createChange(), validateChangeName()
- Update component diagram and summary table

* docs: clarify existing vs new functionality in artifact_poc.md

Audit artifact_poc.md against existing codebase to mark what already
exists vs what's genuinely new:

- Slice 4 CLI table: Added Status column (NEW/EXISTS)
- Added "Existing CLI commands" section listing what's not in scope
- Updated Implementation Order Slice 4 with explicit new vs existing
- Summary table: Updated status + added "What already exists" section

Key finding: The document was already well-simplified. Only truly new
functionality (createChange, validateChangeName, InstructionLoader,
artifact graph CLI commands) is proposed.

* rename: change-manager -> change-creation capability

The capability name "change-manager" implied a manager class abstraction,
but the simplified proposal uses only utility functions. Renamed to
"change-creation" to accurately reflect what the capability provides.

* feat: implement change creation utilities

Add createChange() and validateChangeName() functions for programmatic
change directory creation with kebab-case validation.

- createChange(projectRoot, name) creates openspec/changes/<name>/
- validateChangeName() enforces kebab-case naming conventions
- Comprehensive test coverage (21 tests)

* chore: archive add-change-manager change

Move change to archive and create change-creation spec with
requirements for createChange() and validateChangeName().

* docs: update change-creation spec purpose
2025-12-26 22:14:56 +11:00
Tabish Bidiwale 9822576770 fix(artifact-graph): normalize paths for cross-platform glob compatibility (#407)
Add FileSystemUtils.toPosixPath() utility and consolidate scattered
path normalization patterns. This fixes Windows test failures where
fast-glob couldn't match paths containing backslashes.

Root cause: path.join() uses backslashes on Windows, but fast-glob
requires forward slashes for glob patterns on all platforms.

Changes:
- Add toPosixPath() to FileSystemUtils for cross-platform path handling
- Update artifact-graph/state.ts to normalize glob patterns
- Consolidate path normalization in update.ts, validator.ts, and
  json-converter.ts to use the new utility
2025-12-25 22:42:00 +11:00
Tabish Bidiwale af273b8e0b proposal: add artifact graph core query system (#400)
* proposal: add artifact graph core query system

Add OpenSpec change proposal for Slice 1 of the artifact POC - the core
"What's Ready?" query system. This implements:

- ArtifactGraph class for DAG-based dependency modeling
- Filesystem-based state detection (file existence = completion)
- Topological sort for build order calculation
- Ready/blocked artifact queries

This is a parallel module that will coexist with the current system.

* docs: specify Zod for schema validation in artifact graph proposal

- Add decision section for Zod schema validation in design.md
- Update data structures to show Zod schemas with z.infer<> types
- Update tasks to specify Zod usage for type definitions and parsing

* docs: add 2-level schema resolution and built-in schemas

- Add decision for global → built-in schema resolution pattern
- Add resolver.ts for schema lookup logic
- Add built-in schemas directory (spec-driven.yaml, tdd.yaml)
- Add schema resolution tests
- Follows ESLint/Prettier/Git patterns (defaults baked in package)

* experiment: add vertical slice version of artifact graph change

Creates add-artifact-graph-core-v2 with requirements organized as
vertical slices - each requirement file contains its spec, design
decisions, and tasks bundled together for comparison.

* feat(core): add getGlobalDataDir for XDG-compliant data directory

Add getGlobalDataDir() function following XDG Base Directory Specification
for storing user data like schema overrides:
- XDG_DATA_HOME takes precedence on all platforms
- Unix/macOS fallback: ~/.local/share/openspec/
- Windows fallback: %LOCALAPPDATA%/openspec/

* feat(artifact-graph): add core dependency graph module

Implement Slice 1 ("What's Ready?") of the artifact graph system:

- types.ts: Zod schemas for artifact definitions with derived TypeScript types
- schema.ts: YAML parsing with validation for duplicates, invalid refs, cycles
- graph.ts: ArtifactGraph class with Kahn's algorithm for topological sort
- state.ts: Filesystem-based completion detection with glob pattern support
- resolver.ts: Two-level schema resolution (global override → built-in)
- builtin-schemas.ts: spec-driven and tdd workflow definitions

Key design decisions:
- Filesystem as database (stateless, git-friendly)
- Cycle errors show full path (e.g., "A → B → C → A")
- Deterministic ordering via sorted queues

* test(artifact-graph): add comprehensive test suite

52 tests covering all artifact-graph functionality:

- schema.test.ts: Parsing, validation errors, cycle detection
- graph.test.ts: Build order, ready artifacts, blocked queries
- state.test.ts: File existence, glob patterns, missing directories
- resolver.test.ts: Schema resolution with global overrides

* docs(openspec): archive add-artifact-graph-core change

Archive completed change proposal and create artifact-graph spec with
6 requirements covering schema loading, build order, state detection,
ready queries, completion checks, and blocked queries.

* chore: remove experimental artifact-graph-core-v2 folder

Clean up experimental vertical slice proposal that is no longer needed.

* feat(artifact-graph): validate global schema overrides

Global schema overrides are now validated through the same pipeline as
built-in schemas, catching invalid schemas, cyclic dependencies, and
invalid requires references at load time. Added SchemaLoadError for
better error context with file paths.

* test(artifact-graph): add workflow integration tests

Add end-to-end integration tests that exercise the full artifact-graph
pipeline: resolveSchema → ArtifactGraph → detectCompleted → queries.

Tests cover:
- Complete spec-driven and tdd workflow progressions
- Out-of-order file creation handling
- Glob pattern matching with multiple files
- Build order consistency
- Edge cases (empty/missing directories, non-matching files)

* refactor(artifact-graph): adopt zod v4 error message format

Update custom error messages from string format to zod v4 object format
using `{ error: 'message' }` convention.

* fix(test): prevent hanging vitest threads after test runs

- Add teardownTimeout (3s) to vitest config for forced cleanup
- Add global teardown function to vitest.setup.ts
- Call child.unref() to prevent child processes from blocking event loop
- Explicitly destroy stdio streams on process close/error
2025-12-25 22:09:42 +11:00
Eunsong-Park 3ceef2db72 fix(archive): allow REMOVED requirements when creating new spec files (#403) (#404)
When creating a new spec file, REMOVED requirements are now ignored
with a warning instead of causing archive to fail. This enables
refactoring scenarios where old fields are removed while documenting
a capability for the first time.

Fixes #403
2025-12-25 03:44:34 +11:00
Tabish Bidiwale 2c2599b1f0 docs: add artifact POC analysis document (#398)
Add internal documentation for the artifact-based approach to OpenSpec
core. This document outlines design decisions, terminology, and the
philosophy behind treating dependencies as enablers rather than gates.
2025-12-23 22:21:11 +11:00
github-actions[bot]andTabish Bidiwale c08a53cb21 chore(release): version packages (#397)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-12-23 12:59:10 +11:00
Tabish Bidiwale 455c65f3c4 Add changeset for --no-interactive flag fix (#396) 2025-12-23 12:45:56 +11:00
Tabish Bidiwale 9ac6330430 fix(cli): respect --no-interactive flag in validate command (#395)
* fix(cli): respect --no-interactive flag in validate command

The validate command's spinner was starting regardless of the
--no-interactive flag, causing hangs in pre-commit hooks.

Changes:
- Pass noInteractive option to runBulkValidation
- Handle Commander.js --no-* flag syntax (sets interactive=false)
- Only start ora spinner when in interactive mode
- Add CI environment variable check to isInteractive() for industry
  standard compliance

* test: add unit tests for interactive utilities and CLI flag

- Export resolveNoInteractive() helper for reuse
- Add InteractiveOptions type export for testing
- Refactor validate.ts to use resolveNoInteractive()
- Add 17 unit tests for isInteractive() and resolveNoInteractive()
- Add CLI integration test for --no-interactive flag

This prevents future regressions where Commander.js --no-* flag
parsing is not properly handled.
2025-12-23 12:42:25 +11:00
github-actions[bot]andTabish Bidiwale fb264bcbcd chore(release): version packages (#394)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-12-23 10:00:01 +11:00
Tabish Bidiwale a2757e7856 Add changeset for config command dynamic import fix (#393) 2025-12-23 09:56:51 +11:00
Tabish Bidiwale 6d84924c18 fix(cli): use dynamic import for @inquirer/prompts in config command (#392)
* fix(cli): use dynamic import for @inquirer/prompts in config command

The config command (added in #382) reintroduced the pre-commit hook hang
issue that was fixed in #380. The static import of @inquirer/prompts at
module load time causes stdin event listeners to be registered even when
running non-interactive commands, preventing clean process exit when
stdin is piped (as pre-commit does).

Convert the static import to a dynamic import that only loads inquirer
when the `config reset` command is actually used interactively.

Fixes #367

* chore: add ESLint with no-restricted-imports rule for @inquirer

Add ESLint configuration that prevents static imports of @inquirer/*
modules. This prevents future regressions of the pre-commit hook hang
issue fixed in this PR.

The rule shows a helpful error message pointing to issue #367 for context.
init.ts is exempted since it's already dynamically imported from the CLI.

* ci: add ESLint step to lint job

Run `pnpm lint` in CI to enforce the no-restricted-imports rule
that prevents static @inquirer imports.
2025-12-23 09:50:54 +11:00
Tabish Bidiwale 6de04f3b2b feat(ci): migrate to npm OIDC trusted publishing (#390)
Replace classic npm token authentication with OIDC trusted publishing:

- Add `id-token: write` permission for OIDC token generation
- Upgrade to Node 24 (includes npm 11.5.1+ required for OIDC)
- Remove NPM_TOKEN/NODE_AUTH_TOKEN env vars (OIDC replaces them)

This eliminates the need for rotating npm access tokens and provides
cryptographically verified publisher identity with automatic provenance
attestation.

Requires configuring trusted publisher on npmjs.com:
- Organization: Fission-AI
- Repository: OpenSpec
- Workflow: release-prepare.yml
2025-12-22 20:10:27 +11:00
github-actions[bot]andTabish Bidiwale c2a1a4c807 chore(release): version packages (#389)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-12-22 18:44:57 +11:00
Tabish Bidiwale 2e71835d23 Add changeset for config command and shell completions (#388) 2025-12-22 18:35:29 +11:00
Tabish Bidiwale 971f8ca4a3 feat(cli): add openspec config command for global configuration management (#382)
* feat(cli): add openspec config command for global configuration management

Implements the `openspec config` command with subcommands:
- `path`: Show config file location
- `list [--json]`: Show all current settings
- `get <key>`: Get a specific value (raw output for scripting)
- `set <key> <value> [--string]`: Set a value with auto type coercion
- `unset <key>`: Remove a key (revert to default)
- `reset --all [-y]`: Reset configuration to defaults
- `edit`: Open config in $EDITOR/$VISUAL

Key features:
- Dot notation for nested key access (e.g., featureFlags.someFlag)
- Auto type coercion (true/false → boolean, numbers → number)
- --string flag to force string storage
- Zod schema validation with unknown field passthrough
- Reserved --scope flag for future project-local config
- Windows-compatible editor spawning with proper path quoting
- Shell completion registry integration

* test(config): add additional unit tests for validation and coercion

- Add tests for unknown fields with various types
- Add test to verify error message path for featureFlags
- Add test for number values rejection in featureFlags
- Add config set simulation tests to verify full coerce → set → validate flow

* fix(config): avoid shell parsing in config edit to handle paths with spaces

Use spawn with shell: false and pass configPath as an argument instead
of building a shell command string. This correctly handles spaces in
both the EDITOR path and config file path on all platforms.

* chore(openspec): archive add-config-command and create cli-config spec

Move completed change to archive and apply spec deltas to create
the cli-config specification documenting the config command interface.

* Validate config keys on set
2025-12-22 18:29:25 +11:00
Tabish Bidiwale 68e0a7e68e fix(cli): prevent hang in pre-commit hooks by using dynamic imports (#380)
Fixes #367

The CLI was hanging when run as a pre-commit hook because @inquirer/prompts
was statically imported at module load time. Even when prompts were never
called (e.g., `openspec validate --specs --no-interactive`), the import
itself could set up stdin references that prevented clean process exit
when stdin was piped.

Changes:
- Convert all static `@inquirer/prompts` imports to dynamic imports
- Dynamically import `InitCommand` (which uses `@inquirer/core`)
- Update `isInteractive()` to accept options object with both
  `noInteractive` and Commander's negated `interactive` property
- Handle empty validation queue with proper exit code

Now when running in non-interactive mode, the inquirer modules are never
loaded, allowing the process to exit cleanly after completion.
2025-12-21 18:10:53 +11:00
Tabish Bidiwale f39cc5c1fb fix(global-config): respect XDG_CONFIG_HOME on all platforms (#378)
Prioritize XDG_CONFIG_HOME on Windows to fix test environment overrides.
Previously, Windows would always use APPDATA regardless of XDG_CONFIG_HOME,
causing tests to fail. Now XDG_CONFIG_HOME is checked first on all platforms
before falling back to platform-specific defaults.

Also update the Windows APPDATA test to explicitly clear XDG_CONFIG_HOME
when testing the fallback behavior.
2025-12-20 23:01:04 +11:00
Tabish Bidiwale 5129a8cf96 feat(core): implement global config directory with XDG support (#377)
* feat(core): implement global config directory with XDG support

Add new global-config module following XDG Base Directory Specification with platform-specific fallbacks (Unix: ~/.config/openspec, Windows: %APPDATA%/openspec). Includes config loading with defaults, config saving with directory creation, and full test coverage. Archive add-global-config-dir change.

* docs(spec): add Purpose section to global-config spec

Replace placeholder text with a concise description of what the spec governs, its scope, and high-level objectives.
2025-12-20 20:16:53 +11:00
Tabish Bidiwale 4ff893048d feat(spec): add XDG global config directory and config command proposals (#376)
Create two OpenSpec change proposals:
1. add-global-config-dir: Foundation for user-level configuration following XDG Base Directory Specification with cross-platform support
2. add-config-command: User-facing CLI command for viewing and managing global settings

Both proposals are minimal and focused on providing a clean, extensible base for OpenSpec settings and future feature flags.
2025-12-20 19:45:55 +11:00
Tabish Bidiwale cefb4719aa fix(completions): resolve Windows compatibility issues in zsh-installer tests (#373)
- Fix canWriteFile to use fs.access with W_OK flag instead of Unix-style
  permission bits (stats.mode & 0o222) which don't work on Windows
- Update test paths to use platform-specific invalid paths that fail on
  both Unix and Windows
- Use regex for path separator matching in test assertions
2025-12-19 23:37:59 +11:00
Tabish Bidiwale 5e1cef3b3b fix(spec): align cli-completion spec with implementation (#360)
Update the cli-completion spec to match the actual implementation:

- Change `completion zsh` to `completion generate [shell]` command structure
- Update uninstall behavior to reflect confirmation prompt cancels entire operation
- Change "not installed" uninstall exit code from 0 to 1
- Update shell detection error message to match implementation
- Replace Purpose placeholder with actual description
2025-12-12 22:13:52 +11:00
1adf3cea88 feature/oh-my-zsh-completions (#289)
* shell completions for zsh

* after code review changes

* expose only postinstall.js script

* Replace _openspec "$@" with compdef in zsh-generator.ts to prevent execution during load

* Update test/commands/completion.test.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* - Fix dispatcher to use $words instead of $line for subcommand routing
  - Add __complete endpoint with tab-separated output for safe parsing
  - Replace brittle awk parsing with __complete in completion helpers
  - Add uninstall confirmation prompt with --yes flag to skip
  - Prefer $ZSH env var for Oh My Zsh detection before dir check
  - Add fpath verification guidance for OMZ installations
  - Update cli-completion spec to document generate subcommand

* improve shell detection and installation handling

  - Return structured result from detectShell() with shell and detected name
  - Detect already-installed completions and skip reinstall
  - Add update detection with automatic backup of previous version
  - Add debug logging to silent catch blocks for diagnostics
  - Quote fpath directories to handle paths with spaces
  - Verify Oh My Zsh fpath configuration and add to .zshrc if needed
  - Show helpful error for detected but unsupported shells
  - Update all tests for new detection API

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2025-12-12 21:30:40 +11:00
Tabish Bidiwale 6d3cfe0443 docs(readme): alphabetize AI tools list and make collapsible (#343)
- Sort supported AI tools alphabetically (A-Z)
- Wrap both "Native Slash Commands" and "AGENTS.md Compatible" sections
  in collapsible <details> tags to reduce visual clutter
2025-11-28 16:13:36 +11:00
Tabish Bidiwale 17d1e5db3f fix(opencode): remove hardcoded agent field from slash commands (#335)
Remove the `agent: build` field from OpenCode slash command templates
to allow OpenCode to use the current/custom agent instead of requiring
the build agent to be available.

Fixes #334
2025-11-25 12:07:51 +11:00
github-actions[bot]andTabish Bidiwale 3f5a66d3e4 chore(release): version packages (#327)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-11-21 22:58:29 +11:00
Tabish Bidiwaleandcoderabbitai[bot] c08fbc1ba0 chore: add changeset for new features and improvements (#326)
* Add changeset for new features and improvements

* Update .changeset/new-features-and-improvements.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-11-21 21:49:33 +11:00
Tabish Bidiwale 938d03be9a feat(init): add IDE restart instruction after init (#323)
Add prominent restart instruction in success message to inform users
they need to restart their IDE/coding tool for slash commands to appear.
Applies to all tools when slash commands are created or refreshed.

Also updates cli-init spec to document the restart instruction requirement.
2025-11-21 20:29:53 +11:00
dkmos2016 19ccaabfc7 feat(iflow-cli): add iFlow-cli integration (#268)
* support iflow-cli

* docs: add iFlow to supported AI tools in README ([#268](https://github.com/Fission-AI/OpenSpec/pull/268))

Add iFlow to the Native Slash Commands table in the README. iFlow support was implemented but was missing from the documentation.

* add UTs for iflow-cli
2025-11-20 21:57:58 +11:00
Tabish Bidiwale 2e382b9898 Add Antigravity slash command support (#318) 2025-11-19 17:18:52 +11:00
Tabish Bidiwale b5a7d096f0 fix: generate TOML commands for Qwen Code (fixes #293) (#317) 2025-11-19 16:52:44 +11:00
Tabish Bidiwale c54079a0cd Clarify scaffold proposal (#310)
* clarify scaffold proposal

* Update scaffold command proposal to support idempotent execution
2025-11-19 16:23:57 +11:00
jax 1050e57ae4 Enhance proposal guidelines in slash-command-templates.ts (#306)
* Enhance proposal guidelines in slash-command-templates.ts

- Added instructions to avoid writing code during the proposal stage and focus on creating design documents.
- Emphasized the design phase by including a reminder not to implement code until the apply stage.
- Updated validation steps to clarify the importance of confirming project conventions before proceeding with tasks.

* Update proposal guidelines in slash-command-templates.ts to clarify that no implementation code should be written during the design phase.

* Refine proposal and apply steps in slash-command-templates.ts

- Removed redundant instruction in proposal steps to streamline the process.
- Clarified the initial reading order for apply steps by omitting the project conventions document, focusing on the proposal and design documents instead.
2025-11-19 15:34:07 +11:00
github-actions[bot]andTabish Bidiwale 17d7e59343 chore(release): version packages (#305)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-11-14 16:32:10 +11:00
Tabish Bidiwale 4758c5c68d Add changeset for new AI tool integrations (#304) 2025-11-14 16:30:16 +11:00
jax c4b0826da7 feat(roocode): add RooCode integration (configurator, slash commands, templates) (#288)
* feat(roocode): Added RooCode tool support and related configurations

Added RooCode tool integration, including:

- Added RooCode configurator class
- Registered RooCode to the tool registry
- Implemented RooCode template files
- Added RooCode slash command support
- Updated README documentation
- Added related test cases

* Removed RooCode related configurations from the project. This includes deleting the RooCode configurator, its template, and associated tests.
2025-11-14 13:44:14 +11:00
537e6078b7 Fix Cline: use workflows instead of rules for slash commands (#283)
* fix(cline): use workflows instead of rules for slash commands

- Update ClineSlashCommandConfigurator to use .clinerules/workflows/ paths
- Update tests to expect correct workflow file locations
- Update README.md to reflect workflows instead of rules
- Fixes Cline integration to match Cline's architecture per their blog post

* Adds spec for fix-cline-workflows-implementation

---------

Co-authored-by: didier <didier.boff@axess.fr>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2025-11-13 23:03:51 +11:00
Tabish Bidiwale 5439ab0833 Document Gemini CLI slash updates (#301) 2025-11-11 22:14:56 +11:00
Larry HopeandTabish Bidiwale 9b6a763eb8 feat: Add Gemini CLI support with TOML-based slash commands (#256)
* feat: add Gemini CLI support with TOML-based slash commands

- Add GeminiSlashCommandConfigurator for .gemini/commands/openspec/
- Register Gemini CLI in AI_TOOLS config and slash command registry
- Generate TOML files with description and prompt fields
- Add comprehensive test coverage for Gemini CLI integration
- Update README to list Gemini CLI under Native Slash Commands
- Remove Gemini CLI from AGENTS.md compatible list (now native)

Implements GitHub issue #248

* [add]

* feat: address PR feedback - remove changeset and add update test

- Remove .changeset/add-gemini-cli-support.md as requested by maintainer
- Add test for Gemini CLI TOML update/refresh path
- Test verifies that existing TOML files are properly updated when running init again

Addresses feedback from TabishB in PR #256

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2025-11-11 21:26:44 +11:00
github-actions[bot]andTabish Bidiwale d32e50fe36 chore(release): version packages (#271)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-11-04 19:39:29 +11:00
Tabish Bidiwale 8386b91a71 Add changeset for AI assistants support and configuration improvements (#270) 2025-11-03 11:20:27 +11:00
8f9c3c7d0b feat: add Qwen Code support with slash command integration (#250)
* feat: add Qwen Code support with slash command integration

- Add QwenSlashCommandConfigurator for .qwen/commands/ structure
- Add QwenConfigurator to main registry
- Update README.md to include Qwen Code in supported tools list
- Register Qwen in both slash command and main tool registries
- Implement proper YAML frontmatter for Qwen command files
- Follow OpenSpec's established patterns for AI tool integration

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs: add docstrings and fix review comments for Qwen Code support

- Add comprehensive JSDoc comments to Qwen configurator files
- Add Qwen Code entry to README_CN.md support table
- Fix file ending newline in src/core/configurators/qwen.ts
- Address CodeRabbit review suggestions for improved documentation coverage

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: add language identifier to markdown code block in supportQwen.md

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: address CodeRabbit review comments - parameter naming fix

- Fix unused parameter naming convention (_openspecDir)
- Keep only necessary changes for Qwen Code support

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* chore: add personal notes files to .gitignore

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* chore: remove personal notes files from git tracking

- Remove README_CN.md and supportQwen.md from git tracking
- These files are now ignored via .gitignore
- Keep only necessary files for the OpenSpec project

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix: remove duplicate JSDoc comment in QwenConfigurator

- Remove duplicate documentation comment for configure method
- Keep only the updated comment that correctly documents the unused parameter

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test: cover qwen configurators

* chore: revert gitignore changes

* test: extend qwen init coverage

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-11-03 11:03:39 +11:00
Tabish Bidiwale 9cdb0743f2 feat: add $ARGUMENTS support to apply slash command (#244)
This change adds the $ARGUMENTS property to the OpenCode apply slash command template, allowing users to pass arguments when invoking the apply command. The template now includes instructions for the agent to find and implement the change proposal, with guidance to ask for clarification when ambiguous.
2025-11-02 23:12:02 +11:00
KUTEJiangandpengjiahan.pjh 4e93d7a881 feat: add Qoder CLI support to configuration and documentation (#261)
Co-authored-by: pengjiahan.pjh <pengjiahan.pjh@antgroup.com>
2025-11-01 19:49:36 +11:00
mini2s c4b6be41c1 feat: add CoStrict AI assistant support (#240)
* feat(ai-tools): add Costrict integration support

Add support for Costrict AI tool with slash commands and configuration template. Includes configurator, registry entries, templates, and comprehensive test coverage.

* feat(config): update branding from 'Costrict' to 'CoStrict'
2025-11-01 19:10:23 +11:00
HariKrishnanandClaude a66580735c docs: add guidance for populating project-level context (#241)
* docs: add optional project context setup instructions

Add documentation for the optional step of populating project.md with
project details, tech stack, and conventions after running openspec init.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* docs: improve project context section formatting and clarity

- Change heading to "Optional: Populate Project Context" for consistency
- Fix double space typo in "After  openspec init"
- Explicitly reference openspec/project.md file
- Enhance explanation of project.md purpose

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 10:12:14 +11:00
Tabish Bidiwale fb1d37e56e fix: recreate missing openspec template files in extend mode (#238)
* fix: recreate missing openspec template files in extend mode

The init command now checks for and recreates missing template files
(like openspec/AGENTS.md and openspec/project.md) when running in
extend mode, instead of skipping file generation entirely.

Previously, if a user deleted openspec/AGENTS.md and ran init again,
the file would not be recreated because the openspec/ directory
existed, triggering extend mode which skipped all file generation.

Changes:
- Added ensureTemplateFiles() method to check and recreate missing files
- Modified extend mode to call ensureTemplateFiles() instead of skipping
- Updated message to "Checking for missing files..." for clarity
- Added tests for recreating deleted openspec/AGENTS.md and project.md

* refactor: consolidate duplicate logic in template file generation

Extracted shared logic from generateFiles() and ensureTemplateFiles()
into a new writeTemplateFiles() method with a skipExisting parameter.
This eliminates code duplication while maintaining the same behavior.

* test: improve extend mode test coverage and reduce duplication

- Extracted testFileRecreationInExtendMode helper to reduce code duplication
- Added test to verify existing files are preserved in extend mode
- Ensures skipExisting behavior is properly tested
2025-10-25 23:55:49 +11:00
Tabish Bidiwale cf0de5e569 fix: prevent false 'already configured' detection for tools (#239)
* fix: prevent false "already configured" detection for tools

Fixes #195

## Problem
Users with existing tool config files (like CLAUDE.md) would see those
tools marked as "already configured" even when running `openspec init`
for the first time. This caused confusion as users thought OpenSpec was
already set up when it wasn't.

Root causes:
1. Tool detection checked only for file existence, not OpenSpec ownership
2. Detection ran even in fresh projects without openspec/ folder

## Solution
Two-part fix:

1. **Conditional detection**: Only check tool configuration when in extend
   mode (when openspec/ directory already exists). Fresh initializations
   skip the check entirely, treating all tools as unconfigured.

2. **Marker-based validation**: For tools to be considered "configured by
   OpenSpec", their files must contain OpenSpec markers (<!-- OPENSPEC:START -->
   and <!-- OPENSPEC:END -->). For tools with both config files and slash
   commands (like Claude Code), BOTH must have markers.

## Changes
- Modified getExistingToolStates() to accept extendMode parameter
- Rewrote isToolConfigured() to verify OpenSpec markers in files
- Added OPENSPEC_MARKERS to imports
- Added 4 comprehensive test cases covering the new behavior

## Test Coverage
- Fresh init with existing CLAUDE.md → NOT shown as configured ✅
- Fresh init with existing slash commands → NOT shown as configured ✅
- Extend mode with OpenSpec files → shown as configured ✅
- Fresh init with global Codex prompts → NOT shown as configured ✅

All 240 tests pass.

* refactor: optimize tool state detection and improve code clarity

Address code review feedback:

1. **Parallelize tool state checks**: Changed from sequential `for` loop to
   `Promise.all()` for checking multiple tools simultaneously. This reduces
   I/O latency during extend mode initialization.

2. **Extract marker validation helper**: Created `fileHasMarkers()` helper
   function to eliminate code duplication between config file and slash
   command checks. Makes the logic clearer and more maintainable.

3. **Clarify slash command policy**: Added explicit comment that "at least
   one file with markers is sufficient" (not all required) for slash commands.
   This is correct because OpenSpec creates all files together - if any
   exists with markers, the tool was configured by OpenSpec.

4. **Simplify fresh init path**: Use `Object.fromEntries()` for cleaner
   initialization of all-false states.

Performance improvement: Extend mode now checks tools in parallel instead
of serially, reducing init time especially for projects with many tools.
2025-10-25 20:46:49 +11:00
Tabish Bidiwale 92b45462c6 fix: use change-id as fallback title instead of "Untitled Change" (#236)
* fix: use change-id as fallback title instead of "Untitled Change"

Fixes #225 by addressing mismatch between proposal template and title extraction:

- Updated proposal template to include `# Change: [description]` header
- Changed extractTitle fallback from "Untitled Change" to change-id
- Updated all extractTitle call sites to pass changeName parameter

This ensures both new and existing proposals display meaningful titles.

* refactor: make title extraction case-insensitive for "Change:"

Makes the extractTitle regex case-insensitive to handle variations like
"# change:" or "# CHANGE:" in addition to "# Change:".
2025-10-25 16:30:37 +11:00
Tabish Bidiwale 5ab438f5fd docs: add Crush to supported AI tools in README (#235)
Add Crush to the Native Slash Commands table in the README. Crush support was implemented in the codebase but was missing from the documentation.
2025-10-24 12:46:35 +11:00
github-actions[bot]andTabish Bidiwale 5855fa2353 chore(release): version packages (#228)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-22 17:18:52 +11:00
Tabish Bidiwale 668a125d4d chore: add changeset for AI assistants support and validation fixes (#227)
* fix: manually merge and archive four completed OpenSpec changes

Merged and archived four concurrent changes that modified the same specs:
- add-cline-support: Added Cline AI tool configuration
- add-crush-support: Added Crush AI tool configuration
- add-factory-slash-commands: Added Factory Droid slash commands
- add-archive-command-arguments: Added archive command argument support

Changes to cli-init/spec.md:
- Added Cline and CodeBuddy Code configuration scenarios
- Added slash command scenarios for CodeBuddy Code, Cline, Crush, Factory Droid

Changes to cli-update/spec.md:
- Added update scenarios for CodeBuddy Code, Cline, Crush, Factory Droid
- Added Archive Command Argument Support requirement
- Modified OpenCode scenario to support $ARGUMENTS placeholder

This required manual intervention to prevent data loss from OpenSpec's
requirement-level replacement during archiving. The archive operations
initially overwrote scenarios from earlier changes, requiring restoration
of all missing content to preserve complete spec state.

All four changes successfully archived to openspec/changes/archive/.

* Add changeset for AI assistants support and validation fixes
2025-10-22 17:03:48 +11:00
Tabish Bidiwale fef961f6e3 fix: manually merge and archive four completed OpenSpec changes (#226)
Merged and archived four concurrent changes that modified the same specs:
- add-cline-support: Added Cline AI tool configuration
- add-crush-support: Added Crush AI tool configuration
- add-factory-slash-commands: Added Factory Droid slash commands
- add-archive-command-arguments: Added archive command argument support

Changes to cli-init/spec.md:
- Added Cline and CodeBuddy Code configuration scenarios
- Added slash command scenarios for CodeBuddy Code, Cline, Crush, Factory Droid

Changes to cli-update/spec.md:
- Added update scenarios for CodeBuddy Code, Cline, Crush, Factory Droid
- Added Archive Command Argument Support requirement
- Modified OpenCode scenario to support $ARGUMENTS placeholder

This required manual intervention to prevent data loss from OpenSpec's
requirement-level replacement during archiving. The archive operations
initially overwrote scenarios from earlier changes, requiring restoration
of all missing content to preserve complete spec state.

All four changes successfully archived to openspec/changes/archive/.
2025-10-22 16:07:28 +11:00
jasonwang82andJason Wang 3677e0175f feat: add CodeBuddy Code support to configuration and documentation (#217)
Co-authored-by: Jason Wang <you@example.com>
2025-10-21 16:12:46 +11:00
Tabish Bidiwale 3ddf2586b4 feat: add CodeRabbit AI assistant support (#221)
Add CodeRabbit configuration to enable AI-powered code reviews with customized review settings, path-specific instructions, and chat configuration.
2025-10-21 14:04:47 +11:00
scala63andningchen ece61a6d68 feat: add Cline support (#213)
Co-authored-by: ningchen <n.ning.c.chen@oracle.com>
2025-10-21 12:08:21 +11:00
Tabish Bidiwale ecddffc22e fix: improve delta spec validation with case-insensitive headers and empty section detection (#191)
This commit enhances the validation logic for delta specs:
- Delta section headers are now parsed case-insensitively (e.g., "Added Requirements" and "ADDED Requirements" both work)
- Empty delta sections now produce clear error messages guiding users to add requirement entries
- Specs with no delta headers at all now receive specific error messages
- Added test coverage for case-insensitive delta header parsing
2025-10-19 23:56:53 +11:00
HariKrishnanandClaude 822464ec44 chore(dev): add VS Code dev container configuration (#209)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-19 21:50:50 +11:00
Gianluca BoianoandCrush 67ab683105 feat: add Crush AI assistant support (#206)
Add comprehensive OpenSpec integration for Crush AI assistant including:
- CrushSlashCommandConfigurator for proposal, apply, and archive commands
- Integration with slash command registry and CLI tools
- Generates .crush/commands/openspec/ with proper frontmatter and workflows
- Available via `openspec init --tools crush`


💘 Generated with Crush

Co-authored-by: Crush <crush@charm.land>
2025-10-19 11:55:36 +11:00
Vimpas f82e243551 feat: add Auggie (Augment CLI) support to configuration and documenta… (#196)
* feat: add Auggie (Augment CLI) support to configuration and documentation

- Added Auggie (Augment CLI) to the AI tools configuration in `config.ts`.
- Updated the slash command registry to include Auggie's configurator.
- Documented Auggie's commands in the README.md for better visibility.

This enhances the integration of Auggie within the existing toolset.

* test: add tests for Auggie command file creation and updates

- Implemented tests to verify the creation of Auggie slash command files with appropriate templates.
- Added checks to ensure existing Auggie command files are refreshed correctly during updates.
- Confirmed that missing command files are not created during the update process.

These changes enhance the test coverage for Auggie's integration and ensure proper functionality of command file management.
2025-10-17 14:01:28 +11:00
Tabish Bidiwale 88b260d51f fix: honor --no-validate and ignore metadata during archive validation (#190)
* fix: skip metadata when validating requirement SHALL/MUST keywords

Fixes validation incorrectly checking metadata lines instead of requirement text.

The extractRequirementText() function was returning the first non-empty line
after the requirement header, which was often metadata like **ID**: REQ-001
instead of the actual requirement statement.

Changes:
- Updated extractRequirementText() to skip lines matching **Key**: Value pattern
- Skip blank lines between header and requirement text
- Return first substantive text line for SHALL/MUST validation

Added comprehensive tests for:
- Requirements with metadata before SHALL/MUST text
- Requirements with SHALL in text but not header
- Requirements correctly failing without SHALL/MUST
- Requirements without metadata fields

All 20 validation tests pass.

Fixes #159

* Respect --no-validate flag while archiving
2025-10-16 17:34:33 +11:00
Tabish Bidiwale ce7422209f docs: sync AGENTS.md and agents-template with explicit change-id notation (#189)
Standardize archive command documentation to use `<change-id>` instead of `[change]` to clarify that the change ID must be explicitly passed. Remove OpenCode-specific slash command reference from AGENTS.md to keep it tool-agnostic.
2025-10-16 14:48:12 +11:00
Tabish Bidiwale 63b8a3e9f9 feat: add argument support to archive slash command (#183)
* feat: add argument support to archive slash command

Add $ARGUMENTS placeholder to the /openspec:archive slash command to allow explicit change ID specification, improving safety and matching CLI behavior.

Changes:
- Add $ARGUMENTS to archive command frontmatter in OpenCode configurator
- Update archive command template with argument validation steps
- Add rewriteArchiveFile method to handle managed section updates
- Update AGENTS.md documentation for archive command usage

This change makes it possible for users to run `/openspec:archive <change-id>` instead of relying on context inference, reducing the risk of archiving the wrong change.

* refactor: improve archive slash command argument handling instructions

Update the archive slash command template to provide clearer guidance on how
to handle change IDs from arguments versus conversation context. The new
instructions better distinguish between explicit argument-provided IDs and
contextual references, and provide more explicit failure modes.
2025-10-16 14:05:29 +11:00
Tabish Bidiwale 4cf7bf863d docs: note restart for slash commands (#182) 2025-10-15 14:37:38 +11:00
github-actions[bot]andTabish Bidiwale b30882b579 chore(release): version packages (#180)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-14 21:36:52 +11:00
Tabish Bidiwale 082abb4795 Add changeset for factory functions and init options (#179) 2025-10-14 21:29:59 +11:00
Tabish Bidiwale b81fa1e6cc feat: add factory function support for slash commands (#178)
This change adds support for factory functions in slash command configuration,
allowing slash commands to be defined as functions that return command objects.
2025-10-14 21:19:58 +11:00
Tabish Bidiwale 4a863285b0 chore: archive 4 completed changes and update specs (#172)
Archived:
- enhance-validation-error-messages (updated cli-validate spec)
- improve-agent-instruction-usability (created docs-agent-instructions spec)
- update-cli-init-root-agents (updated cli-init and cli-update specs)
- update-release-automation (no spec updates)
2025-10-14 15:42:49 +11:00
Tabish Bidiwale fe83be5d61 Add parallel merge plan (#171) 2025-10-14 15:39:25 +11:00
Tabish Bidiwale 345f9dbb45 chore: archive 7 completed changes and update specs (#170)
Archive completed changes:
- add-non-interactive-init-options
- slim-root-agents-file
- update-cli-init-enter-selection
- add-windsurf-workflows
- add-kilocode-workflows
- add-codex-slash-command-support
- add-github-copilot-prompts

Updates to specs:
- cli-init: Added 7 slash command scenarios (Claude Code, Cursor, OpenCode, Windsurf, Kilo Code, Codex, GitHub Copilot)
- cli-update: Added corresponding update scenarios for all 7 tools
- Fixed MODIFIED requirement deltas to include all existing scenarios before archiving
- Manual correction applied to preserve Windsurf scenario after archive conflicts

All changes validated with --strict flag.
2025-10-14 15:24:49 +11:00
cc9d5402ff feat: add non-interactive options to openspec init (#122)
* feat: add non-interactive options to openspec init

- Add --tools, --all-tools, and --skip-tools CLI options
- Enable automated initialization for CI/CD pipelines
- Maintain backward compatibility with interactive mode
- Add comprehensive validation and error handling
- Update cli-init spec with non-interactive requirements
- Add unit and integration tests for new functionality

Closes change proposal: add-non-interactive-init-options

* feat(init): add single --tools flag for non-interactive init

* test(init): verify --tools help lists available ids

* Revert manual spec.md edits

The canonical spec shouldn't be edited directly when a change delta
already captures the update. Archiving that delta will sync the spec.

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-14 14:14:05 +11:00
github-actions[bot]andTabish Bidiwale 108bcd66d8 chore(release): version packages (#167)
* Version Packages

* run CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-13 19:49:08 +11:00
Tabish Bidiwale a50105e03c fix: use correct scoped package name in changeset (#166) 2025-10-13 19:41:25 +11:00
Tabish Bidiwale 312e1d6d7c Add changeset for Amazon Q Developer integration (#165) 2025-10-13 19:33:35 +11:00
Brian AndersonandBrian Anderson 56d57da119 Amazon Q Developer integration (#160)
* feat: add Amazon Q Developer CLI integration

- Add AmazonQSlashCommandConfigurator for .amazonq/prompts/ support
- Register Amazon Q in SlashCommandRegistry and AI_TOOLS config
- Generate slash commands compatible with Amazon Q CLI (@-syntax)
- Update README.md with Amazon Q Developer in tools table

* test: add Amazon Q Developer integration tests

- Add init tests for Amazon Q prompt file creation and configuration detection
- Add update tests for Amazon Q prompt refresh and missing file handling
- Follow same test patterns as GitHub Copilot integration
- Verify .amazonq/prompts/ directory structure and file content

---------

Co-authored-by: Brian Anderson <brian@popsofviolet.com>
2025-10-12 18:17:01 +11:00
github-actions[bot]andTabish Bidiwale f56189a8f7 chore(release): version packages (#158)
* Version Packages

* chore: trigger CI

* chore: trigger CI again

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-12 15:06:46 +11:00
Tabish Bidiwale d7e0ce85e5 Add changeset for init wizard Enter key improvements (#157) 2025-10-12 14:59:47 +11:00
Tabish Bidiwale eb0d50c094 feat: improve init wizard Enter key behavior (#156)
Update the tool selection wizard so pressing Enter on a highlighted tool
automatically selects it before proceeding to the review step. This aligns
with common CLI expectations where Enter confirms the highlighted item.

Changes:
- Add logic to select the currently highlighted tool when Enter is pressed
- Update help text to clarify that Enter selects the highlighted tool
- Maintain Space key for toggling multiple selections

This reduces friction during onboarding by matching user expectations,
especially for users who navigate to a tool and press Enter without
first toggling it with Space.
2025-10-12 14:53:44 +11:00
github-actions[bot]andTabish Bidiwale c482f1b47a chore(release): version packages (#150)
* chore: trigger CI

* chore: trigger CI

* Version Packages

---------

Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-11 11:47:37 +11:00
Tabish Bidiwale 2ae0484ac7 chore: add changeset for cross-platform fixes release (#147)
Add changeset for patch release including fixes for joinPath behavior and slash command path resolution across platforms.
2025-10-11 11:27:26 +11:00
Tabish Bidiwale 8c65b47abe Fix cross-platform joinPath behavior (#145) 2025-10-11 01:46:32 +11:00
Tabish Bidiwale 9c9e57daa1 Ensure slash command paths resolve on Windows platforms (#144)
* Ensure slash command paths work on Windows

* Add Linux home path coverage for joinPath
2025-10-11 00:27:16 +11:00
github-actions[bot]andTabish Bidiwale c7ca76cb4f chore(release): version packages (#138)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-09 17:48:59 +11:00
06bd3999bf chore(release): version packages (#137)
* Version Packages

* empty

* RUN CI

* trigger CI

* empty

* trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
2025-10-09 17:38:55 +11:00
Tabish Bidiwale 821097079a chore: add changeset for Windows OpenSpec fix (#136)
Add changeset for patch release to fix OpenSpec not working on Windows
when Codex integration is selected. Includes cross-platform path handling
and normalization fixes.
2025-10-09 17:33:16 +11:00
Tabish Bidiwale 42e3118b0c fix: normalize paths for cross-platform consistency in logging (#135)
- Use POSIX-style forward slashes in FILE_PATHS for consistent logging
- Normalize backslashes to forward slashes in update command output
- Improves Windows compatibility and log readability
2025-10-09 17:20:33 +11:00
Tabish Bidiwale a785c2a99a fix: use path.join for cross-platform compatibility in Codex FILE_PATHS (#134)
Fixes #132

The FILE_PATHS constant was using hardcoded forward slashes, which caused
path.basename() to fail on Windows. On Windows, path.basename() expects
backslashes as path separators, so it would return the entire string
instead of just the filename.

This broke Codex detection on Windows during init/update because the
resolveAbsolutePath() method would construct incorrect paths, causing
file existence checks to fail.

Changed FILE_PATHS to use path.join() which automatically uses the
correct platform-specific path separators (backslashes on Windows,
forward slashes on Unix).
2025-10-09 16:51:23 +11:00
github-actions[bot]andTabish Bidiwale af513191eb chore(release): version packages (#131)
* Version Packages

* empty

* RUN CI

* trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-09 02:52:47 +11:00
Tabish Bidiwale efbbf3b9f1 chore: add changeset for new release (#130)
Add changeset to release support for Codex and GitHub Copilot slash commands with YAML frontmatter and $ARGUMENTS.
2025-10-09 02:43:58 +11:00
Tabish Bidiwale 6105211163 feat: update Codex slash commands to use YAML frontmatter and $ARGUMENTS (#129)
* feat: update Codex slash commands to use YAML frontmatter and $ARGUMENTS

Updates Codex custom slash command format to match the official Codex implementation:
- Replace simple header format with YAML frontmatter (description + argument-hint fields)
- Switch from positional $1 placeholder to $ARGUMENTS for consistency with GitHub Copilot
- Add updateFullFile method to ensure both frontmatter and body are updated during openspec update
- Align with Codex custom_prompts.rs specification

* docs: update Codex proposal to reflect YAML frontmatter and $ARGUMENTS

Updates the proposal to accurately describe the implemented format:
- YAML frontmatter with description and argument-hint fields
- $ARGUMENTS instead of positional placeholders like $1
- Alignment with GitHub Copilot pattern and official Codex specification
- Clarifies that openspec update refreshes both frontmatter and body

* test: update Codex tests for YAML frontmatter and $ARGUMENTS

Updates test assertions to match the new Codex format:
- YAML frontmatter with description and argument-hint fields
- $ARGUMENTS instead of positional $1 placeholders
- Verifies frontmatter is updated during openspec update
2025-10-09 02:39:09 +11:00
Tabish Bidiwale b3d31d224d feat: add GitHub Copilot slash command support (#128)
* feat: add GitHub Copilot slash command support

Add GitHub Copilot as a natively supported AI tool with custom slash
commands for OpenSpec workflow operations. This enables teams using
GitHub Copilot to access /openspec-proposal, /openspec-apply, and
/openspec-archive directly from Copilot's chat interface.

Implementation:
- Create GitHubCopilotSlashCommandConfigurator that writes prompts to
  .github/prompts/ directory with YAML frontmatter and $ARGUMENTS
  placeholder following GitHub Copilot's prompt format
- Register GitHub Copilot in AI_TOOLS configuration and slash
  command registry for automatic init/update integration
- Add comprehensive test coverage for prompt generation, updates,
  and extend mode detection
- Update documentation (README and CHANGELOG) to include GitHub
  Copilot in the slash-command support table

The implementation follows the existing SlashCommandConfigurator
pattern and integrates seamlessly with openspec init and openspec
update commands.

* docs: remove GitHub Copilot from tools list
2025-10-09 02:23:42 +11:00
Tabish Bidiwale 9ae6141eb1 feat: Add codex custom slash command support (#120)
* Document current cli specs and archive safety

* feat: add Codex slash command support

Add support for generating and updating Codex prompts in `.codex/prompts/` directory:
- Implement CodexSlashCommandConfigurator for managing openspec-*.md prompts
- Update AI_TOOLS configuration to include Codex as an available option
- Add Codex registration in SlashCommandRegistry
- Update documentation to reflect Codex support
- Add comprehensive test coverage for Codex init and update workflows

* feat: complete Codex slash command support implementation

Add comprehensive Codex slash command support with Claude.md integration,
config-driven command management, and full test coverage. Update documentation
and changelog to reflect changes.

* chore: mark all Codex slash command tasks as completed

All tasks for the Codex slash command support feature have been implemented and tested.

* docs: remove Codex-specific note from README

Remove the Codex-specific installation note as it's no longer needed in the main setup instructions. This information is better suited for tool-specific documentation.
2025-10-09 01:55:47 +11:00
Tabish Bidiwale d84069a3ae docs: add spec-kit comparison and comparison overview section (#127)
Added a "How OpenSpec compares (at a glance)" section to highlight key differentiators early in the README. Expanded the comparison section with a dedicated spec-kit comparison, emphasizing OpenSpec's two-folder model for managing existing features and cross-spec updates.
2025-10-09 00:13:42 +11:00
Tabish Bidiwale 8c974f8a80 update discord invite link (#126) 2025-10-08 23:29:14 +11:00
github-actions[bot]andTabish Bidiwale 25289b510d chore(release): version packages (#124)
* Version Packages

* empty

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-08 14:59:33 +11:00
Tabish Bidiwale d070d08aa8 fix: correct CLI version mismatch and add release guard (0.8.1) (#123)
* fix: correct CLI version mismatch and add release guard\n\n- Add patch changeset for 0.8.1\n- Add pack-version check to validate tarball version\n- Update release script to include versioning and guard

* chore(release): simplify release script and harden pack-version-check\n\n- Run pack-version check before publish only\n- Remove redundant changeset version + explicit build in release script\n- Always cleanup temp dir and tgz\n- Quieter, faster npm install during guard

* chore(release): clarify CI vs local release scripts; refine pack guard\n\n- Add scripts: release:ci (no version), release:local (runs changeset version)\n- Workflow uses release:ci to ensure version PR bump precedes publish\n- Pack guard: document npm vs pnpm choice; improve JSON fallback handling
2025-10-08 14:46:15 +11:00
github-actions[bot]andTabish Bidiwale 6539ceb54a chore(release): version packages (#117)
* Version Packages

* chore: trigger CI

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-04 02:22:12 +10:00
Tabish Bidiwale c29b06da42 chore: changeset for Windsurf support (#116) 2025-10-04 02:11:14 +10:00
Tabish Bidiwale 4a2b23942c chore(release): phase 2 – enable publish via changesets action, add release script, remove legacy release-publish workflow (#115) 2025-10-04 01:56:11 +10:00
Tabish Bidiwale 807b9d32a6 chore(release): phase 1 – wire changesets (dry-run), add npm auth config (#114)
* Clarify release automation proposal

* chore(release): phase 1 – wire up changesets action (dry-run publish) and GitHub release drafting

* ci(release): phase 1 – add NODE_AUTH_TOKEN alias and registry/auth config for npm (dry-run)
2025-10-04 01:28:47 +10:00
b3d05d2f78 Add Windsurf IDE support with slash commands (#113)
* docs(windsurf): propose workflow support

* restore missing opencode spec

* Add Windsurf IDE support with slash commands

* feat(windsurf): add Windsurf workflows support under .windsurf/workflows and simplify templates\n\n- Write workflows to .windsurf/workflows instead of .windsurf/commands\n- Remove YAML frontmatter; add concise intro before managed markers\n- Add init/update tests for Windsurf and marker preservation\n- List Windsurf in README native tools table\n- Normalize registry indentation

* chore(windsurf): remove optional intro content to simplify workflows\n\n- Drop intro hook and headings for Windsurf workflows\n- Keep OPENSPEC markers-only body for safe updates\n- Adjust tests to assert marker-managed content

* feat(windsurf): add required YAML frontmatter to workflows\n\n- Include description and auto_execution_mode: 3 for proposal/apply/archive\n- Keep content minimal; body remains marker-managed

---------

Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com>
Co-authored-by: Tabish Bidiwale <tabishbidiwale@gmail.com>
2025-10-04 00:54:07 +10:00
Tabish Bidiwale 9848242587 chore: add change proposals for agent scaffolding (#108) 2025-10-02 00:26:25 +10:00
Tabish Bidiwale 5e0d21d1ed chore: release 0.7.0 (#107) 2025-10-01 23:01:23 +10:00
Tabish Bidiwale 31d85d0e8b feat: Always install agentsmd (#106)
* Update CLI init to install root agents

* cleanup init command
2025-10-01 22:51:15 +10:00
Tabish Bidiwale bc3666d702 feat: Add Kilo Code workflow support (#105)
Implements Kilo Code integration with the following features:
- Added Kilo Code as a selectable AI tool in `openspec init`
- Created KiloCodeSlashCommandConfigurator to generate workflow files
- Generates `.kilocode/workflows/openspec-{proposal,apply,archive}.md`
- Added update support to refresh existing Kilo Code workflows
- Updated README with Kilo Code integration details
- Added comprehensive test coverage for init and update commands
- Updated CHANGELOG with new feature

All tasks from the change proposal are complete.
2025-10-01 19:01:10 +10:00
Tabish Bidiwale 970b9f6e2d Add Kilo Code workflow proposal (#103) 2025-10-01 13:21:22 +10:00
Tabish Bidiwale 5cb84a775e Add change proposal for Windsurf workflow support (#94)
* docs(windsurf): propose workflow support

* restore missing opencode spec
2025-10-01 11:51:07 +10:00
Tabish Bidiwale adc63069a9 chore(release): version packages (#100) 2025-09-30 17:35:29 +10:00
Tabish Bidiwale f8eca37796 feat(init): slim root agent instructions (#98)
* feat(init): slim root agent instructions

* Fix marker updates to ignore inline mentions

* styling updates

* update instructions

* fix tests
2025-09-30 17:03:56 +10:00
Tabish Bidiwale a908dc5a05 chore(release): version packages (#93)
Bump version to 0.5.0 with new features and improvements:
- E2E testing with cross-platform CI matrix
- Improved apply instructions
- Documentation improvements and cleanup
2025-09-29 23:47:22 +10:00
Tabish Bidiwale b46f99b9bc Make apply instructions more specific (#92) 2025-09-29 23:41:24 +10:00
Tabish Bidiwale 6f7cc2abd2 archive completed changes (#91) 2025-09-29 23:03:04 +10:00
Tabish Bidiwale 4867bfade5 feat: implement Phase 1 E2E testing with cross-platform CI matrix (#80)
* feat: implement Phase 1 E2E testing with cross-platform CI matrix

- Add shared runCLI helper in test/helpers/run-cli.ts for spawn testing
- Create test/cli-e2e/basic.test.ts covering help, version, validate flows
- Migrate existing CLI exec tests to use runCLI helper
- Extend CI matrix to bash (Linux/macOS) and pwsh (Windows)
- Update Phase 1 tasks and proposal with implementation status

* fix: correct YAML syntax in CI workflow diagnostics command

* fix: use multiline YAML for diagnostics command

* fix ci

* fix: ci

* fix: update core validation and json converter

* chore(ci): split pr and main workflows

* refactor: simplify CI workflow with unified matrix strategy

- Consolidate test_pr and test_matrix into single test job
- Add proper shell configuration with defaults
- Add timeout protection (15 minutes)
- Simplify required-checks to single job
- Maintain cross-platform testing (bash on Linux/macOS, pwsh on Windows)

* fix: restore lean PR workflow with async main branch matrix

- PRs run only essential tests on ubuntu-latest (fast feedback)
- Main branch runs full cross-platform matrix asynchronously
- Separate required-checks for each workflow type
- Different timeouts: 10min for PR, 15min for matrix
2025-09-29 22:20:30 +10:00
Tabish Bidiwale 7359b4846a docs(archive): document non-interactive flag (#90) 2025-09-29 15:59:51 +10:00
Tabish Bidiwale 88526e6b93 docs(readme): replace discord badge (#87) 2025-09-26 18:23:37 +10:00
Tabish Bidiwale 367aa12892 chore(release): version packages (#86) 2025-09-26 16:03:15 +10:00
James G. Best dcfb6afe0c feat: add Opencode slash commands (#83)
* First pass at adding Opencode slash commands

* Fix the agent

* Pass in Arguments to opencode slash commands

* Remove unneeded agents file
2025-09-26 01:37:30 +10:00
Tabish Bidiwale 86925b2b2d docs: add --yes flag to archive command template (#84) 2025-09-26 00:32:56 +10:00
Tabish Bidiwale 604ecb8bd1 fix: normalize line endings in markdown parser to handle CRLF files (#79)
Fixes validation errors on Windows by normalizing CRLF/CR line endings
to LF before parsing sections. Adds comprehensive test coverage for
CRLF handling in both unit and integration tests.
2025-09-25 15:59:09 +10:00
Tabish Bidiwale 5a4837c37d feat: add OpenSpec change proposals for CLI improvements (#78)
* feat: add CLI e2e testing improvement plan

## Summary
- Add phased approach to stabilize CLI spawn testing
- Expand cross-shell/OS matrix coverage when stable
- Optional packaging validation for CI environments

* feat: add markdown parser CRLF fix proposal and update e2e plan

- Add comprehensive proposal for fixing CRLF parsing issues on Windows
- Update CLI path references from dist/cli.js to dist/cli/index.js
- Streamline e2e testing tasks based on refined approach

* fix: correct spec delta to add parsing requirement instead of modifying remediation

- Change from MODIFIED to ADDED Requirements for cross-platform line ending parsing
- Create focused requirement for parser behavior rather than validation messages
- Maintain logical coherence between requirement and scenario
2025-09-25 14:53:21 +10:00
Tabish Bidiwale 9d9539aaa2 docs: add Discord badge (#73)
* docs: add discord badge

* chore: ignore ds store
2025-09-24 03:10:13 +10:00
Tabish Bidiwale c3fecf0619 chore: add codeowners (#72) 2025-09-19 11:56:37 +10:00
Tabish Bidiwale 6469593495 chore(release): publish to latest 2025-09-18 00:05:51 +10:00
Tabish Bidiwale 157936cf68 chore(release): prepare v0.3.0 2025-09-17 23:48:35 +10:00
Tabish Bidiwale fef33df753 Remove unused folders 2025-09-17 23:41:03 +10:00
Tabish Bidiwale 78b61e8466 Merge pull request #70 from Fission-AI/update-readme
docs: improve README Getting Started section
2025-09-17 23:28:44 +10:00
Tabish Bidiwale 5fa0fa68a7 fix tests 2025-09-17 23:27:04 +10:00
Tabish Bidiwale fe9eb44ec2 Remove md file 2025-09-17 23:14:57 +10:00
Tabish Bidiwale ee78f21b08 docs: improve README Getting Started section formatting and clarity 2025-09-17 23:12:40 +10:00
Tabish Bidiwale e3ae2ceaf0 feat(cli): polish init experience 2025-09-17 12:45:14 +10:00
Tabish Bidiwale 20b2fee749 feat(init): support multi-select extend flow 2025-09-17 11:36:56 +10:00
Tabish Bidiwale e7fff31df2 feat(cli): prepare init onboarding improvements 2025-09-17 10:45:22 +10:00
Tabish Bidiwale fdf9a30f0b Merge pull request #69 from Fission-AI/feat/add-agents-md-config
feat(cli): add agents md standard support
2025-09-17 10:25:49 +10:00
Tabish Bidiwale 161aa41cb3 style(cli): clarify agents option label 2025-09-17 10:18:51 +10:00
Tabish Bidiwale 9e092a185b style(cli): clarify init tool labels 2025-09-17 10:15:41 +10:00
Tabish Bidiwale 38454bb2a6 feat(cli): reorder init tool options 2025-09-17 10:12:40 +10:00
Tabish Bidiwale b04f1cc923 docs: note agents standard init option 2025-09-17 10:08:08 +10:00
Tabish Bidiwale ae86e9be9e chore(openspec): update agents tasks 2025-09-17 10:04:57 +10:00
Tabish Bidiwale f955e87fd9 feat(cli): add agents md configurator 2025-09-17 10:01:23 +10:00
Tabish Bidiwale 55efd19953 docs: add agents md config proposal 2025-09-17 09:50:56 +10:00
Tabish Bidiwale dab5d93b85 Merge pull request #68 from Fission-AI/codex/add-support-for-multiple-coding-agents
feat(cli-init): propose additional agent init flow
2025-09-17 08:34:45 +10:00
Tabish Bidiwale 7b0f494754 feat(cli-init): propose additional agent init flow 2025-09-17 08:33:10 +10:00
Tabish Bidiwale dd7ba71fe5 Merge pull request #67 from Fission-AI/codex/update-readme-for-custom-slash-commands
docs: correct claude code commands
2025-09-17 08:31:59 +10:00
Tabish Bidiwale 66ad5658f9 docs: correct claude code commands 2025-09-17 08:29:23 +10:00
Tabish Bidiwale 21a0e74b74 Merge pull request #66 from Fission-AI/changeset-release/main
chore(release): version packages
2025-09-16 16:50:42 +10:00
github-actions[bot] 485ef07ec7 Version Packages 2025-09-16 06:49:43 +00:00
Tabish Bidiwale ce5ceadbe7 chore(release): add changeset for dashboard release 2025-09-16 16:49:21 +10:00
Tabish Bidiwale 9a173b917c docs: refresh readme hero 2025-09-16 16:38:22 +10:00
Tabish Bidiwale 79baabbed1 Merge pull request #65 from Fission-AI/update-slash-commands
Update slash command guardrails
2025-09-16 15:48:02 +10:00
Tabish Bidiwale 818a5922ce docs: reference agents conventions in slash guardrails 2025-09-16 15:46:53 +10:00
Tabish Bidiwale d8d2930182 docs(templates): update slash command instructions 2025-09-16 15:05:59 +10:00
Tabish Bidiwale 6af6e0ccb6 Merge pull request #62 from Fission-AI/codex/implement-update-agent-file-name-change
feat: rename agent instructions file to AGENTS.md
2025-09-16 13:32:30 +10:00
Tabish Bidiwale 50e6660018 test: update update command logs 2025-09-16 13:28:36 +10:00
Tabish Bidiwale 4bbb52dda4 feat: rename agent instructions file 2025-09-16 13:17:49 +10:00
Tabish Bidiwale 4a0ae49b6e Merge pull request #64 from Fission-AI/codex/add-sorting-for-active-changes-by-completion
feat: add active change sorting proposal
2025-09-16 12:00:33 +10:00
Tabish Bidiwale 5b2049aedf feat(view): sort active changes by progress 2025-09-16 11:59:40 +10:00
Tabish Bidiwale 332020ac6b fix: clarify active change sorting tasks 2025-09-16 11:49:57 +10:00
Tabish Bidiwale 646c516b0d Merge pull request #63 from Fission-AI/feat/add-slash-command-support
feat(cli): add slash command support
2025-09-16 11:49:22 +10:00
Tabish Bidiwale 8c1b580f03 feat(cli): add slash command support 2025-09-16 11:36:00 +10:00
Tabish Bidiwale 17e6f7166b docs(readme): merge 'What You Get' into 'Why OpenSpec?' 2025-09-16 10:33:29 +10:00
Tabish Bidiwale 931d10477e Merge pull request #59 from Fission-AI/codex/rename-agent-instruction-file-to-agents.md
chore(changes): propose agent file rename
2025-09-16 10:26:37 +10:00
Tabish Bidiwale e4548bcc58 Merge pull request #60 from Fission-AI/codex/add-custom-slash-command-support-for-openspec
docs: add slash command support proposal
2025-09-16 08:41:10 +10:00
Tabish Bidiwale 68fc049955 docs(changes): use proposal/apply/archive names and per-tool slash naming; add format examples and test guidance 2025-09-16 08:39:39 +10:00
Tabish Bidiwale 4874a16495 feat(validate): propose scope-aware change validation (validate only existing artifacts) 2025-09-16 08:15:39 +10:00
Tabish Bidiwale 3caabf86cf docs(readme): regenerate from template via openspec update 2025-09-16 07:42:52 +10:00
Tabish Bidiwale d4593e4a54 docs(readme): clarify ADDED vs MODIFIED and update README template 2025-09-16 07:40:35 +10:00
Tabish Bidiwale 0144ec2b1b fix(changes): use ADDED for slash command requirements in cli-init and cli-update 2025-09-16 07:40:21 +10:00
Tabish Bidiwale 98d90cc00d Merge pull request #61 from Fission-AI/view-command-proposal
feat: add openspec view dashboard command
2025-09-12 21:33:45 +10:00
Tabish Bidiwale ccaa5ad0b0 feat: add openspec view dashboard command 2025-09-12 21:11:42 +10:00
Tabish Bidiwale 8eb7ebd7cd docs: detail slash command instructions 2025-09-12 18:25:40 +10:00
Tabish Bidiwale be395d9d74 docs(readme): shrink header logo to 64px 2025-09-12 16:34:17 +10:00
Tabish Bidiwale a09b87e391 docs(readme): add adaptive logo and center badges 2025-09-12 16:32:33 +10:00
Tabish Bidiwale 9d7b44b722 chore(changes): propose agent file rename 2025-09-10 10:56:08 +10:00
Tabish Bidiwale 44c06cc40e Merge pull request #58 from Fission-AI/docs/align-agent-instructions
docs(openspec): align agent instructions and templates
2025-09-10 10:38:29 +10:00
Tabish Bidiwale b33f435812 docs(template): sync readme-template to exactly match openspec/README.md 2025-09-09 22:15:39 +10:00
Tabish Bidiwale b62b57caf3 fix(templates): escape backticks and move examples inside template literals 2025-09-09 22:02:34 +10:00
Tabish Bidiwale 758d91613d docs(openspec): prefer CLI examples for listing/showing; keep rg for full-text search 2025-09-09 21:50:05 +10:00
Tabish Bidiwale 47180e5120 docs(openspec): add TL;DR, search guidance, design skeleton, renamed example, approval gate, and examples 2025-09-09 21:36:17 +10:00
Tabish Bidiwale 8dde1d55fc docs(openspec): align agent instructions and templates 2025-09-09 21:26:56 +10:00
Tabish Bidiwale 3cef6f0925 Merge pull request #57 from Fission-AI/remove-diff-command
Remove diff command in favor of show command
2025-09-09 14:15:34 +10:00
Tabish Bidiwale 82ba1f504e merge: resolve conflicts with main branch 2025-09-09 14:12:05 +10:00
Tabish Bidiwale d54fcc97f2 docs: mark completed tasks for diff command removal 2025-09-09 14:07:52 +10:00
Tabish Bidiwale ebff738860 feat: remove diff command in favor of show command
The diff command added unnecessary complexity and duplicated functionality
already available through the show command. Users can now use:
- `openspec show <change>` for structured change viewing
- `openspec show <change> --json --deltas-only` for delta-only views
- Standard git diff or other tools for file comparisons

This change:
- Removes ~227 lines of code and the jest-diff dependency
- Simplifies the CLI interface
- Reduces maintenance burden
- Aligns with verb-first command structure
2025-09-09 14:05:41 +10:00
Tabish Bidiwale 1bdaeef4da Update README.md 2025-09-07 09:16:53 +10:00
Tabish Bidiwale 2921676e93 docs(readme): make alignment the central value proposition 2025-09-07 05:16:40 +10:00
Tabish Bidiwale 792129bfe3 docs(readme): highlight supported AI tools and emphasize universal interoperability 2025-09-07 05:10:46 +10:00
Tabish Bidiwale 715ff513e3 docs(readme): restructure for clarity - focus on AI alignment benefits and quick wins 2025-09-07 05:07:21 +10:00
Tabish Bidiwale f6913b7661 docs(readme): streamline content, focus on change management vs Kiro 2025-09-07 04:53:19 +10:00
Tabish Bidiwale 730bbc00af docs(readme): remove JSON for automation section 2025-09-07 04:46:18 +10:00
Tabish Bidiwale adfcc65b9f docs(readme): simplify getting started with clearer AI workflow steps 2025-09-07 04:41:56 +10:00
Tabish Bidiwale 590541277d docs(readme): fix getting started to show AI-native workflow, not manual file creation 2025-09-07 04:36:03 +10:00
Tabish Bidiwale 14e2cc628a docs(readme): enhance for public release with why, workflow diagram, AI integration, comparisons 2025-09-07 04:26:44 +10:00
Tabish Bidiwale 299171c5cb docs(readme): add CI, npm, Node, license, conventional commits badges 2025-09-07 03:57:33 +10:00
Tabish Bidiwale bb6aae0205 docs(license): add MIT license file 2025-09-07 03:32:27 +10:00
Tabish Bidiwale 23c0ab6358 docs(readme): improve onboarding, verb-first commands, examples, JSON usage, troubleshooting 2025-09-07 03:20:34 +10:00
Tabish Bidiwale 02fe5b3547 Merge pull request #56 from Fission-AI/fix-tests
fix(test): resolve CI test failures with proper build setup
2025-09-07 02:34:13 +10:00
Tabish Bidiwale 57216a7824 refactor(test): use vitest globalSetup for build instead of per-test builds 2025-09-07 02:16:17 +10:00
Tabish Bidiwale 6e210cf084 fix(test): ensure dist exists before spawning CLI subprocesses 2025-09-07 02:13:21 +10:00
Tabish Bidiwale 5c6ae8e407 Merge pull request #55 from Fission-AI/fix-tests
fix(ci): ensure build runs before tests in workflows
2025-09-07 02:04:04 +10:00
Tabish Bidiwale 5376030421 fix(ci): simplify to single Node version for faster CI 2025-09-07 01:56:00 +10:00
Tabish Bidiwale 7d735eb2d8 fix(ci): ensure build runs before tests in workflows 2025-09-07 01:45:11 +10:00
Tabish Bidiwale 4d55e9ac6d chore(ci): use NODE_AUTH_TOKEN auth, add debug, build before tests 2025-09-07 01:23:32 +10:00
Tabish Bidiwale 9d674b22a3 Fix provenance 2025-09-07 01:13:23 +10:00
Tabish Bidiwale 96458ced1f Update actions workflow 2025-09-07 01:01:55 +10:00
Tabish Bidiwale 3d8f2a5974 update workflow 2025-09-07 00:31:37 +10:00
Tabish Bidiwale 006676c973 chore(test): clarify vitest worker note and newline 2025-09-06 23:27:49 +10:00
Tabish Bidiwale 63f45c0fcf test(commands): isolate change command tests via temp fixtures 2025-09-06 23:27:42 +10:00
Tabish Bidiwale 522126a6ee fix(utils): harden item discovery for determinism 2025-09-06 23:27:33 +10:00
Tabish Bidiwale 23b8030494 fix(change): only list active changes with proposal.md 2025-09-06 23:26:51 +10:00
Tabish Bidiwale f70df96656 docs(changes): add tasks.md for improve-deterministic-tests 2025-09-06 23:20:03 +10:00
Tabish Bidiwale df12368f11 chore(changes): remove obsolete cli-list spec 2025-09-06 21:01:19 +10:00
Tabish Bidiwale acd1ca28f3 docs(changes): add deterministic tests proposal 2025-09-06 21:01:19 +10:00
Tabish Bidiwale aedf4a34af docs(release): add 0.1.0 notes 2025-09-06 21:01:19 +10:00
Tabish Bidiwale f0c52ac7e8 Merge pull request #54 from Fission-AI/changeset-release/main
chore(release): version packages
2025-09-06 14:56:28 +10:00
github-actions[bot] f933e9b144 Version Packages 2025-09-06 04:43:55 +00:00
Tabish Bidiwale 24b4866426 chore(changeset): seed release notes 2025-09-06 14:35:50 +10:00
Tabish Bidiwale b7899602b4 chore(ci): add release workflows 2025-09-06 14:32:32 +10:00
Tabish Bidiwale b66d914198 chore(changesets): add config and script 2025-09-06 02:52:02 +10:00
Tabish Bidiwale 9926103505 chore(pkg): scope to @fission-ai and set public 2025-09-06 02:34:11 +10:00
Tabish Bidiwale 873e45a996 Merge pull request #53 from Fission-AI/prepare-publish
build: prepare for package publish
2025-09-06 02:28:48 +10:00
Tabish Bidiwale 573afa0c65 prepare for package publish 2025-09-06 02:22:38 +10:00
Tabish Bidiwale 665d740adb Remove retrospective doc 2025-09-01 11:34:23 +10:00
Tabish Bidiwale c35dd38567 Test cursor rules 2025-08-27 21:20:37 +10:00
Tabish Bidiwale aa9e49612b Merge pull request #51 from Fission-AI/updating-agent-instructions
feat: streamline OpenSpec agent instructions by 48%
2025-08-27 20:59:31 +10:00
Tabish Bidiwale 36eb0bbbf5 feat: streamline OpenSpec agent instructions by 48%
- Restructured README.md with three-stage workflow front-loaded
- Reduced from 575 to 298 lines while adding comprehensive content
- Added clear decision trees and removed ambiguous conditions
- Documented all CLI commands with examples and debugging tips
- Added critical scenario formatting guidance (most common error)
- Created troubleshooting section with error solutions
- Updated CLAUDE.md template with streamlined, focused content
- Added "Before Any Task" checklist for context gathering
- Added spec discovery workflow to prevent duplicates
- Included tool selection matrix and best practices
2025-08-27 18:22:29 +10:00
Tabish Bidiwale d549cec121 Merge pull request #50 from Fission-AI/update-openspec-agent-instructions
Update OpenSpec agent instructions for clarity and completeness
2025-08-27 18:01:29 +10:00
Tabish Bidiwale 1a3bfae784 feat: add comprehensive retrospective-based improvements
Based on OPENSPEC_COMPREHENSIVE_RETROSPECTIVE.md analysis:

Added critical missing documentation:
- Scenario formatting requirements (#### Scenario: headers) - #1 pain point
- Complete spec file structure examples with ADDED/MODIFIED sections
- Delta file location and extraction explanation
- Debugging commands (show --json --deltas-only)
- Troubleshooting section with common errors and solutions

Expanded implementation:
- Added 2 new task sections (Spec File Documentation, Troubleshooting)
- Increased from 41 to 52 total implementation tasks
- Added critical items to CLAUDE.md template tasks

This directly addresses the retrospective's top issues:
1. Scenario format documentation (marked "COMPLETELY MISSING")
2. Complete spec file examples
3. Delta detection debugging
4. Silent parsing failure explanations
2025-08-25 15:31:35 +10:00
Tabish Bidiwale fae08072a9 feat: add explicit implementation workflow for Stage 2
- Add detailed implementation steps: read docs → implement → mark complete
- Emphasize reading proposal.md, design.md, and tasks.md first
- Require immediate task completion marking (no batching)
- Add rationale: prevents jumping straight to code without context
- Update tasks to include implementation workflow documentation

This ensures agents understand and follow the complete change properly
2025-08-25 15:25:49 +10:00
Tabish Bidiwale 07df6c97c9 feat: add comprehensive CLI documentation and spec discovery workflow
- Document all 9 primary OpenSpec commands with examples
- Add openspec list and list --specs prominently
- Add "Before Creating Specs" rule to check existing specs first
- Document all CLI flags (--json, --type, --skip-specs, etc.)
- Update tasks to include 9 CLI documentation items
- Add spec discovery workflow to prevent duplicate capabilities

This ensures AI agents have complete CLI knowledge and avoid spec fragmentation
2025-08-25 15:21:09 +10:00
Tabish Bidiwale 7b13a2de03 feat: enhance proposal with agent instruction best practices
- Add decision clarity improvements (decision trees, remove ambiguity)
- Include agent-specific sections (tool selection, error recovery, context management)
- Restructure with clear information hierarchy
- Add comprehensive implementation tasks (6 sections, 26 tasks)
- Update design with industry best practices rationale

Based on analysis of Claude Code, Cursor, and other coding agent patterns
2025-08-24 13:36:12 +10:00
Tabish Bidiwale 41fc14d360 fix: remove spec deltas - this is a tooling change not a capability
- Documentation updates are tooling/infrastructure changes
- No specs needed for OpenSpec's own instructions
- Will use --skip-specs flag when archiving
2025-08-24 13:28:22 +10:00
Tabish Bidiwale 7c0face31b feat: add change proposal to update OpenSpec agent instructions
- Create proposal for streamlining agent instructions
- Document three-stage workflow clearly
- Update CLI command documentation
- Add best practices for AI agents
- Include spec deltas for documentation requirements
2025-08-24 13:25:23 +10:00
Tabish Bidiwale 332816cc35 Merge pull request #48 from Fission-AI/archive-changes
archive: apply delta-based spec updates and archive changes\n\n- adop…
2025-08-20 03:12:58 +10:00
Tabish Bidiwale 7ced2a8791 archive: apply delta-based spec updates and archive changes\n\n- adopt-delta-based-changes: fix MODIFIED/ADDED headers; update specs; archive\n- add-zod-validation: mark cli-diff validation as ADDED; archive\n- adopt-verb-noun-cli-structure: move Flags to MODIFIED; archive\n\nAlso adjust openspec-conventions deltas to reflect existing headers. 2025-08-20 03:11:00 +10:00
Tabish Bidiwale a79b8b5c03 Merge pull request #47 from Fission-AI/fix-invalid-spec-files
fix: fix invalid files
2025-08-20 01:42:09 +10:00
Tabish Bidiwale 52d620e40e fix invalid files 2025-08-20 01:41:36 +10:00
Tabish Bidiwale 22082338fd Merge pull request #46 from Fission-AI/feat/adopt-verb-noun-cli-structure
Adopt verb-noun CLI structure
2025-08-20 01:06:28 +10:00
Tabish Bidiwale 6458b6ed39 feat: adopt verb-noun CLI structure 2025-08-20 01:01:17 +10:00
Tabish Bidiwale 01a2f5d600 Merge pull request #45 from Fission-AI/feat/improve-validation-error-messages
feat(validate): improve error messages with actionable guidance
2025-08-20 01:00:14 +10:00
Tabish Bidiwale 95d855d641 feat(validate): improve error messages with actionable guidance 2025-08-20 00:54:34 +10:00
Tabish Bidiwale 562530dfa8 Merge pull request #44 from Fission-AI/feat/add-interactive-show-command
feat: add unified show command with interactive selection
2025-08-20 00:17:26 +10:00
Tabish Bidiwale 1e17cfdd0b Address review 2025-08-20 00:14:34 +10:00
Tabish Bidiwale 5d185ba3a8 feat: add unified show command with interactive selection 2025-08-20 00:06:19 +10:00
Tabish Bidiwale 08b41c7bea Merge pull request #43 from Fission-AI/feat/validate-command-interactive-selection
feat: add unified validate command with interactive selection and bulk operations
2025-08-19 23:23:11 +10:00
Tabish Bidiwale 8ac50289f0 Add tests 2025-08-19 23:22:18 +10:00
Tabish Bidiwale 1f295cec52 feat: add unified validate command with interactive selection and bulk operations 2025-08-19 22:58:17 +10:00
Tabish Bidiwale ad8e213cf9 Merge pull request #42 from Fission-AI/feat/bulk-validation-and-interactive-selection
feat: add bulk validation and interactive selection for OpenSpec commands
2025-08-19 22:35:25 +10:00
Tabish Bidiwale a6c1a90165 docs: consolidate retrospective documents into comprehensive analysis 2025-08-19 22:30:13 +10:00
Tabish Bidiwale 21b5a3e680 refactor: split validation and show commands into separate change proposals 2025-08-19 22:06:09 +10:00
Tabish Bidiwale 1bda5be96c refactor: use single validate command with flags for better UX 2025-08-19 21:40:27 +10:00
Tabish Bidiwale 0faf44807e refactor: simplify change to modify existing command specs instead of creating new ones 2025-08-19 21:29:38 +10:00
Tabish Bidiwale f9c1d07edb feat: add change proposal for bulk validation and interactive selection 2025-08-19 21:10:56 +10:00
Tabish Bidiwale 2bd1a4417c Merge pull request #41 from Fission-AI/chore/fix-change-validations
feat: Chore/fix change validations
2025-08-19 20:51:22 +10:00
Tabish Bidiwale 1db19ac3d8 remove delta from proposal 2025-08-19 20:49:02 +10:00
Tabish Bidiwale 25018786e4 chore(conventions): remove delta sections from proposals; keep deltas only in change specs; all changes pass --strict validation 2025-08-19 20:46:13 +10:00
Tabish Bidiwale 5fd9173ad9 remove md files 2025-08-19 20:40:14 +10:00
Tabish Bidiwale 0a611747bc fix(change-validate): ensure delta specs emit requirements arrays; add missing Why/What sections and delta content for changes; refine removed requirement text and scenarios; all changes pass --strict validation 2025-08-19 20:31:41 +10:00
Tabish Bidiwale 49e422724f update test commands 2025-08-19 19:51:43 +10:00
Tabish Bidiwale c22d6bce1c show completion for tasks when archiving 2025-08-19 19:48:54 +10:00
Tabish Bidiwale 1c0dc09dc9 Merge pull request #40 from Fission-AI/update-archive-command
feat: Update archive command
2025-08-19 18:57:51 +10:00
Tabish Bidiwale f0b1e00c65 Address review 2025-08-19 18:44:37 +10:00
Tabish Bidiwale 5fe72ddc5d remove archive file 2025-08-19 18:26:34 +10:00
Tabish Bidiwale c18f3b2b2e feat(archive): apply delta-based updates with header matching, skeleton creation, atomic writes, and per-spec counts; add requirement-block parser; add tests covering normalization, order, validation, rename+modify, and multi-spec; update proposal and tasks with product decisions 2025-08-19 18:24:27 +10:00
Tabish Bidiwale 33344727a8 Merge pull request #39 from Fission-AI/make-commands-consistent
Make change and spec commands consistent (raw-first)
2025-08-18 23:26:47 +10:00
Tabish Bidiwale 828e5ba316 chore: remove unused imports; improve no-change messaging; update README for raw-first, JSON-only filters, --long, and --no-color 2025-08-18 23:20:47 +10:00
Tabish Bidiwale 31c57f5c0f Follow-up: add debug logging and tests for raw-first behavior\n\n- change list: add conditional debug logging when reading tasks.md fails\n- spec tests: align with raw-first (JSON-only filters), add --no-color test, raw text passthrough, missing ID error\n- fix change show JSON mapping to stable keys (id/title) and types; ensure build passes 2025-08-18 22:47:03 +10:00
Tabish Bidiwale 767a0053e8 Make change and spec commands consistent (raw-first)\n\n- Require explicit IDs for show; no auto-pick\n- Text mode: raw markdown passthrough; no filters\n- JSON contracts: minimal objects (no top-level arrays)\n- change show: add --deltas-only (JSON); deprecate --requirements-only\n- change list: ids by default; --long for minimal details; unified JSON { id, title, deltaCount, taskStatus }\n- spec show: raw text; JSON { id, title, overview, requirementCount, requirements, metadata }\n- spec list: ids by default; --long for minimal details; unified JSON { id, title, requirementCount }\n- Errors: console.error + process.exitCode\n- Add global --no-color\n- Update tests to new contracts 2025-08-18 22:31:17 +10:00
Tabish Bidiwale fd65b99c91 Merge pull request #38 from Fission-AI/add-change-commands
feat: add change command with show, list, and validate subcommands
2025-08-16 17:19:35 +10:00
Tabish Bidiwale e170df9f41 test(change): add minimal tests for change parser and command; fix async converter usage 2025-08-16 17:18:32 +10:00
Tabish Bidiwale b91040e8c2 chore(cli): tighten change show help text and remove unused imports 2025-08-16 17:18:32 +10:00
Tabish Bidiwale 8824bd2a42 feat: implement change-specific parser for delta format 2025-08-16 17:18:32 +10:00
Tabish Bidiwale 1d3c292d94 fix: address code review feedback for change commands
- Replace any types with proper Change and Delta types from schemas
- Add error logging in catch blocks when DEBUG env var is set
- Include file paths in error messages for better debugging
- Extract regex patterns and magic strings as constants
- Improve code maintainability and type safety
2025-08-16 17:18:32 +10:00
Tabish Bidiwale cfe6da96ac feat: add change command with show, list, and validate subcommands
- Add new `openspec change` command with three subcommands
- Implement JSON output capability for change proposals
- Add deprecation warning to legacy `openspec list` command
- Enable --requirements-only filtering for change show
- Support --strict mode and --json flags for validation

This provides programmatic access to change proposals through JSON output
and establishes a consistent resource-based command structure.
2025-08-16 17:18:32 +10:00
Tabish Bidiwale c3c78551d0 Merge pull request #37 from Fission-AI/add-spec-commands
Add spec command for programmatic access to specifications
2025-08-16 11:40:25 +10:00
Tabish Bidiwale f1fabc5f18 refactor: standardize spec format to use Purpose and Requirements sections only 2025-08-16 11:34:09 +10:00
Tabish Bidiwale 166b960428 chore(deps): upgrade zod to v4 and verify compatibility 2025-08-16 00:39:47 +10:00
Tabish Bidiwale ef1a6c0f0b docs: mark all spec command tasks as complete 2025-08-16 00:39:42 +10:00
Tabish Bidiwale 9b3944bd09 refactor(cli): simplify spec command parsing and filtering; improve option validation and exits 2025-08-16 00:32:55 +10:00
Tabish Bidiwale 7917d08a50 feat(cli): add spec command for programmatic access to specifications
Implements new `openspec spec` command with three subcommands:
- `spec show`: Display specs with JSON output and filtering options
- `spec list`: List all available specifications
- `spec validate`: Validate spec structure with detailed reporting

Key features:
- JSON output for CI/CD integration (--json flag)
- Content filtering (--requirements, --no-scenarios, -r)
- Strict validation mode (--strict)
- Support for both Overview/Purpose and Requirements/Behavior sections

This enables programmatic access to OpenSpec specifications for external
tools and automated pipelines as specified in the add-spec-commands change.
2025-08-15 23:54:26 +10:00
Tabish Bidiwale 4a8e5986f0 Merge pull request #35 from Fission-AI/add-zod-validation
feat: Add Zod runtime validation for specs and changes
2025-08-15 23:34:48 +10:00
Tabish Bidiwale 103838f371 fix: address PR review comments for validation improvements
- Use word boundaries in delta operation detection to avoid false matches
- Standardize name extraction to use directory name after specs/changes
- Combine archive validation warning into single prompt for better UX
- Add change.md validation to archive command before archiving
2025-08-15 23:32:51 +10:00
Tabish Bidiwale 0a26c686f9 refactor: simplify scenario parsing to store raw text
- Replace structured {given, when, then} with {rawText} field
- Remove complex Given/When/Then parsing logic
- Preserve original formatting and whitespace
- Update all tests to use rawText field
- Remove unnecessary validation checks

This change reduces complexity while preserving all content exactly
as written, making the system more maintainable and flexible.
2025-08-15 23:25:24 +10:00
Tabish Bidiwale efcf766193 docs: add validation and migration documentation to openspec
- Add VALIDATION.md with comprehensive schema and rules documentation
- Add MIGRATION.md with guide for future command integration
- Update task references to correct documentation locations
2025-08-15 23:07:00 +10:00
Tabish Bidiwale 151eddb759 fix: address minor code review issues
- Extract magic numbers to named constants in validation/constants.ts
- Update task 3.2 to reflect actual implementation (constants.ts)
- Add comprehensive documentation for validation system
- Add migration guide for future command integration
- Update CLI help text for diff command
2025-08-15 23:05:47 +10:00
Tabish Bidiwale cb0d6f3189 feat: add zod runtime validation for specs and changes
- Add Zod schemas for specs, changes, requirements, and scenarios
- Implement markdown parser for extracting structured data
- Create validation infrastructure with error/warning/info levels
- Enhance archive command with pre-archive validation
- Add --no-validate flag with confirmation prompt for emergencies
- Enhance diff command with non-blocking validation warnings
- Add JSON converters for spec and change formats
- Add comprehensive test coverage for all validation components
2025-08-15 22:50:05 +10:00
Tabish Bidiwale a897c697a5 Merge pull request #34 from Fission-AI/json-zod-implementation-plan
Add JSON output and Zod validation change proposals
2025-08-15 22:01:58 +10:00
Tabish Bidiwale 3bedf6b23e fix: move cli-change and cli-spec specs to their respective changes 2025-08-15 21:28:57 +10:00
Tabish Bidiwale 9ff0e85693 refactor: reorder implementation phases to zod -> change -> spec 2025-08-15 21:09:46 +10:00
Tabish Bidiwale 1ca407fa2f fix: rename --deltas to --requirements-only for clarity
The --deltas flag was ambiguous. Since it shows only the requirement
changes (ADDED/MODIFIED/REMOVED/RENAMED sections), rename it to
--requirements-only to be explicit about what it displays.
2025-08-15 19:14:29 +10:00
Tabish Bidiwale 46c927af06 fix: use explicit --json flag instead of ambiguous -j
Following the principle that explicit is better than implicit,
replace all occurrences of `-j` with `--json` for clarity.
2025-08-15 19:12:12 +10:00
Tabish Bidiwale 87cb206e88 feat: add JSON output and Zod validation change proposals
Add three OpenSpec change proposals for enhancing the CLI:
- add-spec-commands: Resource-based spec commands with JSON output
- add-change-commands: Resource-based change commands with JSON output
- add-zod-validation: Runtime validation with detailed error reporting

These proposals enable programmatic access to specs and changes,
improving integration with CI/CD pipelines and external tooling.
2025-08-15 17:40:06 +10:00
Tabish Bidiwale 6806a2fc5a Merge pull request #32 from Fission-AI/update-delta-conventions
feat: update conventions to support delta-based changes
2025-08-14 18:06:43 +10:00
Tabish Bidiwale 4ab65d75dd feat: update conventions to support delta-based changes
- Update openspec-conventions spec with delta-based approach
- Add Header-Based Requirement Identification for programmatic matching
- Define ADDED/MODIFIED/REMOVED/RENAMED sections format
- Document standard output symbols (+ ~ - →)
- Update openspec/README.md with delta conventions and examples
- Update init command template to use delta format
- Mark completed tasks in adopt-delta-based-changes/tasks.md

This implements the first part of the delta-based changes proposal,
updating all documentation and conventions to support the new format.
2025-08-14 18:01:09 +10:00
Tabish Bidiwale 2a3294dbfb Delete abandoned changes 2025-08-14 17:44:21 +10:00
Tabish Bidiwale 8334006f2b Merge pull request #31 from Fission-AI/adopt-delta-based-changes
feat: adopt delta-based change storage for better reviews
2025-08-14 17:33:50 +10:00
Tabish Bidiwale 8a559e0d00 fix: clarify openspec/README.md in tasks (AI instructions file) 2025-08-14 17:31:37 +10:00
Tabish Bidiwale a3924f17b2 fix: remove specific rendering examples from diff spec 2025-08-14 17:25:12 +10:00
Tabish Bidiwale b11e862b0f chore: reorganize tasks into clearer command-based groups 2025-08-14 17:20:18 +10:00
Tabish Bidiwale 099585afcb fix: remove unnecessary backward compatibility for full-state format 2025-08-14 17:16:18 +10:00
Tabish Bidiwale f023fc317e fix: simplify diff command to show only changes by default 2025-08-14 16:59:47 +10:00
Tabish Bidiwale 38a1463af0 fix: redesign diff command for requirement-level comparison
The diff command now applies deltas and shows side-by-side
requirement comparison rather than just displaying delta instructions.
2025-08-14 16:49:39 +10:00
Tabish Bidiwale f2399d3280 fix: restore implementation tasks that update actual specs
- Added back tasks to update the actual specs (not just proposals)
- Included validation implementation tasks
- Kept implementation-focused structure
- Clarified that specs in changes folder are proposals, not current truth
2025-08-14 12:51:01 +10:00
Tabish Bidiwale f699e10778 fix: remove duplication and simplify spec organization
- CLI specs now reference openspec-conventions for shared concepts
- Added standard output symbols definition to conventions
- Simplified tasks.md to focus on implementation only
- Fixed terminology to consistently use 'normalized header'
2025-08-14 12:38:27 +10:00
Tabish Bidiwale c824d8927f fix: address review feedback for consistency and clarity
- Unify header matching: normalize(header) = trim(header), case-sensitive
- Clarify RENAMED+MODIFIED: MODIFIED must use new header after rename
- Add RENAMED display to cli-diff with → symbol
- Define delta format detection via level-2 heading presence
- Remove RESTRUCTURED marker completely (unnecessary complexity)
- Standardize output symbols: + (added), ~ (modified), - (removed), → (renamed)
2025-08-14 12:14:26 +10:00
Tabish Bidiwale 5821b24ab3 fix: simplify proposal to reduce complexity
- Condense 'What Changes' section to core concepts only
- Simplify Impact section to essentials
- Make Conflict Resolution one concise paragraph
- Remove inline comment from example
- Focus on the key benefit: readable GitHub diffs
2025-08-14 00:02:30 +10:00
Tabish Bidiwale e812eb9e78 fix: remove migration timeline and deprecation notices
- Remove phased migration timeline (project not in use yet)
- Remove deprecation notices from CLI commands
- Keep simple backward compatibility for both formats
2025-08-13 23:59:52 +10:00
Tabish Bidiwale abfe13c5a7 fix: address review feedback on delta-based storage proposal
- Add whitespace normalization for header matching
- Add migration timeline with 3-phase approach over 6 months
- Clarify conflict resolution (handled by Git naturally)
- Replace 'self-contained' with 'complete content' for clarity
2025-08-13 23:57:24 +10:00
Tabish Bidiwale 0d5a75d3a0 feat: add cli-archive and cli-diff spec changes for delta-based storage 2025-08-13 23:49:36 +10:00
Tabish Bidiwale b30c0ad27e chore: remove overly detailed header-matching example 2025-08-13 23:43:14 +10:00
Tabish Bidiwale 1cada18186 feat: propose delta-based change storage for better reviews
- Replace full future state storage with delta-based approach
- Store only ADDED, MODIFIED, RENAMED, and REMOVED requirements
- Use headers as unique identifiers for programmatic matching
- Enable cleaner GitHub reviews showing only actual changes
- Add comprehensive examples and implementation tasks
2025-08-13 23:40:01 +10:00
Tabish Bidiwale fa50b07938 Merge pull request #29 from Fission-AI/fix-update-respects-tool-selection
fix: update command respects existing AI tool files
2025-08-13 23:36:50 +10:00
Tabish Bidiwale b6cad1631c feat: improve error handling and console output clarity
- Added try-catch error handling for configurator failures
- Improved console output to be more specific about what was updated
- Added TODO comment for future multi-configurator test enhancement
- Added test for error handling when configurator fails
- Console now shows 'Updated OpenSpec instructions (README.md)' for clarity
2025-08-13 23:33:23 +10:00
Tabish Bidiwale 2497e81e4d Merge pull request #28 from Fission-AI/add-skip-specs-archive-option
feat: add --skip-specs flag to archive command
2025-08-13 23:31:15 +10:00
Tabish Bidiwale d8cba03840 docs: enhance --skip-specs help text and add implementation notes 2025-08-13 23:27:41 +10:00
Tabish Bidiwale 0b1be19302 fix: update command respects existing AI tool files
The update command now only updates existing AI tool configuration
files instead of forcing CLAUDE.md creation. This allows team members
to use different AI tools without conflicts.

- Modified update.ts to check for existing files before updating
- Added comprehensive tests for the new behavior
- Updated spec and documentation to reflect team-friendly approach
- Created project README documenting the behavior
2025-08-13 23:25:53 +10:00
Tabish Bidiwale d7ebee4555 feat: add --skip-specs flag to archive command and fix confirmation behavior
- Add --skip-specs flag to archive command to skip spec update operations
- Fix confirmation behavior: declining spec updates now continues with archiving instead of cancelling
- Add comprehensive tests for new functionality
- Update task documentation to reflect completed implementation
2025-08-13 23:21:57 +10:00
Tabish Bidiwale 8f45a6f6ee Merge pull request #27 from Fission-AI/fix/update-respects-tool-selection
Fix: Update command respects AI tool selection
2025-08-13 23:11:36 +10:00
Tabish Bidiwale 6da77f01ce Merge pull request #26 from Fission-AI/feat/skip-spec-update-archive-proposal
feat: add skip-specs option for archive command
2025-08-13 23:10:45 +10:00
Tabish Bidiwale d90eccf959 fix: update command respects AI tool selection
The update command now only updates existing AI tool configuration
files instead of forcing CLAUDE.md creation. This allows team members
to use different AI tools without conflicts.
2025-08-13 23:06:05 +10:00
Tabish Bidiwale f192a97aeb feat: add proposal for skip-specs option in archive command
Add change proposal to enable skipping spec updates during archive operation.
This allows archiving changes that don't modify specs (tooling, docs, etc.)
and fixes the confirmation behavior to continue archiving even when users
decline spec updates.
2025-08-13 23:00:16 +10:00
Tabish Bidiwale 7781bbadd3 Merge pull request #25 from Fission-AI/feat/apply-structured-spec-format
feat: apply structured spec format to all specifications
2025-08-13 22:31:43 +10:00
Tabish Bidiwale aeaa1d50cc fix: remove Format Flexibility requirement from conventions
Remove the Format Flexibility section as it's not needed for the structured spec format. Keep focus on behavioral specifications only.
2025-08-13 22:29:10 +10:00
Tabish Bidiwale fa5df9a329 feat: apply structured spec format to all specifications
- Add Specification Format section to openspec-conventions with:
  - Requirement headers for consistent structure
  - Scenario headers with bold WHEN/THEN/AND keywords
  - Format flexibility for different content types

- Update all CLI command specs to use structured format:
  - cli-init: Convert all behavioral sections
  - cli-list: Apply structured format throughout
  - cli-update: Restructure requirements and edge cases
  - cli-diff: Update all behavior sections
  - cli-archive: Convert complex behaviors to scenarios

- Update openspec-conventions spec itself to follow its own format
- Mark all tasks as completed
2025-08-13 22:26:03 +10:00
Tabish Bidiwale f94f396c99 Merge pull request #24 from Fission-AI/cleanup/remove-add-requirement-markers
chore: remove abandoned add-requirement-markers change
2025-08-13 22:10:24 +10:00
Tabish Bidiwale 1f670f71d4 chore: remove abandoned add-requirement-markers change 2025-08-13 22:02:51 +10:00
Tabish Bidiwale 32b2901d13 Merge pull request #23 from Fission-AI/feat/structured-spec-format
feat(openspec): add structured format specification
2025-08-13 21:52:05 +10:00
Tabish Bidiwale 2ad0b1d306 feat: add tasks to update existing specs to new format
Add section 3 with tasks to update all existing CLI command specs to use the new structured format in their Behavior sections
2025-08-13 21:49:26 +10:00
Tabish Bidiwale 279d327899 fix: remove Format Flexibility task for non-behavioral specs
Non-behavioral specs not planned for now, keeping focus on behavioral specifications only
2025-08-13 21:48:36 +10:00
Tabish Bidiwale 5d848cf005 fix: remove unnecessary migration documentation
- Remove migration.md as project has no existing users to migrate
- Remove Migration Support section from tasks.md
- Structured format only applies to behavioral specs, not convention definitions
2025-08-13 21:36:52 +10:00
Tabish Bidiwale 5607fd3ccb fix: remove migration section from spec, keep only in change proposal 2025-08-13 21:21:28 +10:00
Tabish Bidiwale 6a0d862258 refactor: enhance openspec-conventions with structured format
- Merge format rules into openspec-conventions instead of separate spec
- Add Format Flexibility requirement for non-behavioral content
- Address review feedback on gradual migration and alternative formats
2025-08-13 21:17:46 +10:00
Tabish Bidiwale 1fe5f84fbc feat(openspec): add structured format specification for consistency 2025-08-13 21:05:36 +10:00
Tabish Bidiwale 80e78ecd1e chore: archive add-archive-command change after deployment 2025-08-13 18:49:17 +10:00
Tabish Bidiwale 564135a530 archive diff command 2025-08-13 18:47:31 +10:00
Tabish Bidiwale b9e80641a0 Merge pull request #21 from Fission-AI/feat/implement-archive-command
feat: implement archive command for OpenSpec changes
2025-08-13 18:41:54 +10:00
Tabish Bidiwale 0755994eaa refactor: use @inquirer/prompts for consistent UX in archive command
- Replace readline with @inquirer/prompts for all user interactions
- Add arrow key navigation for change selection (consistent with diff command)
- Use confirm() for yes/no prompts with better UX
- Remove manual readline interface management (no longer needed)
- Update tests to mock @inquirer/prompts instead of readline
- Add new test cases for interactive mode behavior

This change provides a consistent user experience across all OpenSpec commands,
where users can navigate options with arrow keys rather than typing numbers.
2025-08-13 18:37:18 +10:00
Tabish Bidiwale dcabd6de31 fix: address PR review feedback for archive command
- Add try-finally block to ensure readline interface always closes
- Extract date formatting to dedicated getArchiveDate() method
- Add comprehensive unit tests for ArchiveCommand covering:
  - Successful archiving flow
  - Incomplete tasks warning
  - Spec updates during archiving
  - Edge cases (missing tasks.md, no specs)
  - Error scenarios (missing change, duplicate archive)
  - No OpenSpec directory error
2025-08-13 18:27:24 +10:00
Tabish Bidiwale aef6ce01ff feat: implement archive command for OpenSpec changes
Adds a new `openspec archive` command that moves completed changes to an archive
directory with date-based naming. The command includes:
- Interactive change selection when no name provided
- Incomplete task warnings before archiving
- Automatic spec updates to main specs directory
- Confirmation prompts (skippable with --yes flag)
- Duplicate archive prevention

Also fixes TypeScript compilation errors in diff.ts and init.ts.
2025-08-13 18:19:26 +10:00
Tabish Bidiwale 441f9f444b Merge pull request #20 from Fission-AI/fix-archive-spec-updates
Fix: Add spec update functionality to archive command
2025-08-13 18:03:09 +10:00
Tabish Bidiwale b322829091 fix: add spec update functionality to archive command
The archive command was missing critical functionality to update main specs
from the change's future state specs when archiving. This fix adds:
- Spec update process that copies future state specs to main specs directory
- Confirmation prompt showing which specs will be created vs updated
- --yes flag for automation scenarios to skip confirmations
- Safety by default with clear visibility into spec changes
2025-08-13 18:00:00 +10:00
Tabish Bidiwale 5167e65a5c chore: archive add-list-command change after deployment 2025-08-13 17:36:12 +10:00
Tabish Bidiwale 5c6b4113a7 Merge pull request #19 from Fission-AI/feat/add-archive-command
feat: add archive command for completed changes
2025-08-13 17:25:34 +10:00
Tabish Bidiwale a8b76c3e69 Merge pull request #18 from Fission-AI/feat/implement-list-command
feat: add list command to show active changes with task status
2025-08-13 17:23:21 +10:00
Tabish Bidiwale d3237cac7b feat: add OpenSpec change proposal for archive command 2025-08-13 17:23:17 +10:00
Tabish Bidiwale e395eb4eeb feat: add list command to show active changes with task status 2025-08-13 17:17:40 +10:00
Tabish Bidiwale 76e1ec2a1f Merge pull request #12 from Fission-AI/feat/add-diff-command
feat: add diff command to view spec changes
2025-08-13 17:00:48 +10:00
Tabish Bidiwale 27eaccc024 Merge pull request #16 from Fission-AI/add-requirement-markers
feat: add @requirement markers convention
2025-08-13 15:28:56 +10:00
Tabish Bidiwale b288f2fc88 fix: update spec to contain complete future state per OpenSpec conventions 2025-08-13 15:21:14 +10:00
Tabish Bidiwale 22134a603b feat: add @requirement markers convention for requirement identification
- Define @requirement marker syntax for identifying requirements in specs
- Each marker includes a kebab-case identifier before WHEN/THEN blocks
- Document convention in openspec-conventions spec
- Enables reliable extraction without brittle regex parsing
2025-08-13 14:50:24 +10:00
Tabish Bidiwale 3b5fd11cb9 Merge pull request #13 from Fission-AI/feat/add-list-command
feat(openspec): add list command to display active changes
2025-08-12 16:57:43 +10:00
Tabish Bidiwale e9417fc147 Merge pull request #11 from Fission-AI/TabishB/abandon-status-command-change
chore: abandon add-status-command change
2025-08-12 01:03:39 +10:00
Tabish Bidiwale 8bcf2c6905 feat(openspec): add list command change proposal 2025-08-12 00:59:45 +10:00
Tabish Bidiwale 9a03ba1853 chore: abandon add-status-command change 2025-08-12 00:59:28 +10:00
998 changed files with 125194 additions and 1919 deletions
+1
View File
@@ -0,0 +1 @@
-P ubuntu-latest=catthehacker/ubuntu:act-latest
+95
View File
@@ -0,0 +1,95 @@
# Changesets
This directory is managed by [Changesets](https://github.com/changesets/changesets).
## Quick Start
```bash
pnpm changeset
```
Follow the prompts to select version bump type and describe your changes.
## Workflow
1. **Add a changeset** — Run `pnpm changeset` locally before or after your PR
2. **Version PR** — CI opens/updates a "Version Packages" PR when changesets merge to main
3. **Release** — Merging the Version PR triggers npm publish and GitHub Release
> **Note:** Contributors only need to run `pnpm changeset`. Versioning (`changeset version`) and publishing happen automatically in CI.
## Template
Use this structure for your changeset content:
```markdown
---
"@fission-ai/openspec": patch
---
### New Features
- **Feature name** — What users can now do
### Bug Fixes
- Fixed issue where X happened when Y
### Breaking Changes
- `oldMethod()` has been removed, use `newMethod()` instead
### Deprecations
- `legacyOption` is deprecated and will be removed in v2.0
### Other
- Internal refactoring of X for better performance
```
Include only the sections relevant to your change.
## Version Bump Guide
| Type | When to use | Example |
|------|-------------|---------|
| `patch` | Bug fixes, small improvements | Fixed crash when config missing |
| `minor` | New features, non-breaking additions | Added `--verbose` flag |
| `major` | Breaking changes, removed features | Renamed `init` to `setup` |
## When to Create a Changeset
**Create one for:**
- New features or commands
- Bug fixes that affect users
- Breaking changes or deprecations
- Performance improvements users would notice
**Skip for:**
- Documentation-only changes
- Test additions/fixes
- Internal refactoring with no user impact
- CI/tooling changes
## Writing Good Descriptions
**Do:** Write for users, not developers
```markdown
- **Shell completions** — Tab completion now available for Bash, Fish, and PowerShell
```
**Don't:** Write implementation details
```markdown
- Added ShellCompletionGenerator class with Bash/Fish/PowerShell subclasses
```
**Do:** Explain the impact
```markdown
- Fixed config loading to respect `XDG_CONFIG_HOME` on Linux
```
**Don't:** Just reference the fix
```markdown
- Fixed #123
```
+15
View File
@@ -0,0 +1,15 @@
{
"$schema": "https://unpkg.com/@changesets/config/schema.json",
"changelog": [
"@changesets/changelog-github",
{ "repo": "Fission-AI/OpenSpec" }
],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
+11
View File
@@ -0,0 +1,11 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
# Minimal configuration for getting started
language: "en-US"
reviews:
profile: "chill"
high_level_summary: true
auto_review:
enabled: true
drafts: false
base_branches:
- ".*"
+92
View File
@@ -0,0 +1,92 @@
# Dev Container Setup
This directory contains the VS Code dev container configuration for OpenSpec development.
## What's Included
- **Node.js 20 LTS** (>=20.19.0) - TypeScript/JavaScript runtime
- **pnpm** - Fast, disk space efficient package manager
- **Git + GitHub CLI** - Version control tools
- **VS Code Extensions**:
- ESLint & Prettier for code quality
- Vitest Explorer for running tests
- GitLens for enhanced git integration
- Error Lens for inline error highlighting
- Code Spell Checker
- Path IntelliSense
## How to Use
### First Time Setup
1. **Install Prerequisites** (on your local machine):
- [VS Code](https://code.visualstudio.com/)
- [Docker Desktop](https://www.docker.com/products/docker-desktop)
- [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
2. **Open in Container**:
- Open this project in VS Code
- You'll see a notification: "Folder contains a Dev Container configuration file"
- Click "Reopen in Container"
OR
- Open Command Palette (`Cmd/Ctrl+Shift+P`)
- Type "Dev Containers: Reopen in Container"
- Press Enter
3. **Wait for Setup**:
- The container will build (first time takes a few minutes)
- `pnpm install` runs automatically via `postCreateCommand`
- All extensions install automatically
### Daily Development
Once set up, the container preserves your development environment:
```bash
# Run development build
pnpm run dev
# Run CLI in development
pnpm run dev:cli
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Build the project
pnpm run build
```
### SSH Keys
Your SSH keys are mounted read-only from `~/.ssh`, so git operations work seamlessly with GitHub/GitLab.
### Rebuilding the Container
If you modify `.devcontainer/devcontainer.json`:
- Command Palette → "Dev Containers: Rebuild Container"
## Benefits
- No need to install Node.js or pnpm on your local machine
- Consistent development environment across team members
- Isolated from other Node.js projects on your machine
- All dependencies and tools containerized
- Easy onboarding for new developers
## Troubleshooting
**Container won't build:**
- Ensure Docker Desktop is running
- Check Docker has enough memory allocated (recommend 4GB+)
**Extensions not appearing:**
- Rebuild the container: "Dev Containers: Rebuild Container"
**Permission issues:**
- The container runs as the `node` user (non-root)
- Files created in the container are owned by this user
+68
View File
@@ -0,0 +1,68 @@
{
"name": "OpenSpec Development",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm",
// Additional tools and features
"features": {
"ghcr.io/devcontainers/features/git:1": {
"version": "latest",
"ppa": true
},
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "latest"
}
},
// Configure tool-specific properties
"customizations": {
"vscode": {
// Set default container specific settings
"settings": {
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"files.eol": "\n",
"terminal.integrated.defaultProfile.linux": "bash"
},
// Add extensions you want installed when the container is created
"extensions": [
// TypeScript/JavaScript essentials
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
// Testing
"vitest.explorer",
// Git
"eamodio.gitlens",
// Utilities
"streetsidesoftware.code-spell-checker",
"usernamehw.errorlens",
"christian-kohler.path-intellisense"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created
"postCreateCommand": "corepack enable && corepack prepare pnpm@latest --activate && pnpm install",
// Configure mounts to preserve SSH keys for git operations
"mounts": [
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,readonly,type=bind,consistency=cached"
],
// Set the default user to 'node' (non-root user)
"remoteUser": "node",
// Ensure git is properly configured
"initializeCommand": "echo 'Initializing dev container...'"
}
+2
View File
@@ -0,0 +1,2 @@
# Default code ownership
* @TabishB
+20
View File
@@ -0,0 +1,20 @@
# Github Workflows
## Testing CI Locally
Test GitHub Actions workflows locally using [act](https://nektosact.com/):
```bash
# Test all PR checks
act pull_request
# Test specific job
act pull_request -j nix-flake-validate
# Dry run to see what would execute
act pull_request --dryrun
```
The `.actrc` file configures act to use the appropriate Docker image.
+326
View File
@@ -0,0 +1,326 @@
name: CI
on:
pull_request:
branches: [main]
merge_group:
branches: [main]
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
# Detect which files changed to enable path-based filtering
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
nix: ${{ steps.filter.outputs.nix }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for Nix-related changes
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
nix:
- 'flake.nix'
- 'flake.lock'
- 'package.json'
- 'pnpm-lock.yaml'
- 'scripts/update-flake.sh'
- '.github/workflows/ci.yml'
test_pr:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 10
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build project
run: pnpm run build
- name: Run tests
run: pnpm test
- name: Upload test coverage
uses: actions/upload-artifact@v4
with:
name: coverage-report-pr
path: coverage/
retention-days: 7
test_matrix:
name: Test (${{ matrix.label }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
if: github.event_name == 'push'
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
shell: bash
label: linux-bash
- os: macos-latest
shell: bash
label: macos-bash
- os: windows-latest
shell: pwsh
label: windows-pwsh
defaults:
run:
shell: ${{ matrix.shell }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Print environment diagnostics
run: |
node -p "JSON.stringify({ platform: process.platform, arch: process.arch, shell: process.env.SHELL || process.env.ComSpec || '' })"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build project
run: pnpm run build
- name: Run tests
run: pnpm test
- name: Upload test coverage
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: coverage-report-main
path: coverage/
retention-days: 7
lint:
name: Lint & Type Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build project
run: pnpm run build
- name: Type check
run: pnpm exec tsc --noEmit
- name: Lint
run: pnpm lint
- name: Check for build artifacts
run: |
if [ ! -d "dist" ]; then
echo "Error: dist directory not found after build"
exit 1
fi
if [ ! -f "dist/cli/index.js" ]; then
echo "Error: CLI entry point not found"
exit 1
fi
nix-flake-validate:
name: Nix Flake Validation
runs-on: ubuntu-latest
timeout-minutes: 10
needs: changes
if: needs.changes.outputs.nix == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@v21
- name: Setup Nix cache
uses: DeterminateSystems/magic-nix-cache-action@v13
- name: Build with Nix
run: nix build
- name: Verify build output
run: |
if [ ! -e "result" ]; then
echo "Error: Nix build output 'result' symlink not found"
exit 1
fi
if [ ! -f "result/bin/openspec" ]; then
echo "Error: openspec binary not found in build output"
exit 1
fi
echo "✅ Build output verified"
- name: Test binary execution
run: |
VERSION=$(nix run . -- --version)
echo "OpenSpec version: $VERSION"
if [ -z "$VERSION" ]; then
echo "Error: Version command returned empty output"
exit 1
fi
echo "✅ Binary execution successful"
- name: Validate update script
run: |
echo "Testing update-flake.sh script..."
bash scripts/update-flake.sh
echo "✅ Update script executed successfully"
- name: Check flake.nix modifications
run: |
if git diff --quiet flake.nix; then
echo "ℹ️ flake.nix unchanged (hash already up-to-date)"
else
echo "✅ flake.nix was updated by script"
git diff flake.nix
fi
- name: Restore flake.nix
if: always()
run: git checkout -- flake.nix || true
validate-changesets:
name: Validate Changesets
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Validate changesets
run: |
if command -v changeset &> /dev/null; then
pnpm exec changeset status --since=origin/main
else
echo "Changesets not configured, skipping validation"
fi
required-checks-pr:
name: All checks passed
runs-on: ubuntu-latest
needs: [test_pr, lint, nix-flake-validate]
if: always() && (github.event_name == 'pull_request' || github.event_name == 'merge_group')
steps:
- name: Verify all checks passed
run: |
if [[ "${{ needs.test_pr.result }}" != "success" ]]; then
echo "Test job failed"
exit 1
fi
if [[ "${{ needs.lint.result }}" != "success" ]]; then
echo "Lint job failed"
exit 1
fi
# Nix validation may be skipped if no Nix-related files changed
if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
echo "Nix flake validation job failed"
exit 1
fi
if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
echo "Nix flake validation skipped (no Nix-related changes)"
fi
echo "All required checks passed!"
required-checks-main:
name: All checks passed
runs-on: ubuntu-latest
needs: [test_matrix, lint, nix-flake-validate]
if: always() && github.event_name == 'push'
steps:
- name: Verify all checks passed
run: |
if [[ "${{ needs.test_matrix.result }}" != "success" ]]; then
echo "Matrix test job failed"
exit 1
fi
if [[ "${{ needs.lint.result }}" != "success" ]]; then
echo "Lint job failed"
exit 1
fi
# Nix validation may be skipped if no Nix-related files changed
if [[ "${{ needs.nix-flake-validate.result }}" != "success" && "${{ needs.nix-flake-validate.result }}" != "skipped" ]]; then
echo "Nix flake validation job failed"
exit 1
fi
if [[ "${{ needs.nix-flake-validate.result }}" == "skipped" ]]; then
echo "Nix flake validation skipped (no Nix-related changes)"
fi
echo "All required checks passed!"
+60
View File
@@ -0,0 +1,60 @@
name: Release (prepare)
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
id-token: write # Required for npm OIDC trusted publishing
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
prepare:
if: github.repository == 'Fission-AI/OpenSpec'
runs-on: ubuntu-latest
steps:
# Generate GitHub App token first - used for checkout and changesets
# This allows git operations to trigger CI workflows on the version PR
# (GITHUB_TOKEN cannot trigger workflows by design)
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: '24' # Node 24 includes npm 11.5.1+ required for OIDC
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
- run: pnpm install --frozen-lockfile
# Opens/updates the Version Packages PR; publishes when the Version PR merges
- name: Create/Update Version PR
id: changesets
uses: changesets/action@v1
with:
title: 'chore(release): version packages'
createGithubReleases: true
# Use CI-specific release script: relies on version PR having been merged
# so package.json already contains the bumped version.
publish: pnpm run release:ci
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
# npm authentication handled via OIDC trusted publishing (no token needed)
+16 -3
View File
@@ -140,9 +140,22 @@ dist/
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
# Internal Docs
docs/
# Claude
.claude/
CLAUDE.md
CLAUDE.md
.DS_Store
# Pnpm
.pnpm-store/
result
# OpenCode
.opencode/
opencode.json
# Codex
.codex/
# Bob
.bob/
+27
View File
@@ -0,0 +1,27 @@
## Product Thinking
When discussing workflows, documentation, onboarding, or product behavior, start from the user's goal and lived interaction. Do not translate the problem into CLI commands, config flags, file formats, or internal implementation steps as the primary answer unless the user explicitly asks for that level.
Default framing:
- What is the user trying to accomplish?
- Where are they starting from?
- What should they say or do in the product experience?
- What should the agent/system do on their behalf?
- What outcome should they see?
Only after that, mention commands, files, APIs, or implementation mechanics as supporting detail. Treat these as backing mechanisms, not the user journey.
Bad pattern:
```text
Run command X, then command Y, then command Z.
```
Better pattern:
```text
Open the relevant experience and tell the agent what outcome you want. The system should guide the workflow and may use command X/Y/Z internally.
```
If the user is critiquing UX, docs, or workflow design, do not answer with a bare CLI recipe. First restate the intended human workflow, then identify where the current product forces implementation details onto the user.
+541
View File
@@ -0,0 +1,541 @@
# @fission-ai/openspec
## 1.3.0
### Minor Changes
- [#952](https://github.com/Fission-AI/OpenSpec/pull/952) [`cce787e`](https://github.com/Fission-AI/OpenSpec/commit/cce787ec4083da2b27781f6786f5ce0002909a7b) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
- **Junie support** — Added tool and command generation for JetBrains Junie
- **Lingma IDE support** — Added configuration support for Lingma IDE
- **ForgeCode support** — Added tool support for ForgeCode
- **IBM Bob support** — Added support for IBM Bob coding assistant
### Bug Fixes
- **Shell completions opt-in** — Completion install is now opt-in, fixing PowerShell encoding corruption
- **Copilot auto-detection** — Prevented false GitHub Copilot detection from a bare `.github/` directory
- **pi.dev command generation** — Fixed command reference transforms and template argument passing
### Patch Changes
- [#760](https://github.com/Fission-AI/OpenSpec/pull/760) [`61eb999`](https://github.com/Fission-AI/OpenSpec/commit/61eb999f7c6c0fc98d2e7f3678756fce6a3f4378) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: OpenCode adapter now uses `.opencode/commands/` (plural) to match OpenCode's official directory convention. Fixes #748.
- [#759](https://github.com/Fission-AI/OpenSpec/pull/759) [`afdca0d`](https://github.com/Fission-AI/OpenSpec/commit/afdca0d5dab1aa109cfd8848b2512333ccad60c3) Thanks [@fsilvaortiz](https://github.com/fsilvaortiz)! - fix: `openspec status` now exits gracefully when no changes exist instead of throwing a fatal error. Fixes #714.
## 1.2.0
### Minor Changes
- [#747](https://github.com/Fission-AI/OpenSpec/pull/747) [`1e94443`](https://github.com/Fission-AI/OpenSpec/commit/1e94443a3551b228eecbc89e95d96d3b9600a192) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
- **Profile system** — Choose between `core` (4 essential workflows) and `custom` (pick any subset) profiles to control which skills get installed. Manage profiles with the new `openspec config profile` command
- **Propose workflow** — New one-step workflow creates a complete change proposal with design, specs, and tasks from a single request — no need to run `new` then `ff` separately
- **AI tool auto-detection** — `openspec init` now scans your project for existing tool directories (`.claude/`, `.cursor/`, etc.) and pre-selects detected tools
- **Pi (pi.dev) support** — Pi coding agent is now a supported tool with prompt and skill generation
- **Kiro support** — AWS Kiro IDE is now a supported tool with prompt and skill generation
- **Sync prunes deselected workflows** — `openspec update` now removes command files and skill directories for workflows you've deselected, keeping your project clean
- **Config drift warning** — `openspec config list` warns when global config is out of sync with the current project
### Bug Fixes
- Fixed onboard preflight giving a false "not initialized" error on freshly initialized projects
- Fixed archive workflow stopping mid-way when syncing — it now properly resumes after sync completes
- Added Windows PowerShell alternatives for onboard shell commands
## 1.1.1
### Patch Changes
- [#627](https://github.com/Fission-AI/OpenSpec/pull/627) [`afb73cf`](https://github.com/Fission-AI/OpenSpec/commit/afb73cf9ec59c6f8b26d0c538c0218c203ba3c56) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
- **OpenCode command references** — Command references in generated files now use the correct `/opsx-` hyphen format instead of `/opsx:` colon format, ensuring commands work properly in OpenCode
## 1.1.0
### Minor Changes
- [#625](https://github.com/Fission-AI/OpenSpec/pull/625) [`53081fb`](https://github.com/Fission-AI/OpenSpec/commit/53081fb2a26ec66d2950ae0474b9a56cbc5b5a76) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
- **Codex global path support** — Codex adapter now resolves global paths correctly, fixing workflow file generation when run outside the project directory (#622)
- **Archive operations on cross-device or restricted paths** — Archive now falls back to copy+remove when rename fails with EPERM or EXDEV errors, fixing failures on networked/external drives (#605)
- **Slash command hints in workflow messages** — Workflow completion messages now display helpful slash command hints for next steps (#603)
- **Windsurf workflow file path** — Updated Windsurf adapter to use the correct `workflows` directory instead of the legacy `commands` path (#610)
### Patch Changes
- [#550](https://github.com/Fission-AI/OpenSpec/pull/550) [`86d2e04`](https://github.com/Fission-AI/OpenSpec/commit/86d2e04cae76a999dbd1b4571f52fa720036be0c) Thanks [@jerome-benoit](https://github.com/jerome-benoit)! - ### Improvements
- **Nix flake maintenance** — Version now read dynamically from package.json, reducing manual sync issues
- **Nix build optimization** — Source filtering excludes node_modules and artifacts, improving build times
- **update-flake.sh script** — Detects when hash is already correct, skipping unnecessary rebuilds
### Other
- Updated Nix CI actions to latest versions (nix-installer v21, magic-nix-cache v13)
## 1.0.2
### Patch Changes
- [#596](https://github.com/Fission-AI/OpenSpec/pull/596) [`e91568d`](https://github.com/Fission-AI/OpenSpec/commit/e91568deb948073f3e9d9bb2d2ab5bf8080d6cf4) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
- Clarified spec naming convention — Specs should be named after capabilities (`specs/<capability>/spec.md`), not changes
- Fixed task checkbox format guidance — Tasks now clearly require `- [ ]` checkbox format for apply phase tracking
## 1.0.1
### Patch Changes
- [#587](https://github.com/Fission-AI/OpenSpec/pull/587) [`943e0d4`](https://github.com/Fission-AI/OpenSpec/commit/943e0d41026d034de66b9442d1276c01b293eb2b) Thanks [@TabishB](https://github.com/TabishB)! - ### Bug Fixes
- Fixed incorrect archive path in onboarding documentation — the template now shows the correct path `openspec/changes/archive/YYYY-MM-DD-<name>/` instead of the incorrect `openspec/archive/YYYY-MM-DD--<name>/`
## 1.0.0
### Major Changes
- [#578](https://github.com/Fission-AI/OpenSpec/pull/578) [`0cc9d90`](https://github.com/Fission-AI/OpenSpec/commit/0cc9d9025af367faa1688a7b2606a2549053cd3f) Thanks [@TabishB](https://github.com/TabishB)! - ## OpenSpec 1.0 — The OPSX Release
The workflow has been rebuilt from the ground up. OPSX replaces the old phase-locked `/openspec:*` commands with an action-based system where AI understands what artifacts exist, what's ready to create, and what each action unlocks.
### Breaking Changes
- **Old commands removed** — `/openspec:proposal`, `/openspec:apply`, and `/openspec:archive` no longer exist
- **Config files removed** — Tool-specific instruction files (`CLAUDE.md`, `.cursorrules`, `AGENTS.md`, `project.md`) are no longer generated
- **Migration** — Run `openspec init` to upgrade. Legacy artifacts are detected and cleaned up with confirmation.
### From Static Prompts to Dynamic Instructions
**Before:** AI received the same static instructions every time, regardless of project state.
**Now:** Instructions are dynamically assembled from three layers:
1. **Context** — Project background from `config.yaml` (tech stack, conventions)
2. **Rules** — Artifact-specific constraints (e.g., "propose spike tasks for unknowns")
3. **Template** — The actual structure for the output file
AI queries the CLI for real-time state: which artifacts exist, what's ready to create, what dependencies are satisfied, and what each action unlocks.
### From Phase-Locked to Action-Based
**Before:** Linear workflow — proposal → apply → archive. Couldn't easily go back or iterate.
**Now:** Flexible actions on a change. Edit any artifact anytime. The artifact graph tracks state automatically.
| Command | What it does |
| -------------------- | ---------------------------------------------------- |
| `/opsx:explore` | Think through ideas before committing to a change |
| `/opsx:new` | Start a new change |
| `/opsx:continue` | Create one artifact at a time (step-through) |
| `/opsx:ff` | Create all planning artifacts at once (fast-forward) |
| `/opsx:apply` | Implement tasks |
| `/opsx:verify` | Validate implementation matches artifacts |
| `/opsx:sync` | Sync delta specs to main specs |
| `/opsx:archive` | Archive completed change |
| `/opsx:bulk-archive` | Archive multiple changes with conflict detection |
| `/opsx:onboard` | Guided 15-minute walkthrough of complete workflow |
### From Text Merging to Semantic Spec Syncing
**Before:** Spec updates required manual merging or wholesale file replacement.
**Now:** Delta specs use semantic markers that AI understands:
- `## ADDED Requirements` — New requirements to add
- `## MODIFIED Requirements` — Partial updates (add scenario without copying existing ones)
- `## REMOVED Requirements` — Delete with reason and migration notes
- `## RENAMED Requirements` — Rename preserving content
Archive parses these at the requirement level, not brittle header matching.
### From Scattered Files to Agent Skills
**Before:** 8+ config files at project root + slash commands scattered across 21 tool-specific locations with different formats.
**Now:** Single `.claude/skills/` directory with YAML-fronted markdown files. Auto-detected by Claude Code, Cursor, Windsurf. Cross-editor compatible.
### New Features
- **Onboarding skill** — `/opsx:onboard` walks new users through their first complete change with codebase-aware task suggestions and step-by-step narration (11 phases, ~15 minutes)
- **21 AI tools supported** — Claude Code, Cursor, Windsurf, Continue, Gemini CLI, GitHub Copilot, Amazon Q, Cline, RooCode, Kilo Code, Auggie, CodeBuddy, Qoder, Qwen, CoStrict, Crush, Factory, OpenCode, Antigravity, iFlow, and Codex
- **Interactive setup** — `openspec init` shows animated welcome screen and searchable multi-select for choosing tools. Pre-selects already-configured tools for easy refresh.
- **Customizable schemas** — Define custom artifact workflows in `openspec/schemas/` without touching package code. Teams can share workflows via version control.
### Bug Fixes
- Fixed Claude Code YAML parsing failure when command names contained colons
- Fixed task file parsing to handle trailing whitespace on checkbox lines
- Fixed JSON instruction output to separate context/rules from template — AI was copying constraint blocks into artifact files
### Documentation
- New getting-started guide, CLI reference, concepts documentation
- Removed misleading "edit mid-flight and continue" claims that weren't implemented
- Added migration guide for upgrading from pre-OPSX versions
## 0.23.0
### Minor Changes
- [#540](https://github.com/Fission-AI/OpenSpec/pull/540) [`c4cfdc7`](https://github.com/Fission-AI/OpenSpec/commit/c4cfdc7c499daef30d8a218f5f59b8d9e5adb754) Thanks [@TabishB](https://github.com/TabishB)! - ### New Features
- **Bulk archive skill** — Archive multiple completed changes in a single operation with `/opsx:bulk-archive`. Includes batch validation, spec conflict detection, and consolidated confirmation
### Other
- **Simplified setup** — Config creation now uses sensible defaults with helpful comments instead of interactive prompts
## 0.22.0
### Minor Changes
- [#530](https://github.com/Fission-AI/OpenSpec/pull/530) [`33466b1`](https://github.com/Fission-AI/OpenSpec/commit/33466b1e2a6798bdd6d0e19149173585b0612e6f) Thanks [@TabishB](https://github.com/TabishB)! - Add project-level configuration, project-local schemas, and schema management commands
**New Features**
- **Project-level configuration** — Configure OpenSpec behavior per-project via `openspec/config.yaml`, including custom rules injection, context files, and schema resolution settings
- **Project-local schemas** — Define custom artifact schemas within your project's `openspec/schemas/` directory for project-specific workflows
- **Schema management commands** — New `openspec schema` commands (`list`, `show`, `export`, `validate`) for inspecting and managing artifact schemas (experimental)
**Bug Fixes**
- Fixed config loading to handle null `rules` field in project configuration
## 0.21.0
### Minor Changes
- [#516](https://github.com/Fission-AI/OpenSpec/pull/516) [`b5a8847`](https://github.com/Fission-AI/OpenSpec/commit/b5a884748be6156a7bb140b4941cfec4f20a9fc8) Thanks [@TabishB](https://github.com/TabishB)! - Add feedback command and Nix flake support
**New Features**
- **Feedback command** — Submit feedback directly from the CLI with `openspec feedback`, which creates GitHub Issues with automatic metadata inclusion and graceful fallback for manual submission
- **Nix flake support** — Install and develop openspec using Nix with the new `flake.nix`, including automated flake maintenance and CI validation
**Bug Fixes**
- **Explore mode guardrails** — Explore mode now explicitly prevents implementation, keeping the focus on thinking and discovery while still allowing artifact creation
**Other**
- Improved change inference in `opsx apply` — automatically detects the target change from conversation context or prompts when ambiguous
- Streamlined archive sync assessment with clearer delta spec location guidance
## 0.20.0
### Minor Changes
- [#502](https://github.com/Fission-AI/OpenSpec/pull/502) [`9db74aa`](https://github.com/Fission-AI/OpenSpec/commit/9db74aa5ac6547efadaed795217cfa17444f2004) Thanks [@TabishB](https://github.com/TabishB)! - Add `/opsx:verify` command and fix vitest process storms
**New Features**
- **`/opsx:verify` command** — Validate that change implementations match their specifications
**Bug Fixes**
- Fixed vitest process storms by capping worker parallelism
- Fixed agent workflows to use non-interactive mode for validation commands
- Fixed PowerShell completions generator to remove trailing commas
## 0.19.0
### Minor Changes
- eb152eb: Add Continue IDE support, shell completions, and `/opsx:explore` command
**New Features**
- **Continue IDE support** – OpenSpec now generates slash commands for [Continue](https://continue.dev/), expanding editor integration options alongside Cursor, Windsurf, Claude Code, and others
- **Shell completions for Bash, Fish, and PowerShell** – Run `openspec completion install` to set up tab completion in your preferred shell
- **`/opsx:explore` command** – A new thinking partner mode for exploring ideas and investigating problems before committing to changes
- **Codebuddy slash command improvements** – Updated frontmatter format for better compatibility
**Bug Fixes**
- Shell completions now correctly offer parent-level flags (like `--help`) when a command has subcommands
- Fixed Windows compatibility issues in tests
**Other**
- Added optional anonymous usage statistics to help understand how OpenSpec is used. This is **opt-out** by default – set `OPENSPEC_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable. Only command names and version are collected; no arguments, file paths, or content. Automatically disabled in CI environments.
## 0.18.0
### Minor Changes
- 8dfd824: Add OPSX experimental workflow commands and enhanced artifact system
**New Commands:**
- `/opsx:ff` - Fast-forward through artifact creation, generating all needed artifacts in one go
- `/opsx:sync` - Sync delta specs from a change to main specs
- `/opsx:archive` - Archive completed changes with smart sync check
**Artifact Workflow Enhancements:**
- Schema-aware apply instructions with inline guidance and XML output
- Agent schema selection for experimental artifact workflow
- Per-change schema metadata via `.openspec.yaml` files
- Agent Skills for experimental artifact workflow
- Instruction loader for template loading and change context
- Restructured schemas as directories with templates
**Improvements:**
- Enhanced list command with last modified timestamps and sorting
- Change creation utilities for better workflow support
**Fixes:**
- Normalize paths for cross-platform glob compatibility
- Allow REMOVED requirements when creating new spec files
## 0.17.2
### Patch Changes
- 455c65f: Fix `--no-interactive` flag in validate command to properly disable spinner, preventing hangs in pre-commit hooks and CI environments
## 0.17.1
### Patch Changes
- a2757e7: Fix pre-commit hook hang issue in config command by using dynamic import for @inquirer/prompts
The config command was causing pre-commit hooks to hang indefinitely due to stdin event listeners being registered at module load time. This fix converts the static import to a dynamic import that only loads inquirer when the `config reset` command is actually used interactively.
Also adds ESLint with a rule to prevent static @inquirer imports, avoiding future regressions.
## 0.17.0
### Minor Changes
- 2e71835: Add `openspec config` command and Oh-my-zsh completions
**New Features**
- Add `openspec config` command for managing global configuration settings
- Implement global config directory with XDG Base Directory specification support
- Add Oh-my-zsh shell completions support for enhanced CLI experience
**Bug Fixes**
- Fix hang in pre-commit hooks by using dynamic imports
- Respect XDG_CONFIG_HOME environment variable on all platforms
- Resolve Windows compatibility issues in zsh-installer tests
- Align cli-completion spec with implementation
- Remove hardcoded agent field from slash commands
**Documentation**
- Alphabetize AI tools list in README and make it collapsible
## 0.16.0
### Minor Changes
- c08fbc1: Add new AI tool integrations and enhancements:
- **feat(iflow-cli)**: Add iFlow-cli integration with slash command support and documentation
- **feat(init)**: Add IDE restart instruction after init to inform users about slash command availability
**feat(antigravity)**: Add Antigravity slash command support
- **fix**: Generate TOML commands for Qwen Code (fixes #293)
- Clarify scaffold proposal documentation and enhance proposal guidelines
- Update proposal guidelines to emphasize design-first approach before implementation
## Unreleased
### Minor Changes
- Add Continue slash command support so `openspec init` can generate `.continue/prompts/openspec-*.prompt` files with MARKDOWN frontmatter and `$ARGUMENTS` placeholder, and refresh them on `openspec update`.
- Add Antigravity slash command support so `openspec init` can generate `.agent/workflows/openspec-*.md` files with description-only frontmatter and `openspec update` refreshes existing workflows alongside Windsurf.
## 0.15.0
### Minor Changes
- 4758c5c: Add support for new AI tools with native slash command integration
- **Gemini CLI**: Add native TOML-based slash command support for Gemini CLI with `.gemini/commands/openspec/` integration
- **RooCode**: Add RooCode integration with configurator, slash commands, and templates
- **Cline**: Fix Cline to use workflows instead of rules for slash commands (`.clinerules/workflows/` paths)
- **Documentation**: Update documentation to reflect new integrations and workflow changes
## 0.14.0
### Minor Changes
- 8386b91: Add support for new AI assistants and configuration improvements
- feat: add Qwen Code support with slash command integration
- feat: add $ARGUMENTS support to apply slash command for dynamic variable passing
- feat: add Qoder CLI support to configuration and documentation
- feat: add CoStrict AI assistant support
- fix: recreate missing openspec template files in extend mode
- fix: prevent false 'already configured' detection for tools
- fix: use change-id as fallback title instead of "Untitled Change"
- docs: add guidance for populating project-level context
- docs: add Crush to supported AI tools in README
## 0.13.0
### Minor Changes
- 668a125: Add support for multiple AI assistants and improve validation
This release adds support for several new AI coding assistants:
- CodeBuddy Code - AI-powered coding assistant
- CodeRabbit - AI code review assistant
- Cline - Claude-powered CLI assistant
- Crush AI - AI assistant platform
- Auggie (Augment CLI) - Code augmentation tool
New features:
- Archive slash command now supports arguments for more flexible workflows
Bug fixes:
- Delta spec validation now handles case-insensitive headers and properly detects empty sections
- Archive validation now correctly honors --no-validate flag and ignores metadata
Documentation improvements:
- Added VS Code dev container configuration for easier development setup
- Updated AGENTS.md with explicit change-id notation
- Enhanced slash commands documentation with restart notes
## 0.12.0
### Minor Changes
- 082abb4: Add factory function support for slash commands and non-interactive init options
This release includes two new features:
- **Factory function support for slash commands**: Slash commands can now be defined as functions that return command objects, enabling dynamic command configuration
- **Non-interactive init options**: Added `--tools`, `--all-tools`, and `--skip-tools` CLI flags to `openspec init` for automated initialization in CI/CD pipelines while maintaining backward compatibility with interactive mode
## 0.11.0
### Minor Changes
- 312e1d6: Add Amazon Q Developer CLI integration. OpenSpec now supports Amazon Q Developer with automatic prompt generation in `.amazonq/prompts/` directory, allowing you to use OpenSpec slash commands with Amazon Q's @-syntax.
## 0.10.0
### Minor Changes
- d7e0ce8: Improve init wizard Enter key behavior to allow proceeding through prompts more naturally
## 0.9.2
### Patch Changes
- 2ae0484: Fix cross-platform path handling issues. This release includes fixes for joinPath behavior and slash command path resolution to ensure OpenSpec works correctly across all platforms.
## 0.9.1
### Patch Changes
- 8210970: Fix OpenSpec not working on Windows when Codex integration is selected. This release includes fixes for cross-platform path handling and normalization to ensure OpenSpec works correctly on Windows systems.
## 0.9.0
### Minor Changes
- efbbf3b: Add support for Codex and GitHub Copilot slash commands with YAML frontmatter and $ARGUMENTS
## Unreleased
### Minor Changes
- Add GitHub Copilot slash command support. OpenSpec now writes prompts to `.github/prompts/openspec-{proposal,apply,archive}.prompt.md` with YAML frontmatter and `$ARGUMENTS` placeholder, and refreshes them on `openspec update`.
## 0.8.1
### Patch Changes
- d070d08: Fix CLI version mismatch and add a release guard that validates the packed tarball prints the same version as package.json via `openspec --version`.
## 0.8.0
### Minor Changes
- c29b06d: Add Windsurf support.
- Add Codex slash command support. OpenSpec now writes prompts directly to Codex's global directory (`~/.codex/prompts` or `$CODEX_HOME/prompts`) and refreshes them on `openspec update`.
## 0.7.0
### Minor Changes
- Add native Kilo Code workflow integration so `openspec init` and `openspec update` manage `.kilocode/workflows/openspec-*.md` files.
- Always scaffold the managed root `AGENTS.md` hand-off stub and regroup the AI tool prompts during init/update to keep instructions consistent.
## 0.6.0
### Minor Changes
- Slim the generated root agent instructions down to a managed hand-off stub and update the init/update flows to refresh it safely.
## 0.5.0
### Minor Changes
- feat: implement Phase 1 E2E testing with cross-platform CI matrix
- Add shared runCLI helper in test/helpers/run-cli.ts for spawn testing
- Create test/cli-e2e/basic.test.ts covering help, version, validate flows
- Migrate existing CLI exec tests to use runCLI helper
- Extend CI matrix to bash (Linux/macOS) and pwsh (Windows)
- Split PR and main workflows for optimized feedback
### Patch Changes
- Make apply instructions more specific
Improve agent templates and slash command templates with more specific and actionable apply instructions.
- docs: improve documentation and cleanup
- Document non-interactive flag for archive command
- Replace discord badge in README
- Archive completed changes for better organization
## 0.4.0
### Minor Changes
- Add OpenSpec change proposals for CLI improvements and enhanced user experience
- Add Opencode slash commands support for AI-driven development workflows
### Patch Changes
- Add documentation improvements including --yes flag for archive command template and Discord badge
- Fix normalize line endings in markdown parser to handle CRLF files properly
## 0.3.0
### Minor Changes
- Enhance `openspec init` with extend mode, multi-tool selection, and an interactive `AGENTS.md` configurator.
## 0.2.0
### Minor Changes
- ce5cead: - Add an `openspec view` dashboard that rolls up spec counts and change progress at a glance
- Generate and update AI slash commands alongside the renamed `openspec/AGENTS.md` instructions file
- Remove the deprecated `openspec diff` command and direct users to `openspec show`
## 0.1.0
### Minor Changes
- 24b4866: Initial release
+22
View File
@@ -0,0 +1,22 @@
MIT License
Copyright (c) 2024 OpenSpec Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+17
View File
@@ -0,0 +1,17 @@
# Maintainers
People who maintain and guide OpenSpec.
## Core Maintainers
| Name | GitHub | Role |
|------|--------|------|
| Tabish Bidiwale | [@TabishB](https://github.com/TabishB) | Lead maintainer |
## Advisors
Advisors help shape technical direction and provide guidance to the project.
| Name | GitHub | Focus |
|------|--------|-------|
| Hari Krishnan | [@harikrishnan83](https://github.com/harikrishnan83) | Technical direction |
+201
View File
@@ -0,0 +1,201 @@
<p align="center">
<a href="https://github.com/Fission-AI/OpenSpec">
<picture>
<source srcset="assets/openspec_bg.png">
<img src="assets/openspec_bg.png" alt="OpenSpec logo">
</picture>
</a>
</p>
<p align="center">
<a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
<a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
<a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/discord/1411657095639601154?style=flat-square&logo=discord&logoColor=white&label=Discord&suffix=%20online" /></a>
</p>
<details>
<summary><strong>The most loved spec framework.</strong></summary>
[![Stars](https://img.shields.io/github/stars/Fission-AI/OpenSpec?style=flat-square&label=Stars)](https://github.com/Fission-AI/OpenSpec/stargazers)
[![Downloads](https://img.shields.io/npm/dm/@fission-ai/openspec?style=flat-square&label=Downloads/mo)](https://www.npmjs.com/package/@fission-ai/openspec)
[![Contributors](https://img.shields.io/github/contributors/Fission-AI/OpenSpec?style=flat-square&label=Contributors)](https://github.com/Fission-AI/OpenSpec/graphs/contributors)
</details>
<p></p>
Our philosophy:
```text
→ fluid not rigid
→ iterative not waterfall
→ easy not complex
→ built for brownfield not just greenfield
→ scalable from personal projects to enterprises
```
> [!TIP]
> **New workflow now available!** We've rebuilt OpenSpec with a new artifact-guided workflow.
>
> Run `/opsx:propose "your idea"` to get started. → [Learn more here](docs/opsx.md)
<p align="center">
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
</p>
<!-- TODO: Add GIF demo of /opsx:propose → /opsx:archive workflow -->
## See it in action
```text
You: /opsx:propose add-dark-mode
AI: Created openspec/changes/add-dark-mode/
✓ proposal.md — why we're doing this, what's changing
✓ specs/ — requirements and scenarios
✓ design.md — technical approach
✓ tasks.md — implementation checklist
Ready for implementation!
You: /opsx:apply
AI: Implementing tasks...
✓ 1.1 Add theme context provider
✓ 1.2 Create toggle component
✓ 2.1 Add CSS variables
✓ 2.2 Wire up localStorage
All tasks complete!
You: /opsx:archive
AI: Archived to openspec/changes/archive/2025-01-23-add-dark-mode/
Specs updated. Ready for the next feature.
```
<details>
<summary><strong>OpenSpec Dashboard</strong></summary>
<p align="center">
<img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
</p>
</details>
## Quick Start
**Requires Node.js 20.19.0 or higher.**
Install OpenSpec globally:
```bash
npm install -g @fission-ai/openspec@latest
```
Then navigate to your project directory and initialize:
```bash
cd your-project
openspec init
```
Now tell your AI: `/opsx:propose <what-you-want-to-build>`
If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:sync`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.
> [!NOTE]
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing.
>
> Also works with pnpm, yarn, bun, and nix. [See installation options](docs/installation.md).
## Docs
→ **[Getting Started](docs/getting-started.md)**: first steps<br>
→ **[Workflows](docs/workflows.md)**: combos and patterns<br>
→ **[Commands](docs/commands.md)**: slash commands & skills<br>
→ **[CLI](docs/cli.md)**: terminal reference<br>
→ **[Workspace Mode](docs/workspace.md)**: when to use cross-repo workspaces, starting with `openspec workspace setup`<br>
→ **[Workspace Demo](docs/workspace-demo.md)**: a real-user workspace tutorial you can run against your actual local repos<br>
→ **[Supported Tools](docs/supported-tools.md)**: tool integrations & install paths<br>
→ **[Concepts](docs/concepts.md)**: how it all fits<br>
→ **[Multi-Language](docs/multi-language.md)**: multi-language support<br>
→ **[Customization](docs/customization.md)**: make it yours
## Why OpenSpec?
AI coding assistants are powerful but unpredictable when requirements live only in chat history. OpenSpec adds a lightweight spec layer so you agree on what to build before any code is written.
- **Agree before you build** — human and AI align on specs before code gets written
- **Stay organized** — each change gets its own folder with proposal, specs, design, and tasks
- **Work fluidly** — update any artifact anytime, no rigid phase gates
- **Use your tools** — works with 20+ AI assistants via slash commands
### How we compare
**vs. [Spec Kit](https://github.com/github/spec-kit)** (GitHub) — Thorough but heavyweight. Rigid phase gates, lots of Markdown, Python setup. OpenSpec is lighter and lets you iterate freely.
**vs. [Kiro](https://kiro.dev)** (AWS) — Powerful but you're locked into their IDE and limited to Claude models. OpenSpec works with the tools you already use.
**vs. nothing** — AI coding without specs means vague prompts and unpredictable results. OpenSpec brings predictability without the ceremony.
## Updating OpenSpec
**Upgrade the package**
```bash
npm install -g @fission-ai/openspec@latest
```
**Refresh agent instructions**
Run this inside each project to regenerate AI guidance and ensure the latest slash commands are active:
```bash
openspec update
```
## Usage Notes
**Model selection**: OpenSpec works best with high-reasoning models. We recommend Opus 4.5 and GPT 5.2 for both planning and implementation.
**Context hygiene**: OpenSpec benefits from a clean context window. Clear your context before starting implementation and maintain good context hygiene throughout your session.
## Contributing
**Small fixes** — Bug fixes, typo corrections, and minor improvements can be submitted directly as PRs.
**Larger changes** — For new features, significant refactors, or architectural changes, please submit an OpenSpec change proposal first so we can align on intent and goals before implementation begins.
When writing proposals, keep the OpenSpec philosophy in mind: we serve a wide variety of users across different coding agents, models, and use cases. Changes should work well for everyone.
**AI-generated code is welcome** — as long as it's been tested and verified. PRs containing AI-generated code should mention the coding agent and model used (e.g., "Generated with Claude Code using claude-opus-4-5-20251101").
### Development
- Install dependencies: `pnpm install`
- Build: `pnpm run build`
- Test: `pnpm test`
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
- Conventional commits (one-line): `type(scope): subject`
## Other
<details>
<summary><strong>Telemetry</strong></summary>
OpenSpec collects anonymous usage stats.
We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.
**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`
</details>
<details>
<summary><strong>Maintainers & Advisors</strong></summary>
See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.
</details>
## License
MIT
+475
View File
@@ -0,0 +1,475 @@
<p align="center">
<a href="https://github.com/Fission-AI/OpenSpec">
<picture>
<source srcset="assets/openspec_pixel_dark.svg" media="(prefers-color-scheme: dark)">
<source srcset="assets/openspec_pixel_light.svg" media="(prefers-color-scheme: light)">
<img src="assets/openspec_pixel_light.svg" alt="OpenSpec logo" height="64">
</picture>
</a>
</p>
<p align="center">Spec-driven development for AI coding assistants.</p>
<p align="center">
<a href="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Fission-AI/OpenSpec/actions/workflows/ci.yml/badge.svg" /></a>
<a href="https://www.npmjs.com/package/@fission-ai/openspec"><img alt="npm version" src="https://img.shields.io/npm/v/@fission-ai/openspec?style=flat-square" /></a>
<a href="https://nodejs.org/"><img alt="node version" src="https://img.shields.io/node/v/@fission-ai/openspec?style=flat-square" /></a>
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" /></a>
<a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg?style=flat-square" /></a>
<a href="https://discord.gg/YctCnvvshC"><img alt="Discord" src="https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white&style=flat-square" /></a>
</p>
<p align="center">
<img src="assets/openspec_dashboard.png" alt="OpenSpec dashboard preview" width="90%">
</p>
<p align="center">
Follow <a href="https://x.com/0xTab">@0xTab on X</a> for updates · Join the <a href="https://discord.gg/YctCnvvshC">OpenSpec Discord</a> for help and questions.
</p>
<p align="center">
<sub>🧪 <strong>New:</strong> <a href="docs/opsx.md">OPSX Workflow</a> — schema-driven, hackable, fluid. Iterate on workflows without code changes.</sub>
</p>
# OpenSpec
OpenSpec aligns humans and AI coding assistants with spec-driven development so you agree on what to build before any code is written. **No API keys required.**
## Why OpenSpec?
AI coding assistants are powerful but unpredictable when requirements live in chat history. OpenSpec adds a lightweight specification workflow that locks intent before implementation, giving you deterministic, reviewable outputs.
Key outcomes:
- Human and AI stakeholders agree on specs before work begins.
- Structured change folders (proposals, tasks, and spec updates) keep scope explicit and auditable.
- Shared visibility into what's proposed, active, or archived.
- Works with the AI tools you already use: custom slash commands where supported, context rules everywhere else.
## How OpenSpec compares (at a glance)
- **Lightweight**: simple workflow, no API keys, minimal setup.
- **Brownfield-first**: works great beyond 0→1. OpenSpec separates the source of truth from proposals: `openspec/specs/` (current truth) and `openspec/changes/` (proposed updates). This keeps diffs explicit and manageable across features.
- **Change tracking**: proposals, tasks, and spec deltas live together; archiving merges the approved updates back into specs.
- **Compared to spec-kit & Kiro**: those shine for brand-new features (0→1). OpenSpec also excels when modifying existing behavior (1→n), especially when updates span multiple specs.
See the full comparison in [How OpenSpec Compares](#how-openspec-compares).
## How It Works
```
┌────────────────────┐
│ Draft Change │
│ Proposal │
└────────┬───────────┘
│ share intent with your AI
▼
┌────────────────────┐
│ Review & Align │
│ (edit specs/tasks) │◀──── feedback loop ──────┐
└────────┬───────────┘ │
│ approved plan │
▼ │
┌────────────────────┐ │
│ Implement Tasks │──────────────────────────┘
│ (AI writes code) │
└────────┬───────────┘
│ ship the change
▼
┌────────────────────┐
│ Archive & Update │
│ Specs (source) │
└────────────────────┘
1. Draft a change proposal that captures the spec updates you want.
2. Review the proposal with your AI assistant until everyone agrees.
3. Implement tasks that reference the agreed specs.
4. Archive the change to merge the approved updates back into the source-of-truth specs.
```
## Getting Started
### Supported AI Tools
<details>
<summary><strong>Native Slash Commands</strong> (click to expand)</summary>
These tools have built-in OpenSpec commands. Select the OpenSpec integration when prompted.
| Tool | Commands |
|------|----------|
| **Amazon Q Developer** | `@openspec-proposal`, `@openspec-apply`, `@openspec-archive` (`.amazonq/prompts/`) |
| **Antigravity** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.agent/workflows/`) |
| **Auggie (Augment CLI)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.augment/commands/`) |
| **Claude Code** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` |
| **Cline** | Workflows in `.clinerules/workflows/` directory (`.clinerules/workflows/openspec-*.md`) |
| **CodeBuddy Code (CLI)** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.codebuddy/commands/`) — see [docs](https://www.codebuddy.ai/cli) |
| **Codex** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (global: `~/.codex/prompts`, auto-installed) |
| **Continue** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.continue/prompts/`) |
| **CoStrict** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.cospec/openspec/commands/`) — see [docs](https://costrict.ai)|
| **Crush** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.crush/commands/openspec/`) |
| **Cursor** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
| **Factory Droid** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.factory/commands/`) |
| **Gemini CLI** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.gemini/commands/openspec/`) |
| **GitHub Copilot** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.github/prompts/`) |
| **iFlow (iflow-cli)** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.iflow/commands/`) |
| **Kilo Code** | `/openspec-proposal.md`, `/openspec-apply.md`, `/openspec-archive.md` (`.kilocode/workflows/`) |
| **OpenCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` |
| **Qoder** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` (`.qoder/commands/openspec/`) — see [docs](https://qoder.com) |
| **Qwen Code** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.qwen/commands/`) |
| **RooCode** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.roo/commands/`) |
| **Windsurf** | `/openspec-proposal`, `/openspec-apply`, `/openspec-archive` (`.windsurf/workflows/`) |
Kilo Code discovers team workflows automatically. Save the generated files under `.kilocode/workflows/` and trigger them from the command palette with `/openspec-proposal.md`, `/openspec-apply.md`, or `/openspec-archive.md`.
</details>
<details>
<summary><strong>AGENTS.md Compatible</strong> (click to expand)</summary>
These tools automatically read workflow instructions from `openspec/AGENTS.md`. Ask them to follow the OpenSpec workflow if they need a reminder. Learn more about the [AGENTS.md convention](https://agents.md/).
| Tools |
|-------|
| Amp • Jules • Others |
</details>
### Install & Initialize
#### Prerequisites
- **Node.js >= 20.19.0** - Check your version with `node --version`
#### Step 1: Install the CLI globally
**Option A: Using npm**
```bash
npm install -g @fission-ai/openspec@latest
```
Verify installation:
```bash
openspec --version
```
**Option B: Using Nix (NixOS and Nix package manager)**
Run OpenSpec directly without installation:
```bash
nix run github:Fission-AI/OpenSpec -- init
```
Or install to your profile:
```bash
nix profile install github:Fission-AI/OpenSpec
```
Or add to your development environment in `flake.nix`:
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
openspec.url = "github:Fission-AI/OpenSpec";
};
outputs = { nixpkgs, openspec, ... }: {
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
buildInputs = [ openspec.packages.x86_64-linux.default ];
};
};
}
```
Verify installation:
```bash
openspec --version
```
#### Step 2: Initialize OpenSpec in your project
Navigate to your project directory:
```bash
cd my-project
```
Run the initialization:
```bash
openspec init
```
**What happens during initialization:**
- You'll be prompted to pick any natively supported AI tools (Claude Code, CodeBuddy, Cursor, OpenCode, Qoder,etc.); other assistants always rely on the shared `AGENTS.md` stub
- OpenSpec automatically configures slash commands for the tools you choose and always writes a managed `AGENTS.md` hand-off at the project root
- A new `openspec/` directory structure is created in your project
**After setup:**
- Primary AI tools can trigger `/openspec` workflows without additional configuration
- Run `openspec list` to verify the setup and view any active changes
- If your coding assistant doesn't surface the new slash commands right away, restart it. Slash commands are loaded at startup,
so a fresh launch ensures they appear
### Optional: Populate Project Context
After `openspec init` completes, you'll receive a suggested prompt to help populate your project context:
```text
Populate your project context:
"Please read openspec/project.md and help me fill it out with details about my project, tech stack, and conventions"
```
Use `openspec/project.md` to define project-level conventions, standards, architectural patterns, and other guidelines that should be followed across all changes.
### Create Your First Change
Here's a real example showing the complete OpenSpec workflow. This works with any AI tool. Those with native slash commands will recognize the shortcuts automatically.
#### 1. Draft the Proposal
Start by asking your AI to create a change proposal:
```text
You: Create an OpenSpec change proposal for adding profile search filters by role and team
(Shortcut for tools with slash commands: /openspec:proposal Add profile search filters)
AI: I'll create an OpenSpec change proposal for profile filters.
*Scaffolds openspec/changes/add-profile-filters/ with proposal.md, tasks.md, spec deltas.*
```
#### 2. Verify & Review
Check that the change was created correctly and review the proposal:
```bash
$ openspec list # Confirm the change folder exists
$ openspec validate add-profile-filters # Validate spec formatting
$ openspec show add-profile-filters # Review proposal, tasks, and spec delta
```
#### 3. Refine the Specs
Iterate on the specifications until they match your needs:
```text
You: Can you add acceptance criteria for the role and team filters?
AI: I'll update the spec delta with scenarios for role and team filters.
*Edits openspec/changes/add-profile-filters/specs/profile/spec.md and tasks.md.*
```
#### 4. Implement the Change
Once specs look good, start implementation:
```text
You: The specs look good. Let's implement this change.
(Shortcut for tools with slash commands: /openspec:apply add-profile-filters)
AI: I'll work through the tasks in the add-profile-filters change.
*Implements tasks from openspec/changes/add-profile-filters/tasks.md*
*Marks tasks complete: Task 1.1 ✓, Task 1.2 ✓, Task 2.1 ✓...*
```
#### 5. Archive the Completed Change
After implementation is complete, archive the change:
```text
AI: All tasks are complete. The implementation is ready.
You: Please archive the change
(Shortcut for tools with slash commands: /openspec:archive add-profile-filters)
AI: I'll archive the add-profile-filters change.
*Runs: openspec archive add-profile-filters --yes*
✓ Change archived successfully. Specs updated. Ready for the next feature!
```
Or run the command yourself in terminal:
```bash
$ openspec archive add-profile-filters --yes # Archive the completed change without prompts
```
**Note:** Tools with native slash commands (Claude Code, CodeBuddy, Cursor, Codex, Qoder, RooCode) can use the shortcuts shown. All other tools work with natural language requests to "create an OpenSpec proposal", "apply the OpenSpec change", or "archive the change".
## Command Reference
```bash
openspec list # View active change folders
openspec view # Interactive dashboard of specs and changes
openspec show <change> # Display change details (proposal, tasks, spec updates)
openspec validate <change> # Check spec formatting and structure
openspec archive <change> [--yes|-y] # Move a completed change into archive/ (non-interactive with --yes)
```
## Example: How AI Creates OpenSpec Files
When you ask your AI assistant to "add two-factor authentication", it creates:
```
openspec/
├── specs/
│ └── auth/
│ └── spec.md # Current auth spec (if exists)
└── changes/
└── add-2fa/ # AI creates this entire structure
├── proposal.md # Why and what changes
├── tasks.md # Implementation checklist
├── design.md # Technical decisions (optional)
└── specs/
└── auth/
└── spec.md # Delta showing additions
```
### AI-Generated Spec (created in `openspec/specs/auth/spec.md`):
```markdown
# Auth Specification
## Purpose
Authentication and session management.
## Requirements
### Requirement: User Authentication
The system SHALL issue a JWT on successful login.
#### Scenario: Valid credentials
- WHEN a user submits valid credentials
- THEN a JWT is returned
```
### AI-Generated Change Delta (created in `openspec/changes/add-2fa/specs/auth/spec.md`):
```markdown
# Delta for Auth
## ADDED Requirements
### Requirement: Two-Factor Authentication
The system MUST require a second factor during login.
#### Scenario: OTP required
- WHEN a user submits valid credentials
- THEN an OTP challenge is required
```
### AI-Generated Tasks (created in `openspec/changes/add-2fa/tasks.md`):
```markdown
## 1. Database Setup
- [ ] 1.1 Add OTP secret column to users table
- [ ] 1.2 Create OTP verification logs table
## 2. Backend Implementation
- [ ] 2.1 Add OTP generation endpoint
- [ ] 2.2 Modify login flow to require OTP
- [ ] 2.3 Add OTP verification endpoint
## 3. Frontend Updates
- [ ] 3.1 Create OTP input component
- [ ] 3.2 Update login flow UI
```
**Important:** You don't create these files manually. Your AI assistant generates them based on your requirements and the existing codebase.
## Understanding OpenSpec Files
### Delta Format
Deltas are "patches" that show how specs change:
- **`## ADDED Requirements`** - New capabilities
- **`## MODIFIED Requirements`** - Changed behavior (include complete updated text)
- **`## REMOVED Requirements`** - Deprecated features
**Format requirements:**
- Use `### Requirement: <name>` for headers
- Every requirement needs at least one `#### Scenario:` block
- Use SHALL/MUST in requirement text
## How OpenSpec Compares
### vs. spec-kit
OpenSpec’s two-folder model (`openspec/specs/` for the current truth, `openspec/changes/` for proposed updates) keeps state and diffs separate. This scales when you modify existing features or touch multiple specs. spec-kit is strong for greenfield/0→1 but provides less structure for cross-spec updates and evolving features.
### vs. Kiro.dev
OpenSpec groups every change for a feature in one folder (`openspec/changes/feature-name/`), making it easy to track related specs, tasks, and designs together. Kiro spreads updates across multiple spec folders, which can make feature tracking harder.
### vs. No Specs
Without specs, AI coding assistants generate code from vague prompts, often missing requirements or adding unwanted features. OpenSpec brings predictability by agreeing on the desired behavior before any code is written.
## Team Adoption
1. **Initialize OpenSpec** – Run `openspec init` in your repo.
2. **Start with new features** – Ask your AI to capture upcoming work as change proposals.
3. **Grow incrementally** – Each change archives into living specs that document your system.
4. **Stay flexible** – Different teammates can use Claude Code, CodeBuddy, Cursor, or any AGENTS.md-compatible tool while sharing the same specs.
Run `openspec update` whenever someone switches tools so your agents pick up the latest instructions and slash-command bindings.
## Updating OpenSpec
1. **Upgrade the package**
```bash
npm install -g @fission-ai/openspec@latest
```
2. **Refresh agent instructions**
- Run `openspec update` inside each project to regenerate AI guidance and ensure the latest slash commands are active.
## Experimental Features
<details>
<summary><strong>🧪 OPSX: Fluid, Iterative Workflow</strong> (Claude Code only)</summary>
**Why this exists:**
- Standard workflow is locked down — you can't tweak instructions or customize
- When AI output is bad, you can't improve the prompts yourself
- Same workflow for everyone, no way to match how your team works
**What's different:**
- **Hackable** — edit templates and schemas yourself, test immediately, no rebuild
- **Granular** — each artifact has its own instructions, test and tweak individually
- **Customizable** — define your own workflows, artifacts, and dependencies
- **Fluid** — no phase gates, update any artifact anytime
```
You can always go back:
proposal ──→ specs ──→ design ──→ tasks ──→ implement
▲ ▲ ▲ │
└───────────┴──────────┴────────────────────┘
```
| Command | What it does |
|---------|--------------|
| `/opsx:new` | Start a new change |
| `/opsx:continue` | Create the next artifact (based on what's ready) |
| `/opsx:ff` | Fast-forward (all planning artifacts at once) |
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
| `/opsx:archive` | Archive when done |
**Setup:** `openspec experimental`
[Full documentation →](docs/opsx.md)
</details>
<details>
<summary><strong>Telemetry</strong> – OpenSpec collects anonymous usage stats (opt-out: <code>OPENSPEC_TELEMETRY=0</code>)</summary>
We collect only command names and version to understand usage patterns. No arguments, paths, content, or PII. Automatically disabled in CI.
**Opt-out:** `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`
</details>
## Contributing
- Install dependencies: `pnpm install`
- Build: `pnpm run build`
- Test: `pnpm test`
- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli`
- Conventional commits (one-line): `type(scope): subject`
<details>
<summary><strong>Maintainers & Advisors</strong></summary>
See [MAINTAINERS.md](MAINTAINERS.md) for the list of core maintainers and advisors who help guide the project.
</details>
## License
MIT
+846
View File
@@ -0,0 +1,846 @@
# Workspace POC Roadmap
## Goal
Deliver a lean but real Workspace POC that follows the intended user flow:
`workspace create` -> `workspace add-repo` -> `new change --targets` -> `workspace open --change` -> `apply --change --repo` -> workspace-aware `status` -> explicit workspace completion/archive.
The roadmap is deliberately execution-ordered. Early phases establish the entrypoint and filesystem model first, then add repo registration, then cross-repo planning, then execution handoff, then roll-up and completion semantics.
## POC Guardrails
- Centralize planning in the workspace, not canonical truth.
- Keep canonical specs in the owning repo.
- Keep repo-local execution repo-local.
- Reuse `change` as the primary user-facing primitive.
- Keep workspace metadata under `.openspec/` at the workspace root.
- Do not create an extra inner `openspec/` directory inside a dedicated workspace.
- Store stable aliases in committed workspace metadata and absolute paths only in the local overlay.
- Make repo attachment change-scoped, not workspace-wide.
- Reuse the workspace change ID when materializing repo-local changes.
- Start with create-only materialization unless a research phase explicitly chooses otherwise.
- Keep mocks narrow. Prefer real temp directories, real file IO, and real CLI execution.
## Testing Strategy
- Reuse the existing Vitest setup, `runCLI()` helper, and temp-directory pattern already used across the repo.
- Add one reusable `workspaceSandbox()` helper instead of many bespoke test setups.
- Add a small fixture set under `test/fixtures/workspace-poc/` and clone it into temp roots per test with `fs.cp` and `mkdtemp`.
- Add shared assertions for the core invariants: no nested `openspec/` under the workspace root; no absolute repo paths in committed files; materialized repo-local change IDs match workspace change IDs; change-scoped attach only includes targeted repos.
- Mock only prompt boundaries, telemetry, and agent-launch adapters. Do not mock filesystem behavior, path canonicalization, materialization logic, or status roll-up rules unless the test is specifically about an adapter boundary.
- Keep three reusable filesystem shapes: empty workspace sandbox, happy-path workspace with three repos, and dirty workspace with stale aliases, partial materialization, and incomplete tasks.
## Output Convention
Every phase writes a `SUMMARY.md` to its phase directory.
- Build and test phases write to `notes/workspace-poc/phase-XX-<slug>/SUMMARY.md`, `notes/workspace-poc/phase-XX-<slug>/VERIFY.md`, and `notes/workspace-poc/phase-XX-<slug>/MANUAL_TEST.md`
- Research phases write to `notes/workspace-poc/phase-XX-<slug>/SUMMARY.md`, `notes/workspace-poc/phase-XX-<slug>/DECISION.md`, `notes/workspace-poc/phase-XX-<slug>/VERIFY.md`, and `notes/workspace-poc/phase-XX-<slug>/MANUAL_TEST.md`
- Task and acceptance-check checkboxes are phase-scoped and numbered sequentially, for example `01.1`, `01.2`, `01.3`.
The summary should capture:
- what was changed
- what tests were run
- what passed or failed
- open issues for the next phase
The verification note should capture:
- what was independently checked in a fresh context
- what issues were found
- what fixes were applied
- what residual risks remain, if any
The manual test note should capture:
- what user-visible or smoke scenarios were exercised in a fresh context
- what passed or failed
- what fixes were applied
- what residual risks remain, if any
## Phase 00 - Testing Infrastructure Foundation
Type: Build
Usable outcome: A lean test harness exists for workspace work, so later phases can use real workspace and repo state without inventing new infrastructure each time.
Output summary directory: `notes/workspace-poc/phase-00-test-harness/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 00.1 Add `test/helpers/workspace-sandbox.ts` to create a temp managed workspace root plus attached repos.
- [x] 00.2 Add fixture seeds under `test/fixtures/workspace-poc/` for `empty`, `happy-path`, and `dirty`.
- [x] 00.3 Add shared assertion helpers for path leakage, workspace layout, target membership, and materialization invariants.
- [x] 00.4 Reserve test suite locations for new coverage: `test/core/workspace/`, `test/commands/workspace/`, and `test/cli-e2e/workspace/`.
- [x] 00.5 Keep the harness compatible with the current `runCLI()` helper and forked Vitest workers.
Acceptance tests:
- [x] 00.6 `workspaceSandbox()` creates a workspace root with `.openspec/` and `changes/`, and no inner `openspec/`.
- [x] 00.7 Cloned fixtures can be mutated independently without cross-test bleed.
- [x] 00.8 Committed fixture files never contain absolute repo paths.
- [x] 00.9 CLI tests can run against the sandbox and keep JSON output free of spinner noise.
## Phase 01 - Workspace Create Entrypoint
Type: Build
Usable outcome: A user can create a persistent workspace root through `openspec workspace create <name>`.
Output summary directory: `notes/workspace-poc/phase-01-workspace-create/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 01.1 Add the `workspace` command group and the `workspace create` entrypoint.
- [x] 01.2 Reuse the current init/setup path rather than inventing a second bootstrap system.
- [x] 01.3 Implement managed workspace root creation.
- [x] 01.4 Create `.openspec/workspace.yaml`, `.openspec/local.yaml`, and top-level `changes/`.
- [x] 01.5 Ensure `.openspec/local.yaml` is treated as local-only state.
- [x] 01.6 Make the created layout clearly distinct from repo-local `openspec/` roots.
Acceptance tests:
- [x] 01.7 Creating a workspace produces `.openspec/workspace.yaml`, `.openspec/local.yaml`, and `changes/`.
- [x] 01.8 The workspace root does not contain `openspec/changes`.
- [x] 01.9 Re-running against an existing workspace fails or behaves idempotently in one explicit, documented way.
- [x] 01.10 Invalid or duplicate workspace names fail with actionable errors.
## Phase 02 - Validate Workspace Create
Type: Test
Usable outcome: `workspace create` is covered at unit, command, and CLI layers before other workspace behavior builds on it.
Output summary directory: `notes/workspace-poc/phase-02-test-workspace-create/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 02.1 Add unit tests for managed path resolution and workspace metadata initialization.
- [x] 02.2 Add command-level tests for create behavior and failure modes.
- [x] 02.3 Add CLI e2e coverage for `workspace create`, help text, exit codes, and layout assertions.
Acceptance tests:
- [x] 02.4 Help output documents `workspace create`.
- [x] 02.5 Successful CLI creation yields a usable workspace root on disk.
- [x] 02.6 JSON output remains clean if a machine-readable mode is added.
- [x] 02.7 Duplicate create attempts do not corrupt the workspace root.
## Phase 03 - Repo Registry and Doctor
Type: Build
Usable outcome: A workspace can register repo aliases and validate them with `workspace add-repo` and `workspace doctor`.
Output summary directory: `notes/workspace-poc/phase-03-repo-registry/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 03.1 Implement committed alias storage in `.openspec/workspace.yaml`.
- [x] 03.2 Implement absolute path storage in `.openspec/local.yaml`.
- [x] 03.3 Validate that registered paths exist and contain repo-local OpenSpec state.
- [x] 03.4 Canonicalize stored local paths.
- [x] 03.5 Implement `workspace doctor` to check alias resolution, missing repos, and overlay drift.
Acceptance tests:
- [x] 03.6 `workspace add-repo <alias> <path>` stores the alias in committed metadata and the path only in local metadata.
- [x] 03.7 Missing paths and duplicate aliases fail cleanly.
- [x] 03.8 Paths are canonicalized before persistence.
- [x] 03.9 `workspace doctor` reports stale or missing repos without mutating state.
- [x] 03.10 No absolute path leaks into committed workspace files.
## Phase 04 - Validate Repo Registry and Doctor
Type: Test
Usable outcome: Repo registration becomes trustworthy enough for targeted changes and later agent attachment.
Output summary directory: `notes/workspace-poc/phase-04-test-repo-registry/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 04.1 Add pure tests for alias parsing, path canonicalization, committed-vs-local serialization, and doctor diagnostics.
- [x] 04.2 Add command tests for add-repo and doctor using the workspace sandbox.
- [x] 04.3 Add CLI e2e coverage for happy path and stale path scenarios.
Acceptance tests:
- [x] 04.4 Doctor detects missing repo roots, missing `openspec/`, and alias/path drift.
- [x] 04.5 Committed metadata remains stable across local path changes.
- [x] 04.6 Repairing a stale path in `local.yaml` restores doctor success.
- [x] 04.7 The registry remains readable after multiple repo additions in one workspace.
## Phase 05 - Target-Aware Workspace Change Creation
Type: Build
Usable outcome: A workspace can create a central cross-repo change with `openspec new change <id> --targets <a,b,c>`.
Output summary directory: `notes/workspace-poc/phase-05-targeted-change-create/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 05.1 Extend change creation to support workspace topology.
- [x] 05.2 Record explicit targets in workspace change metadata.
- [x] 05.3 Scaffold central planning artifacts in the workspace change: proposal, design, coordination tasks, and per-target draft task/spec partitions.
- [x] 05.4 Hard-fail if a requested target alias is unknown.
- [x] 05.5 Ensure no repo-local artifacts are created yet.
Acceptance tests:
- [x] 05.6 Creating a targeted workspace change records the exact target set.
- [x] 05.7 Per-target planning directories are created under the workspace change.
- [x] 05.8 Unknown or duplicate targets fail with actionable errors.
- [x] 05.9 Repo-local repos remain untouched until `apply`.
- [x] 05.10 Duplicate change IDs still fail predictably.
## Phase 06 - Validate Target-Aware Change Creation
Type: Test
Usable outcome: The central planning object is stable before any agent-open or materialization work begins.
Output summary directory: `notes/workspace-poc/phase-06-test-targeted-change-create/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 06.1 Add unit tests for target parsing and workspace change metadata rules.
- [x] 06.2 Add command tests for targeted change creation against a registered workspace.
- [x] 06.3 Add CLI e2e coverage for successful creation, unknown aliases, and untouched repo-local roots.
Acceptance tests:
- [x] 06.4 `new change --targets` rejects aliases not present in the workspace registry.
- [x] 06.5 The workspace change layout matches the chosen topology.
- [x] 06.6 The workspace change contains central planning artifacts and per-target partitions only.
- [x] 06.7 Running status or doctor after creation still sees the workspace as healthy.
## Phase 07 - Research Minimum `workspace open` Contract
Type: Research
Usable outcome: The team decides the smallest honest v0 behavior for `workspace open --change` without overcommitting to multi-root agent support that may not be real.
Output summary directory: `notes/workspace-poc/phase-07-open-contract-research/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 07.1 Write the research note in `notes/workspace-poc/phase-07-open-contract-research/DECISION.md`.
- [x] 07.2 Decide the minimum v0 behavior for planning-only mode, change-scoped attached mode, supported agent targets for the demo path, and failure behavior when one or more targeted repos are unresolved.
- [x] 07.3 Choose whether non-primary agents are supported, partial, or explicitly out of scope in v0.
Acceptance tests:
- [x] 07.4 The research note names one recommended contract and at least one rejected alternative.
- [x] 07.5 The note defines exact user-visible behavior for `workspace open --change <id>` and `workspace open` with no change.
- [x] 07.6 The note lists testable success and failure cases for the next phase.
## Phase 08 - Workspace Open
Type: Build
Usable outcome: A user can open the workspace in planning-only mode or open a specific change with only its target repos attached.
Output summary directory: `notes/workspace-poc/phase-08-workspace-open/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 08.1 Implement `workspace open --change <id> [--agent <tool>]`.
- [x] 08.2 Implement planning-only mode when no change is supplied.
- [x] 08.3 Ensure change-scoped open resolves only the change’s targeted repos.
- [x] 08.4 Integrate with the existing command-generation/tooling path rather than inventing a new one.
- [x] 08.5 Fail with actionable diagnostics when targeted repos are unresolved.
Acceptance tests:
- [x] 08.6 `workspace open` without `--change` does not attach repo roots.
- [x] 08.7 `workspace open --change <id>` attaches only targeted repos, not all registered repos.
- [x] 08.8 Open fails clearly when a targeted repo path is stale or missing.
- [x] 08.9 The chosen primary agent path produces a usable session launch or instruction surface.
## Phase 09 - Validate Workspace Open
Type: Test
Usable outcome: The open contract is pinned down with real fixture state before materialization depends on it.
Output summary directory: `notes/workspace-poc/phase-09-test-workspace-open/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 09.1 Add tests for planning-only vs change-scoped mode.
- [x] 09.2 Add tests that verify only the expected repo aliases are attached.
- [x] 09.3 Add tests for unresolved target paths and unsupported agent/tool combinations.
- [x] 09.4 Add CLI e2e coverage for the selected primary demo path.
Acceptance tests:
- [x] 09.5 Planning-only open never exposes attached repo roots.
- [x] 09.6 Change-scoped open never attaches unrelated repos.
- [x] 09.7 Open diagnostics point to `workspace doctor` or the alias that needs repair.
- [x] 09.8 Test coverage does not depend on real multi-root writes.
## Phase 10 - Research Materialization Contract
Type: Research
Usable outcome: The materialization contract is explicit before `apply --change --repo` is implemented.
Output summary directory: `notes/workspace-poc/phase-10-materialization-contract-research/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 10.1 Write the research note in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
- [x] 10.2 Decide the v0 rule for create-only vs refresh, overwrite behavior, rerun behavior, conflict handling, and the minimum metadata written during materialization.
- [x] 10.3 Prefer the simplest honest contract for the POC, even if refresh is deferred.
Acceptance tests:
- [x] 10.4 The research note chooses one v0 contract and names explicit non-goals.
- [x] 10.5 The note defines what counts as a successful materialization.
- [x] 10.6 The note defines the expected behavior for repeat `apply` calls.
## Phase 11 - Target Materialization via `apply`
Type: Build
Usable outcome: A selected target can be materialized into its repo with `openspec apply --change <id> --repo <alias>`.
Output summary directory: `notes/workspace-poc/phase-11-apply-materialization/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 11.1 Extend `apply` to understand workspace topology.
- [x] 11.2 Materialize only the selected target slice into the target repo.
- [x] 11.3 Reuse the same change ID in the target repo.
- [x] 11.4 Keep workspace planning artifacts intact after materialization.
- [x] 11.5 Make the authority handoff explicit: workspace draft before `apply`, repo-local execution after `apply`.
- [x] 11.6 Write the minimum trace metadata needed for later status roll-up.
Acceptance tests:
- [x] 11.7 Materialization creates a repo-local change with the same change ID.
- [x] 11.8 Only the selected target repo is modified.
- [x] 11.9 Untargeted aliases and unknown aliases fail clearly.
- [x] 11.10 Repeating `apply` follows the v0 contract from Phase 10.
- [x] 11.11 Workspace drafts remain intact after successful materialization.
## Phase 12 - Validate Materialization
Type: Test
Usable outcome: The execution handoff is proven against real repos before status and completion semantics are layered on top.
Output summary directory: `notes/workspace-poc/phase-12-test-apply-materialization/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 12.1 Add unit tests for materialization plan construction and target resolution.
- [x] 12.2 Add command tests for apply success, apply failure, and repeat-apply behavior.
- [x] 12.3 Add CLI e2e coverage for selective materialization into one repo out of many.
- [x] 12.4 Add dirty-workspace coverage for stale aliases and pre-existing target change collisions.
Acceptance tests:
- [x] 12.5 The repo-local change ID exactly matches the workspace change ID.
- [x] 12.6 Apply never writes to repos outside the selected alias.
- [x] 12.7 Apply surfaces collisions and stale-path failures without partial silent success.
- [x] 12.8 The happy-path fixture supports `create -> add-repo -> new change -> apply`.
## Phase 13 - Research Status Roll-Up and Reverse Links
Type: Research
Usable outcome: Status semantics are concrete enough to implement without inventing misleading lifecycle labels.
Output summary directory: `notes/workspace-poc/phase-13-status-research/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 13.1 Write the research note in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
- [x] 13.2 Define the minimum v0 workspace states and their derivation rules: planned, materialized, in progress, blocked, complete, soft-done, and hard-done.
- [x] 13.3 Decide whether repo-local changes need reverse links back to the workspace change in v0.
- [x] 13.4 Define the minimum JSON status shape that tests can lock down.
Acceptance tests:
- [x] 13.5 The research note gives one precise derivation rule per state.
- [x] 13.6 The note defines which states rely on repo-local inspection and which rely on workspace state alone.
- [x] 13.7 The note resolves whether reverse links are required, optional, or deferred.
## Phase 14 - Workspace Status Roll-Up
Type: Build
Usable outcome: Running status from the workspace tells the user what is planned, materialized, active, blocked, complete, soft-done, and hard-done.
Output summary directory: `notes/workspace-poc/phase-14-workspace-status/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 14.1 Extend status behavior to recognize workspace topology.
- [x] 14.2 Roll up central coordination state plus per-target execution state.
- [x] 14.3 Keep output honest and minimal.
- [x] 14.4 Add stable JSON output for workspace status.
- [x] 14.5 Do not infer more than the underlying workspace and repo-local state can actually support.
Acceptance tests:
- [x] 14.6 Workspace status distinguishes planning-only targets from materialized targets.
- [x] 14.7 Status can report blocked states for stale repo paths or missing materializations when appropriate.
- [x] 14.8 Soft-done only appears when all known coordination and target work is complete.
- [x] 14.9 Hard-done only appears after explicit workspace archive/completion in a later phase.
- [x] 14.10 JSON status output is stable and free of spinner contamination.
## Phase 15 - Validate Workspace Status
Type: Test
Usable outcome: Roll-up semantics are verified with deterministic scenarios rather than manual interpretation.
Output summary directory: `notes/workspace-poc/phase-15-test-workspace-status/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 15.1 Add pure tests for state derivation logic.
- [x] 15.2 Add command tests for workspace-aware status output.
- [x] 15.3 Add CLI e2e coverage for mixed states across three repos.
- [x] 15.4 Add regression tests for JSON shape and spinner-free output.
Acceptance tests:
- [x] 15.5 Status correctly reports a mix of planned, materialized, archived, and blocked targets in one workspace.
- [x] 15.6 Status remains readable when one repo is missing or stale.
- [x] 15.7 JSON output can be parsed directly by an agent or automation.
- [x] 15.8 The dirty fixture supports interruption and resume scenarios.
## Phase 16 - Workspace Completion and Archive Semantics
Type: Build
Usable outcome: The workspace has an explicit top-level completion/hard-done path while repo-local archive remains repo-local.
Output summary directory: `notes/workspace-poc/phase-16-workspace-archive/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 16.1 Decide the minimal command path for explicit workspace completion/archive using the existing archive surface where practical.
- [x] 16.2 Preserve repo-local archive behavior and canonical spec ownership.
- [x] 16.3 Ensure top-level hard-done is explicit and never implied by repo-local activity alone.
- [x] 16.4 Record enough workspace-level completion state for status to report hard-done.
Acceptance tests:
- [x] 16.5 Archiving a repo-local change does not automatically archive the workspace change.
- [x] 16.6 Workspace hard-done requires explicit top-level user action.
- [x] 16.7 Repo-local archive continues to operate against repo-local canonical specs.
- [x] 16.8 Mixed repo cadences are allowed without invalidating workspace state.
## Phase 17 - Validate Workspace Completion and Archive
Type: Test
Usable outcome: Completion semantics are proven and do not collapse repo ownership boundaries.
Output summary directory: `notes/workspace-poc/phase-17-test-workspace-archive/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 17.1 Add command and CLI tests for workspace hard-done behavior.
- [x] 17.2 Add tests for partial repo archive, staggered repo archive, and explicit workspace archive.
- [x] 17.3 Add regression tests to ensure repo-local archive behavior is unchanged outside workspace flows.
Acceptance tests:
- [x] 17.4 One repo can archive while another remains in progress without forcing top-level done.
- [x] 17.5 Status shows soft-done before hard-done when the documented conditions are met.
- [x] 17.6 Existing repo-local archive tests still pass without workspace regressions.
## Phase 18 - Deferred Research: Shared-Contract Promotion and Stable IDs
Type: Research
Usable outcome: Deferred questions are captured cleanly without bloating the POC implementation.
Output summary directory: `notes/workspace-poc/phase-18-deferred-research/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 18.1 Write the research note in `notes/workspace-poc/phase-18-deferred-research/DECISION.md`.
- [x] 18.2 Capture the recommended next-step design for shared-contract promotion into canonical owner repos, migration from local alias/path overlays to stable project IDs, and whether any team-shared workspace semantics should exist after the POC.
- [x] 18.3 Keep this phase explicitly non-blocking for the working POC.
Acceptance tests:
- [x] 18.4 The research note separates deferred concerns from the shipped POC contract.
- [x] 18.5 The note identifies which future changes would break current tests or fixture shape.
- [x] 18.6 The note names at least one migration seam that preserves backward compatibility.
## Phase 19 - End-to-End POC Acceptance
Type: Test
Usable outcome: The whole POC is proven with a small number of realistic, repeatable scenarios.
Output summary directory: `notes/workspace-poc/phase-19-e2e-acceptance/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 19.1 Add one golden happy-path e2e scenario covering: create workspace, register three repos, create one targeted change, open the change, materialize one repo, inspect status, archive repo-local work, and explicitly complete/archive the workspace.
- [x] 19.2 Add one interruption/re-entry scenario covering: an existing workspace, one materialized target, one stale target, and status/doctor output that points to the next action.
- [x] 19.3 Add one failure-recovery scenario covering: duplicate aliases, unknown targets, repeat apply, stale repo paths, and partial completion.
Acceptance tests:
- [x] 19.4 The happy-path scenario can run end-to-end with real filesystem state and no broad mocks.
- [x] 19.5 The interruption scenario can be resumed without reconstructing context manually.
- [x] 19.6 The failure-recovery scenario produces actionable errors and no silent corruption.
- [x] 19.7 The final suite demonstrates the product promise: plan centrally, execute locally, preserve repo ownership.
## Phase 20 - PRD Satisfaction Audit
Type: Test
Usable outcome: The implementation is checked directly against `WORKSPACE_POC_PRD.md` rather than only against the roadmap or inferred intent.
Output summary directory: `notes/workspace-poc/phase-20-prd-audit/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 20.1 Compare the full implementation, docs, tests, and user-facing behavior against `WORKSPACE_POC_PRD.md`.
- [x] 20.2 Identify every unmet, partially met, or ambiguous PRD requirement.
- [x] 20.3 Validate that the implementation still respects the key guardrails from the PRD and decision record.
- [x] 20.4 If any PRD gaps remain, insert concrete remediation phases immediately after this phase, each with acceptance tests and output directories, before allowing final signoff to proceed.
Acceptance tests:
- [x] 20.5 Every meaningful PRD requirement is mapped to implemented behavior, explicit non-goal, or a documented gap.
- [x] 20.6 Any remaining gaps result in newly inserted remediation phases, not a vague TODO list.
- [x] 20.7 The audit output is concrete enough for a fresh agent session to act on immediately.
## Phase 21 - Workspace Guidance and Owner Visibility
Type: Build
Usable outcome: A fresh user can tell when workspace mode fits the job, capture owner or handoff information per repo, and see that information from the existing workspace surfaces.
Output summary directory: `notes/workspace-poc/phase-21-workspace-guidance-and-owners/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 21.1 Extend committed workspace repo metadata to capture optional owner or handoff information without storing machine-specific paths.
- [x] 21.2 Add a backward-compatible CLI path to record or update owner or handoff information for a registered repo alias.
- [x] 21.3 Surface owner or handoff information anywhere the workspace already shows affected repos and next actions, at minimum workspace-aware `status` and `workspace open`.
- [x] 21.4 Add shipped user-facing guidance that explains when to use workspace mode versus stay repo-local, the supported end-to-end CLI flow, and how to re-enter or hand off an in-flight workspace change.
Acceptance tests:
- [x] 21.5 Fresh users can discover from shipped docs or help when workspace mode is the right tool and what the supported CLI flow is.
- [x] 21.6 When owner or handoff information is configured, workspace status and open surfaces expose it without leaking local paths into committed metadata.
- [x] 21.7 Existing workspaces remain valid and readable when owner or handoff information is absent.
## Phase 22 - Validate Guidance and Owner Visibility
Type: Test
Usable outcome: Guidance and owner or handoff visibility are proven on real workspace state and remain backward-compatible with the shipped POC.
Output summary directory: `notes/workspace-poc/phase-22-test-workspace-guidance-and-owners/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 22.1 Add unit, command, and CLI coverage for owner or handoff metadata plus the updated docs or help surface.
- [x] 22.2 Verify older workspace fixtures and workspaces without owner or handoff metadata still pass unchanged.
- [x] 22.3 Run manual CLI checks for docs or help, `workspace open`, and workspace-aware `status` from a fresh workspace.
Acceptance tests:
- [x] 22.4 Shipped docs or help no longer require the PRD or roadmap to explain when workspace mode is appropriate.
- [x] 22.5 Workspace text and JSON surfaces show configured owner or handoff information consistently.
- [x] 22.6 Existing ownerless workspaces and the Phase 19 acceptance flow continue to pass.
## Phase 23 - Workspace Target Set Adjustment
Type: Build
Usable outcome: Users can adjust the target set on a workspace change after creation without manual file edits or silent authority drift.
Output summary directory: `notes/workspace-poc/phase-23-workspace-target-set-adjustment/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 23.1 Add a minimal explicit command path to add or remove target aliases from an existing workspace change.
- [x] 23.2 Keep workspace change metadata, per-target draft artifacts, and workspace registry validation coherent when targets are added or removed.
- [x] 23.3 Define and implement safe guardrails for removing a target that has already been materialized or otherwise moved into repo-local execution.
- [x] 23.4 Update workspace `open`, `apply`, and workspace-aware `status` to respect the adjusted target set.
Acceptance tests:
- [x] 23.5 Adding a target updates the workspace change metadata and scaffolds the new per-target draft slice.
- [x] 23.6 Removing an unmaterialized target updates the workspace cleanly without corrupting other targets.
- [x] 23.7 Removing or mutating a materialized target fails or requires an explicit documented safety path instead of silently breaking authority handoff.
## Phase 24 - Validate Target Set Adjustment
Type: Test
Usable outcome: Target-set edits behave safely under real workspace conditions and do not regress the shipped POC flow.
Output summary directory: `notes/workspace-poc/phase-24-test-workspace-target-set-adjustment/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 24.1 Add unit, command, and CLI coverage for target-add and target-remove behavior, including materialized-target guardrails.
- [x] 24.2 Run manual re-entry, `status`, `workspace open`, and `apply` checks after target-set edits in a fresh workspace.
- [x] 24.3 Re-run the workspace acceptance slice to confirm target adjustment does not regress the existing happy path or interruption flow.
Acceptance tests:
- [x] 24.4 Adjusted target sets are reflected consistently in workspace metadata, `workspace open`, `apply`, and workspace-aware `status`.
- [x] 24.5 Guardrails prevent silent divergence for already materialized targets.
- [x] 24.6 The existing Phase 19 acceptance scenario still passes after target-set support lands.
## Phase 25 - Final PRD Recheck and Signoff
Type: Test
Usable outcome: After any remediation phases have run, the codebase is rechecked against the PRD and the POC can be considered complete.
Output summary directory: `notes/workspace-poc/phase-25-prd-signoff/`
Completion checklist:
- [x] Tasks completed
- [x] Acceptance tests satisfied
- [x] Independent verification complete
- [x] Manual testing complete
- [x] Phase complete
Tasks:
- [x] 25.1 Re-run the PRD satisfaction check after all remediation phases are complete.
- [x] 25.2 Confirm the final implementation, documentation, and tests satisfy the PRD.
- [x] 25.3 Confirm the roadmap itself has no incomplete required phases left behind.
- [x] 25.4 Produce a final signoff summary that states whether the POC is complete and what residual risks remain.
Acceptance tests:
- [x] 25.5 The final signoff references `WORKSPACE_POC_PRD.md` directly and confirms whether it is satisfied.
- [x] 25.6 If the PRD is still not satisfied, the phase does not sign off and instead inserts further remediation phases before trying again.
- [x] 25.7 The final signoff is explicit about any residual risks, but it does not leave known fixable PRD gaps unresolved.
## Recommended First Shipping Slice
If the POC needs the smallest credible milestone before full roll-up and completion semantics, ship through Phase 12:
- test harness
- workspace create
- repo registry + doctor
- targeted workspace changes
- minimum researched `workspace open`
- create-only materialization through `apply`
That is the first point where the product is honest for real cross-repo work. Phases 13 through 25 then harden status, completion semantics, end-to-end resilience, PRD completeness, and final signoff.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+293
View File
@@ -0,0 +1,293 @@
# Workspace POC PRD
- Status: Signed Off
- Date: 2026-04-17
- Audience: OpenSpec maintainers and future implementers
- Derived from: [WORKSPACE_POC_DECISION_RECORD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_DECISION_RECORD.md)
## Summary
The Workspace POC gives OpenSpec a lightweight way to coordinate work that spans multiple repositories without forcing planning into a single repo or introducing a separate planning primitive for users to learn.
A workspace is a persistent coordination home. Inside it, users create feature-scoped changes, plan the work once, and then materialize repo-specific execution artifacts into the affected repos when implementation is ready to begin.
The POC is intentionally opinionated:
- planning is centralized in the workspace
- canonical specs remain in the owning repo
- repo-local execution remains repo-local
- the primary user-facing primitive stays `change`
- the existing `spec-driven` methodology is reused rather than forked into a separate workspace schema
This document describes what we are building for the POC. It does not try to break the work into implementation phases yet.
## Problem
OpenSpec currently behaves like a single-root tool:
- commands assume one local root
- changes are authored locally under one repo
- specs and delta specs are resolved locally
- `apply` and `archive` are repo-local lifecycle steps
That works for normal single-repo use, but it breaks down when one feature spans multiple services, clients, or owner repos.
Users need one place to:
- write a single proposal and design
- see the full cross-repo change
- assign and track repo-specific work
- reason about shared behavior across repos
At the same time, repos still need to remain the source of truth for:
- canonical specs
- implementation work
- review and shipping
- archive semantics
The product problem is to provide centralized planning without collapsing repo ownership.
## Who This Is For
The POC is aimed at users coordinating cross-boundary work, including:
- an engineer changing behavior across multiple repos
- a lead or staff engineer coordinating a feature across teams
- a team that needs one planning surface but still executes in separate repos
## When Users Reach For Workspace
Users should reach for a workspace when repo-local OpenSpec stops being an honest representation of the work.
Typical trigger situations:
- one feature spans two or more repos
- the canonical spec owner is different from one or more implementation repos
- different repos or teams need to move on different cadences
- one person needs to coordinate work that will later be handed off to several repo owners
- the user needs one place to pause and resume a cross-repo effort without reconstructing the full plan from scattered notes
## Jobs To Be Done
### Functional Jobs
Users hire the workspace POC to:
- start one cross-repo change from a neutral planning home
- identify which repos are affected
- author shared planning artifacts once
- break the work into repo-specific slices for execution
- materialize repo-local change artifacts when implementation should begin
- track overall progress without losing repo ownership boundaries
- resume a cross-repo change later and quickly understand what is planned, materialized, in progress, blocked, complete, or archived
### Social Jobs
Users also hire the workspace POC to:
- make the full cross-repo change legible to repo owners, reviewers, and leads
- hand off the right slice of work to each repo owner without duplicating planning docs
- show what is planned centrally versus what is already executing locally
- reduce coordination overhead that would otherwise live in Slack threads, meetings, and ad hoc documents
### Emotional Jobs
The workspace POC should help users feel confident that:
- there is one clear planning home for the overall change
- canonical repo ownership is preserved
- materialization will not create confusing dual authority
- they can tell what is authoritative at each step
- they can recover safely from interruption, partial rollout, or divergence between workspace drafts and repo-local execution
### Adoption And Operations Jobs
For teams using this repeatedly, the workspace POC should also support:
- a repeatable way to start cross-repo work
- a clear way to decide when to use workspace mode versus stay repo-local
- onboarding another engineer into an in-flight cross-repo change
- re-entering an existing workspace after time away
- adjusting targets and continuing even when some repos are not ready at the same time
## Product Goals
The Workspace POC should:
1. Provide a credible cross-repo coordination experience for real work.
2. Make the workspace a persistent coordination home rather than a disposable feature folder.
3. Keep planning centralized while preserving canonical spec ownership in repos.
4. Reuse the existing `change` primitive and `spec-driven` methodology.
5. Minimize disruption to existing repo-local OpenSpec workflows.
6. Support a simple, explicit CLI flow for creating workspaces, registering repos, opening a change, and materializing repo-local work.
7. Avoid leaking machine-specific repo paths into committed workspace state.
## Non-Goals
The POC does not attempt to solve the full long-term workspace model.
Out of scope:
- a fully multi-root-aware CLI across every command
- a new top-level `initiative` primitive
- a separate workspace-only methodology schema
- stable remote repo identifiers or shared project IDs
- automatic escalation from local work into a workspace
- a full sync engine between workspace drafts and repo-local changes
- final governance for shared-contract ownership
- arbitrary user-chosen workspace locations as the default v0 behavior
## Product Shape
### Workspace
A workspace is a persistent coordination root used for cross-repo planning.
For the POC:
- it lives in a managed location by default
- workspace metadata lives under `.openspec/`
- the workspace does not add an extra inner `openspec/` directory
- the workspace can contain many feature-scoped changes over time
### Workspace Change
A workspace change is the central planning object for one cross-repo feature or initiative-sized piece of work.
For the POC:
- users still think in terms of `change`
- a workspace change records its target repos explicitly
- proposal, design, coordination tasks, and per-target draft work live in the workspace until materialization
### Target Repos
Target repos are registered in the workspace by alias.
For the POC:
- stable repo aliases are stored in committed workspace metadata
- machine-specific absolute paths are stored only in a gitignored local overlay
- repo attachment should be change-scoped by default, not workspace-wide
### Repo-Local Changes
Repo-local changes are the execution artifacts created from a workspace change.
For the POC:
- a materialized repo-local change reuses the same change ID as the workspace change by default
- repo-local execution remains local to that repo
- repo-local archive remains local to that repo
## Core Principles
### Centralize The View, Not The Truth
The workspace is the shared planning surface. It is not the permanent home of canonical specs or repo execution state.
### Methodology And Topology Stay Separate
The POC reuses `spec-driven`. Workspace behavior is a topology concern, not a new methodology family.
### Planning First, Materialization Second
Users should be able to author the cross-repo plan in one place before copying the relevant slice into a repo for execution.
### Clear Authority Handoff
Before materialization, the workspace target slice is the planning truth for that repo.
After a successful `apply --change <id> --repo <alias>`, the repo-local change becomes the execution truth for that repo.
### Manual Completion At The Top Level
A workspace change becomes:
- soft-done when all known coordination work and tracked target work are complete
- hard-done only when the user manually archives the workspace change
## User Experience
The intended POC flow is:
1. A user creates a workspace using the normal OpenSpec setup path.
2. The user registers repo aliases against local repo paths.
3. The user creates a workspace change with explicit targets.
4. Planning happens centrally in the workspace:
- proposal
- design
- coordination tasks
- per-target draft tasks
- per-target draft delta specs
5. When execution should begin in a repo, the user runs `openspec apply --change <id> --repo <alias>`.
6. OpenSpec materializes the selected repo’s local change using the same change ID.
7. Repo-local implementation and archive proceed in that repo.
8. The workspace continues to show overall coordination and completion state.
This is meant to feel like one change with multiple execution surfaces, not like separate unrelated changes stitched together manually.
## POC Command Surface
The minimum command shape for the POC is:
- `openspec workspace create <name>`
- `openspec workspace add-repo <alias> <path>`
- `openspec workspace doctor`
- `openspec new change <id> --targets <a,b,c>`
- `openspec workspace open --change <id> [--agent <tool>]`
- `openspec apply --change <id> --repo <alias>`
These commands are enough to support:
- persistent workspace creation
- repo registration and validation
- explicit targeted change creation
- change-scoped agent opening
- deterministic materialization into a target repo
## Agent Story
The POC should optimize for the cleanest demo path rather than promise identical behavior across all tools.
Current expectation:
- Claude Code is the headline multi-root demo path
- Codex is secondary if it remains straightforward
- Copilot is partial or manual support, not the primary story
Because agent multi-root write behavior is uneven, `openspec apply --change --repo` is the safest POC default for moving from planning into repo execution.
## Success Criteria
The POC is successful if users can:
- recognize when workspace mode is the right tool for the job
- create one canonical plan for a cross-repo change without forcing it into a dishonest home repo
- identify affected repos, owners, and next actions from one planning surface
- hand off repo-specific work cleanly without duplicating the same plan across multiple repos or side documents
- understand which work is planned, materialized, in progress, blocked, complete, and archived
- resume an interrupted cross-repo change without reconstructing context from Slack, PRs, or notes
- preserve canonical spec ownership in repos while still coordinating the overall effort centrally
- trust what is authoritative at each stage of the workflow
- avoid committing local absolute repo paths into shared state
## Open Questions
These are intentionally left open for roadmap and implementation planning:
- Should materialization be create-only at first, or support explicit refresh?
- If re-materialization exists, what can be overwritten and what must be preserved?
- How should workspace status roll up repo-local progress?
- Should repo-local changes keep a reverse link back to the workspace change?
- What is the minimum supported `workspace open --change` behavior in v0?
- How should shared contract drafts be promoted into canonical owner repos?
## Appendix: Working Mental Model
The POC is built around one simple idea:
> Plan centrally, execute locally, preserve repo ownership.
That is the product promise the roadmap should now flesh out.
+454
View File
@@ -0,0 +1,454 @@
# Workspace Reimplementation Direction
Date: 2026-04-30
This document captures the intended direction for reimplementing OpenSpec workspace support from scratch, based on what we learned from the workspace POC.
The reimplementation should be ordered around the path a real user takes through OpenSpec:
```text
create workspace
-> add repos
-> open workspace
-> explore across repos
-> 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 create an OpenSpec workspace.
I open it with my agent.
The agent can see the registered repos.
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 workspace overlays.
I need to manage target metadata separately from proposal files.
```
The core product rule is:
```text
Repository visibility is not change commitment.
```
Registered repos are the workspace working set. Creating a change is a planning commitment. Applying a change is an implementation workflow.
## Build Order
### 1. Workspace Creation
First make workspace creation boring and solid.
User goal:
```text
Create a place where cross-repo planning lives.
```
Expected surface:
```bash
openspec workspace create my-workspace
openspec workspace add-repo openspec /path/to/openspec
openspec workspace add-repo landing /path/to/openspec-landing
```
Expected outcome:
```text
workspace/
AGENTS.md
changes/
.openspec-workspace/
```
Product decisions:
- Use `.openspec-workspace/`, not `.openspec/`, for workspace metadata.
- Keep `changes/` visible at the workspace root.
- Treat registered repos as the workspace working set.
- Make `doctor` show human-readable repo names and resolved paths.
Defer:
- Branches.
- Worktrees.
- Apply.
- Archive.
- Complex target lifecycle.
Done when a user can create a workspace, register repos, and run `doctor` to see exactly what OpenSpec knows.
### 2. Workspace Open
Next make the workspace openable in the way users expect.
User goal:
```text
Open this multi-repo working set 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 registered repos.
- 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 root
registered repo A
registered repo B
```
For Claude and Codex, attach the registered repo 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 registered repos.
### 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 registered repos, but do not implement yet.
```
Agent behavior:
- Understand it is in workspace mode.
- Inspect registered repos.
- 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.
- Registered repo 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 create
-> 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 create the workspace?
2. Can I see my repos?
3. Can my agent explore them?
4. Can we capture a proposal?
5. Can status tell us if it is ready?
6. Can the agent implement one repo slice?
7. Can we verify it?
8. Can we archive it?
```
Avoid starting with internal abstractions unless they are required for the next user-visible capability.
Do not start with:
- Target metadata machinery.
- Materialization.
- Adapter abstractions.
- Branch orchestration.
- Worktree orchestration.
- Multi-repo apply.
Those may matter later, but they should not define the first reimplementation path.
## Product Shape
The workspace should feel like OpenSpec's normal workflow stretched across multiple repos, not a second product with its own lifecycle.
The durable product model is:
```text
workspace = central planning source of truth
registered repos = visible working set
proposal = scoped planning commitment
repo target = one affected repo in the plan
branch/worktree = implementation checkout
/apply = implement one selected repo slice
```
Keep the user journey simple:
```text
Open the workspace.
Ask the agent to explore.
Create the proposal when scope is clear.
Implement one repo slice at a time.
Verify.
Archive.
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

+89
View File
@@ -0,0 +1,89 @@
<svg width="640" height="80" viewBox="0 0 640 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M32 0H16V16H32V0Z" fill="white"/>
<path d="M48 0H32V16H48V0Z" fill="white"/>
<path d="M16 16H0V32H16V16Z" fill="white"/>
<path d="M64 16H48V32H64V16Z" fill="white"/>
<path d="M16 32H0V48H16V32Z" fill="white"/>
<path d="M64 32H48V48H64V32Z" fill="white"/>
<path d="M16 48H0V64H16V48Z" fill="white"/>
<path d="M64 48H48V64H64V48Z" fill="white"/>
<path d="M32 64H16V80H32V64Z" fill="white"/>
<path d="M48 64H32V80H48V64Z" fill="white"/>
<path d="M96 0H80V16H96V0Z" fill="white"/>
<path d="M112 0H96V16H112V0Z" fill="white"/>
<path d="M128 0H112V16H128V0Z" fill="white"/>
<path d="M96 16H80V32H96V16Z" fill="white"/>
<path d="M144 16H128V32H144V16Z" fill="white"/>
<path d="M96 32H80V48H96V32Z" fill="white"/>
<path d="M112 32H96V48H112V32Z" fill="white"/>
<path d="M128 32H112V48H128V32Z" fill="white"/>
<path d="M144 32H128V48H144V32Z" fill="white"/>
<path d="M96 48H80V64H96V48Z" fill="white"/>
<path d="M96 64H80V80H96V64Z" fill="white"/>
<path d="M176 0H160V16H176V0Z" fill="white"/>
<path d="M192 0H176V16H192V0Z" fill="white"/>
<path d="M208 0H192V16H208V0Z" fill="white"/>
<path d="M224 0H208V16H224V0Z" fill="white"/>
<path d="M176 16H160V32H176V16Z" fill="white"/>
<path d="M176 32H160V48H176V32Z" fill="white"/>
<path d="M192 32H176V48H192V32Z" fill="white"/>
<path d="M208 32H192V48H208V32Z" fill="white"/>
<path d="M176 48H160V64H176V48Z" fill="white"/>
<path d="M176 64H160V80H176V64Z" fill="white"/>
<path d="M192 64H176V80H192V64Z" fill="white"/>
<path d="M208 64H192V80H208V64Z" fill="white"/>
<path d="M224 64H208V80H224V64Z" fill="white"/>
<path d="M256 0H240V16H256V0Z" fill="white"/>
<path d="M304 0H288V16H304V0Z" fill="white"/>
<path d="M256 16H240V32H256V16Z" fill="white"/>
<path d="M272 16H256V32H272V16Z" fill="white"/>
<path d="M304 16H288V32H304V16Z" fill="white"/>
<path d="M256 32H240V48H256V32Z" fill="white"/>
<path d="M288 32H272V48H288V32Z" fill="white"/>
<path d="M304 32H288V48H304V32Z" fill="white"/>
<path d="M256 48H240V64H256V48Z" fill="white"/>
<path d="M304 48H288V64H304V48Z" fill="white"/>
<path d="M256 64H240V80H256V64Z" fill="white"/>
<path d="M304 64H288V80H304V64Z" fill="white"/>
<path d="M352 0H336V16H352V0Z" fill="white"/>
<path d="M368 0H352V16H368V0Z" fill="white"/>
<path d="M384 0H368V16H384V0Z" fill="white"/>
<path d="M336 16H320V32H336V16Z" fill="white"/>
<path d="M352 32H336V48H352V32Z" fill="white"/>
<path d="M368 32H352V48H368V32Z" fill="white"/>
<path d="M384 48H368V64H384V48Z" fill="white"/>
<path d="M336 64H320V80H336V64Z" fill="white"/>
<path d="M352 64H336V80H352V64Z" fill="white"/>
<path d="M368 64H352V80H368V64Z" fill="white"/>
<path d="M416 0H400V16H416V0Z" fill="white"/>
<path d="M432 0H416V16H432V0Z" fill="white"/>
<path d="M448 0H432V16H448V0Z" fill="white"/>
<path d="M416 16H400V32H416V16Z" fill="white"/>
<path d="M464 16H448V32H464V16Z" fill="white"/>
<path d="M416 32H400V48H416V32Z" fill="white"/>
<path d="M432 32H416V48H432V32Z" fill="white"/>
<path d="M448 32H432V48H448V32Z" fill="white"/>
<path d="M464 32H448V48H464V32Z" fill="white"/>
<path d="M416 48H400V64H416V48Z" fill="white"/>
<path d="M416 64H400V80H416V64Z" fill="white"/>
<path d="M496 0H480V16H496V0Z" fill="white"/>
<path d="M512 0H496V16H512V0Z" fill="white"/>
<path d="M528 0H512V16H528V0Z" fill="white"/>
<path d="M544 0H528V16H544V0Z" fill="white"/>
<path d="M496 16H480V32H496V16Z" fill="white"/>
<path d="M496 32H480V48H496V32Z" fill="white"/>
<path d="M512 32H496V48H512V32Z" fill="white"/>
<path d="M528 32H512V48H528V32Z" fill="white"/>
<path d="M496 48H480V64H496V48Z" fill="white"/>
<path d="M496 64H480V80H496V64Z" fill="white"/>
<path d="M512 64H496V80H512V64Z" fill="white"/>
<path d="M528 64H512V80H528V64Z" fill="white"/>
<path d="M544 64H528V80H544V64Z" fill="white"/>
<path d="M592 0H576V16H592V0Z" fill="white"/>
<path d="M608 0H592V16H608V0Z" fill="white"/>
<path d="M576 16H560V32H576V16Z" fill="white"/>
<path d="M576 32H560V48H576V32Z" fill="white"/>
<path d="M576 48H560V64H576V48Z" fill="white"/>
<path d="M592 64H576V80H592V64Z" fill="white"/>
<path d="M608 64H592V80H608V64Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

+89
View File
@@ -0,0 +1,89 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="80" viewBox="0 0 640 80">
<rect x="16" y="0" width="16" height="16" fill="black" />
<rect x="32" y="0" width="16" height="16" fill="black" />
<rect x="0" y="16" width="16" height="16" fill="black" />
<rect x="48" y="16" width="16" height="16" fill="black" />
<rect x="0" y="32" width="16" height="16" fill="black" />
<rect x="48" y="32" width="16" height="16" fill="black" />
<rect x="0" y="48" width="16" height="16" fill="black" />
<rect x="48" y="48" width="16" height="16" fill="black" />
<rect x="16" y="64" width="16" height="16" fill="black" />
<rect x="32" y="64" width="16" height="16" fill="black" />
<rect x="80" y="0" width="16" height="16" fill="black" />
<rect x="96" y="0" width="16" height="16" fill="black" />
<rect x="112" y="0" width="16" height="16" fill="black" />
<rect x="80" y="16" width="16" height="16" fill="black" />
<rect x="128" y="16" width="16" height="16" fill="black" />
<rect x="80" y="32" width="16" height="16" fill="black" />
<rect x="96" y="32" width="16" height="16" fill="black" />
<rect x="112" y="32" width="16" height="16" fill="black" />
<rect x="128" y="32" width="16" height="16" fill="black" />
<rect x="80" y="48" width="16" height="16" fill="black" />
<rect x="80" y="64" width="16" height="16" fill="black" />
<rect x="160" y="0" width="16" height="16" fill="black" />
<rect x="176" y="0" width="16" height="16" fill="black" />
<rect x="192" y="0" width="16" height="16" fill="black" />
<rect x="208" y="0" width="16" height="16" fill="black" />
<rect x="160" y="16" width="16" height="16" fill="black" />
<rect x="160" y="32" width="16" height="16" fill="black" />
<rect x="176" y="32" width="16" height="16" fill="black" />
<rect x="192" y="32" width="16" height="16" fill="black" />
<rect x="160" y="48" width="16" height="16" fill="black" />
<rect x="160" y="64" width="16" height="16" fill="black" />
<rect x="176" y="64" width="16" height="16" fill="black" />
<rect x="192" y="64" width="16" height="16" fill="black" />
<rect x="208" y="64" width="16" height="16" fill="black" />
<rect x="240" y="0" width="16" height="16" fill="black" />
<rect x="288" y="0" width="16" height="16" fill="black" />
<rect x="240" y="16" width="16" height="16" fill="black" />
<rect x="256" y="16" width="16" height="16" fill="black" />
<rect x="288" y="16" width="16" height="16" fill="black" />
<rect x="240" y="32" width="16" height="16" fill="black" />
<rect x="272" y="32" width="16" height="16" fill="black" />
<rect x="288" y="32" width="16" height="16" fill="black" />
<rect x="240" y="48" width="16" height="16" fill="black" />
<rect x="288" y="48" width="16" height="16" fill="black" />
<rect x="240" y="64" width="16" height="16" fill="black" />
<rect x="288" y="64" width="16" height="16" fill="black" />
<rect x="336" y="0" width="16" height="16" fill="black" />
<rect x="352" y="0" width="16" height="16" fill="black" />
<rect x="368" y="0" width="16" height="16" fill="black" />
<rect x="320" y="16" width="16" height="16" fill="black" />
<rect x="336" y="32" width="16" height="16" fill="black" />
<rect x="352" y="32" width="16" height="16" fill="black" />
<rect x="368" y="48" width="16" height="16" fill="black" />
<rect x="320" y="64" width="16" height="16" fill="black" />
<rect x="336" y="64" width="16" height="16" fill="black" />
<rect x="352" y="64" width="16" height="16" fill="black" />
<rect x="400" y="0" width="16" height="16" fill="black" />
<rect x="416" y="0" width="16" height="16" fill="black" />
<rect x="432" y="0" width="16" height="16" fill="black" />
<rect x="400" y="16" width="16" height="16" fill="black" />
<rect x="448" y="16" width="16" height="16" fill="black" />
<rect x="400" y="32" width="16" height="16" fill="black" />
<rect x="416" y="32" width="16" height="16" fill="black" />
<rect x="432" y="32" width="16" height="16" fill="black" />
<rect x="448" y="32" width="16" height="16" fill="black" />
<rect x="400" y="48" width="16" height="16" fill="black" />
<rect x="400" y="64" width="16" height="16" fill="black" />
<rect x="480" y="0" width="16" height="16" fill="black" />
<rect x="496" y="0" width="16" height="16" fill="black" />
<rect x="512" y="0" width="16" height="16" fill="black" />
<rect x="528" y="0" width="16" height="16" fill="black" />
<rect x="480" y="16" width="16" height="16" fill="black" />
<rect x="480" y="32" width="16" height="16" fill="black" />
<rect x="496" y="32" width="16" height="16" fill="black" />
<rect x="512" y="32" width="16" height="16" fill="black" />
<rect x="480" y="48" width="16" height="16" fill="black" />
<rect x="480" y="64" width="16" height="16" fill="black" />
<rect x="496" y="64" width="16" height="16" fill="black" />
<rect x="512" y="64" width="16" height="16" fill="black" />
<rect x="528" y="64" width="16" height="16" fill="black" />
<rect x="576" y="0" width="16" height="16" fill="black" />
<rect x="592" y="0" width="16" height="16" fill="black" />
<rect x="560" y="16" width="16" height="16" fill="black" />
<rect x="560" y="32" width="16" height="16" fill="black" />
<rect x="560" y="48" width="16" height="16" fill="black" />
<rect x="576" y="64" width="16" height="16" fill="black" />
<rect x="592" y="64" width="16" height="16" fill="black" />
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

+13 -4
View File
@@ -1,7 +1,15 @@
#!/usr/bin/env node
import { execSync } from 'child_process';
import { execFileSync } from 'child_process';
import { existsSync, rmSync } from 'fs';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const runTsc = (args = []) => {
const tscPath = require.resolve('typescript/bin/tsc');
execFileSync(process.execPath, [tscPath, ...args], { stdio: 'inherit' });
};
console.log('🔨 Building OpenSpec...\n');
@@ -11,12 +19,13 @@ if (existsSync('dist')) {
rmSync('dist', { recursive: true, force: true });
}
// Run TypeScript compiler
// Run TypeScript compiler (use local version explicitly)
console.log('Compiling TypeScript...');
try {
execSync('tsc', { stdio: 'inherit' });
runTsc(['--version']);
runTsc();
console.log('\n✅ Build completed successfully!');
} catch (error) {
console.error('\n❌ Build failed!');
process.exit(1);
}
}
+316
View File
@@ -0,0 +1,316 @@
---
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
**Timestamp:** 2026-04-28 11:59:49 AEST
**Agent:** GitHubCopilot
### User
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
How could we get the docs from openspec repo to show up in the landing page
### Assistant / Events
---
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
**Timestamp:** 2026-04-28 11:59:49 AEST
**Agent:** GitHubCopilot
### User
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
How could we get the docs from openspec repo to show up in the landing page
### Assistant / Events
I'm in explore mode. Let me think through this with you.
First, let me understand what you're working with:
**The setup:**
- You have
---
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
**Timestamp:** 2026-04-28 11:59:49 AEST
**Agent:** GitHubCopilot
### User
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
How could we get the docs from openspec repo to show up in the landing page
### Assistant / Events
---
## Request `request_79caa9a0-bb0e-4cb4-bf91-4ce6456ad26a`
**Timestamp:** 2026-04-28 11:59:49 AEST
**Agent:** GitHubCopilot
### User
Follow instructions in [SKILL.md](file:///Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/.agents/skills/openspec-explore/SKILL.md).
How could we get the docs from openspec repo to show up in the landing page
### Assistant / Events
repo (the core product/system)
- You have `/openspec-landing` (the landing page)
- You want docs from openspec to appear on the landing page
**Before I dig into the code, some clarifying questions:**
1. **What docs are we talking about?** Are these:
- API documentation (auto-generated from code)?
- Guides and tutorials (hand-written markdown)?
- Specs and architecture docs?
- All of the above?
2. **How should they appear on the landing page?**
- Embedded directly (copy/sync)?
- Linked to (openspec repo becomes the source of truth)?
- A combination (some docs embedded, some linked)?
3. **Single source of truth?** Should the landing page reflect the *current* state of docs in openspec automatically, or is it okay if they drift?
4. **User experience angle**: When someone lands on the landing page, what should they see/do? Is the landing page meant to be:
- An entry point that says "here's what this is" + links to full docs elsewhere?
- Self-contained docs that happen to be synced from the repo?
- Something else?
Let me also check what's actually in these repos right now - that'll ground the thinking:
```bash
# What docs exist in openspec?
find /Users/tabishbidiwale/fission/repos/openspec -name "*.md" -type f | head -20
# What's the landing page structure?
ls -la /Users/tabishbidiwale/fission/repos/openspec-landing/
```
Once I see the actual structure and understand your intent, the solution becomes clearer. Could be anything from a static build step that copies markdown, to a dynamic system that fetches docs at runtime, to a link-and-let-them-navigate approach.
What resonates most with how you're thinking about this?
---
## Request `request_b6e88cd6-d531-43eb-904b-6225c3981934`
**Timestamp:** 2026-04-28 12:00:32 AEST
**Agent:** agent
### User
go search and ground before asking questions
### Assistant / Events
---
## Request `request_b6e88cd6-d531-43eb-904b-6225c3981934`
**Timestamp:** 2026-04-28 12:00:32 AEST
**Agent:** agent
### User
go search and ground before asking questions
### Assistant / Events
**Visible Thinking**
The user is right - I should explore the codebase first before asking clarifying questions. They're in explore mode and I should ground my thinking in what actually exists. Let me search and read the actual structure of both repos.
Let me:
1. Look at the docs in the openspec repo
2. Look at the structure of openspec-landing
3. See if there's any existing mechanism for sharing docs
4. Then come back with grounded thinking
I should use tools to explore the codebase first.
---
## Request `request_b6e88cd6-d531-43eb-904b-6225c3981934`
**Timestamp:** 2026-04-28 12:00:32 AEST
**Agent:** agent
### User
go search and ground before asking questions
### Assistant / Events
**Tool Call** `run_in_terminal`
```bash
find /Users/tabishbidiwale/fission/repos/openspec/docs -type f -name "*.md" | head -20
```
---
## Request `request_d515673c-cd78-483d-b0c7-139dfbe0f4b7`
**Timestamp:** 2026-04-28 12:09:16 AEST
**Agent:** agent
### User
choose best defaults and create a change proposal
### Assistant / Events
---
## Request `request_c020834d-3218-4ba4-b3ac-0fe8d8a292db`
**Timestamp:** 2026-04-28 12:32:26 AEST
**Agent:** agent
### User
what was this session id?
### Assistant / Events
---
## Request `request_c020834d-3218-4ba4-b3ac-0fe8d8a292db`
**Timestamp:** 2026-04-28 12:32:26 AEST
**Agent:** agent
### User
what was this session id?
### Assistant / Events
**Visible Thinking**
The user is asking about the session ID. I need to check what session ID was used or assigned during this exploration/proposal creation. Let me look back at what happened.
Looking at the context, I don't see a specific session ID mentioned anywhere. The user might be asking about:
1. The OpenSpec change ID (which is "integrate-docs")
2. Some kind of terminal session ID
3. Some other identifier
The change we created is called "integrate-docs" and it's located at:
`/Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/changes/integrate-docs/`
I should clarify what they're asking about. The most likely answer is the change name/ID, which is "integrate-docs".
---
## Request `request_c020834d-3218-4ba4-b3ac-0fe8d8a292db`
**Timestamp:** 2026-04-28 12:32:26 AEST
**Agent:** agent
### User
what was this session id?
### Assistant / Events
The change ID is **`integrate-docs`**.
It's located at:
```
/Users/tabishbidiwale/.local/share/openspec/workspaces/poc-workspace/changes/integrate-docs/
```
You can reference it in commands with `--change integrate-docs`.
---
## Request `request_632f186b-58f8-4301-8b64-a29b5005d8bf`
**Timestamp:** 2026-04-28 12:32:41 AEST
**Agent:** agent
### User
nah chat session ID
### Assistant / Events
---
## Request `request_632f186b-58f8-4301-8b64-a29b5005d8bf`
**Timestamp:** 2026-04-28 12:32:41 AEST
**Agent:** agent
### User
nah chat session ID
### Assistant / Events
**Visible Thinking**
The user is asking for the chat session ID - not the OpenSpec change ID. They want to know the session ID for this conversation.
However, I don't have a built-in way to retrieve the chat session ID from the context provided to me. The context includes information about the workspace, files, and environment, but not the chat session ID.
I should be honest that I don't have access to that information.
---
## Request `request_632f186b-58f8-4301-8b64-a29b5005d8bf`
**Timestamp:** 2026-04-28 12:32:41 AEST
**Agent:** agent
### User
nah chat session ID
### Assistant / Events
I don't have access to the chat session ID from my context. That information isn't available to me in the tools and context I can see. You might be able to find it in your chat client's UI or logs.
File diff suppressed because it is too large Load Diff
+978
View File
@@ -0,0 +1,978 @@
# CLI Reference
The OpenSpec CLI (`openspec`) provides terminal commands for project setup, validation, status inspection, and management. These commands complement the AI slash commands (like `/opsx:propose`) documented in [Commands](commands.md).
## Summary
| Category | Commands | Purpose |
|----------|----------|---------|
| **Setup** | `init`, `update` | Initialize and update OpenSpec in your project |
| **Browsing** | `list`, `view`, `show` | Explore changes and specs |
| **Validation** | `validate` | Check changes and specs for issues |
| **Lifecycle** | `archive` | Finalize completed changes |
| **Workflow** | `status`, `instructions`, `templates`, `schemas` | Artifact-driven workflow support |
| **Workspace** | `workspace setup`, `workspace list`, `workspace create`, `workspace add-repo`, `workspace update-repo`, `workspace targets`, `workspace doctor`, `workspace open` | Coordinate cross-repo planning without collapsing repo ownership |
| **Schemas** | `schema init`, `schema fork`, `schema validate`, `schema which` | Create and manage custom workflows |
| **Config** | `config` | View and modify settings |
| **Utility** | `feedback`, `completion` | Feedback and shell integration |
---
## Human vs Agent Commands
Most CLI commands are designed for **human use** in a terminal. Some commands also support **agent/script use** via JSON output.
### Human-Only Commands
These commands are interactive and designed for terminal use:
| Command | Purpose |
|---------|---------|
| `openspec init` | Initialize project (interactive prompts) |
| `openspec view` | Interactive dashboard |
| `openspec config edit` | Open config in editor |
| `openspec feedback` | Submit feedback via GitHub |
| `openspec completion install` | Install shell completions |
### Agent-Compatible Commands
These commands support `--json` output for programmatic use by AI agents and scripts:
| Command | Human Use | Agent Use |
|---------|-----------|-----------|
| `openspec list` | Browse changes/specs | `--json` for structured data |
| `openspec show <item>` | Read content | `--json` for parsing |
| `openspec validate` | Check for issues | `--all --json` for bulk validation |
| `openspec status` | See artifact progress | `--json` for structured status |
| `openspec instructions` | Get next steps | `--json` for agent instructions |
| `openspec templates` | Find template paths | `--json` for path resolution |
| `openspec schemas` | List available schemas | `--json` for schema discovery |
---
## Global Options
These options work with all commands:
| Option | Description |
|--------|-------------|
| `--version`, `-V` | Show version number |
| `--no-color` | Disable color output |
| `--help`, `-h` | Display help for command |
---
## Setup Commands
### `openspec init`
Initialize OpenSpec in your project. Creates the folder structure and configures AI tool integrations.
Default behavior uses global config defaults: profile `core`, delivery `both`, workflows `propose, explore, apply, archive`.
```
openspec init [path] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `path` | No | Target directory (default: current directory) |
**Options:**
| Option | Description |
|--------|-------------|
| `--tools <list>` | Configure AI tools non-interactively. Use `all`, `none`, or comma-separated list |
| `--force` | Auto-cleanup legacy files without prompting |
| `--profile <profile>` | Override global profile for this init run (`core` or `custom`) |
`--profile custom` uses whatever workflows are currently selected in global config (`openspec config profile`).
**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
**Examples:**
```bash
# Interactive initialization
openspec init
# Initialize in a specific directory
openspec init ./my-project
# Non-interactive: configure for Claude and Cursor
openspec init --tools claude,cursor
# Configure for all supported tools
openspec init --tools all
# Override profile for this run
openspec init --profile core
# Skip prompts and auto-cleanup legacy files
openspec init --force
```
**What it creates:**
```
openspec/
├── specs/ # Your specifications (source of truth)
├── changes/ # Proposed changes
└── config.yaml # Project configuration
.claude/skills/ # Claude Code skills (if claude selected)
.cursor/skills/ # Cursor skills (if cursor selected)
.cursor/commands/ # Cursor OPSX commands (if delivery includes commands)
... (other tool configs)
```
---
### `openspec update`
Update OpenSpec instruction files after upgrading the CLI. Re-generates AI tool configuration files using your current global profile, selected workflows, and delivery mode.
```
openspec update [path] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `path` | No | Target directory (default: current directory) |
**Options:**
| Option | Description |
|--------|-------------|
| `--force` | Force update even when files are up to date |
**Example:**
```bash
# Update instruction files after npm upgrade
npm update @fission-ai/openspec
openspec update
```
---
## Browsing Commands
### `openspec list`
List changes or specs in your project.
```
openspec list [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--specs` | List specs instead of changes |
| `--changes` | List changes (default) |
| `--sort <order>` | Sort by `recent` (default) or `name` |
| `--json` | Output as JSON |
**Examples:**
```bash
# List all active changes
openspec list
# List all specs
openspec list --specs
# JSON output for scripts
openspec list --json
```
**Output (text):**
```
Active changes:
add-dark-mode UI theme switching support
fix-login-bug Session timeout handling
```
---
### `openspec view`
Display an interactive dashboard for exploring specs and changes.
```
openspec view
```
Opens a terminal-based interface for navigating your project's specifications and changes.
---
### `openspec show`
Display details of a change or spec.
```
openspec show [item-name] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `item-name` | No | Name of change or spec (prompts if omitted) |
**Options:**
| Option | Description |
|--------|-------------|
| `--type <type>` | Specify type: `change` or `spec` (auto-detected if unambiguous) |
| `--json` | Output as JSON |
| `--no-interactive` | Disable prompts |
**Change-specific options:**
| Option | Description |
|--------|-------------|
| `--deltas-only` | Show only delta specs (JSON mode) |
**Spec-specific options:**
| Option | Description |
|--------|-------------|
| `--requirements` | Show only requirements, exclude scenarios (JSON mode) |
| `--no-scenarios` | Exclude scenario content (JSON mode) |
| `-r, --requirement <id>` | Show specific requirement by 1-based index (JSON mode) |
**Examples:**
```bash
# Interactive selection
openspec show
# Show a specific change
openspec show add-dark-mode
# Show a specific spec
openspec show auth --type spec
# JSON output for parsing
openspec show add-dark-mode --json
```
---
## Validation Commands
### `openspec validate`
Validate changes and specs for structural issues.
```
openspec validate [item-name] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `item-name` | No | Specific item to validate (prompts if omitted) |
**Options:**
| Option | Description |
|--------|-------------|
| `--all` | Validate all changes and specs |
| `--changes` | Validate all changes |
| `--specs` | Validate all specs |
| `--type <type>` | Specify type when name is ambiguous: `change` or `spec` |
| `--strict` | Enable strict validation mode |
| `--json` | Output as JSON |
| `--concurrency <n>` | Max parallel validations (default: 6, or `OPENSPEC_CONCURRENCY` env) |
| `--no-interactive` | Disable prompts |
**Examples:**
```bash
# Interactive validation
openspec validate
# Validate a specific change
openspec validate add-dark-mode
# Validate all changes
openspec validate --changes
# Validate everything with JSON output (for CI/scripts)
openspec validate --all --json
# Strict validation with increased parallelism
openspec validate --all --strict --concurrency 12
```
**Output (text):**
```
Validating add-dark-mode...
✓ proposal.md valid
✓ specs/ui/spec.md valid
⚠ design.md: missing "Technical Approach" section
1 warning found
```
**Output (JSON):**
```json
{
"version": "1.0.0",
"results": {
"changes": [
{
"name": "add-dark-mode",
"valid": true,
"warnings": ["design.md: missing 'Technical Approach' section"]
}
]
},
"summary": {
"total": 1,
"valid": 1,
"invalid": 0
}
}
```
---
## Lifecycle Commands
### `openspec archive`
Archive a completed change and merge delta specs into main specs.
```
openspec archive [change-name] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Change to archive (prompts if omitted) |
**Options:**
| Option | Description |
|--------|-------------|
| `-y, --yes` | Skip confirmation prompts |
| `--skip-specs` | Skip spec updates (for infrastructure/tooling/doc-only changes) |
| `--no-validate` | Skip validation (requires confirmation) |
**Examples:**
```bash
# Interactive archive
openspec archive
# Archive specific change
openspec archive add-dark-mode
# Archive without prompts (CI/scripts)
openspec archive add-dark-mode --yes
# Archive a tooling change that doesn't affect specs
openspec archive update-ci-config --skip-specs
```
**What it does:**
1. Validates the change (unless `--no-validate`)
2. Prompts for confirmation (unless `--yes`)
3. Merges delta specs into `openspec/specs/`
4. Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
---
## Workflow Commands
These commands support the artifact-driven OPSX workflow. They're useful for both humans checking progress and agents determining next steps.
### `openspec status`
Display artifact completion status for a change.
```
openspec status [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--change <id>` | Change name (prompts if omitted) |
| `--schema <name>` | Schema override (auto-detected from change's config) |
| `--json` | Output as JSON |
**Examples:**
```bash
# Interactive status check
openspec status
# Status for specific change
openspec status --change add-dark-mode
# JSON for agent use
openspec status --change add-dark-mode --json
```
**Output (text):**
```
Change: add-dark-mode
Schema: spec-driven
Progress: 2/4 artifacts complete
[x] proposal
[ ] design
[x] specs
[-] tasks (blocked by: design)
```
**Output (JSON):**
```json
{
"changeName": "add-dark-mode",
"schemaName": "spec-driven",
"isComplete": false,
"applyRequires": ["tasks"],
"artifacts": [
{"id": "proposal", "outputPath": "proposal.md", "status": "done"},
{"id": "design", "outputPath": "design.md", "status": "ready"},
{"id": "specs", "outputPath": "specs/**/*.md", "status": "done"},
{"id": "tasks", "outputPath": "tasks.md", "status": "blocked", "missingDeps": ["design"]}
]
}
```
---
### `openspec instructions`
Get enriched instructions for creating an artifact or applying tasks. Used by AI agents to understand what to create next.
```
openspec instructions [artifact] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `artifact` | No | Artifact ID: `proposal`, `specs`, `design`, `tasks`, or `apply` |
**Options:**
| Option | Description |
|--------|-------------|
| `--change <id>` | Change name (required in non-interactive mode) |
| `--schema <name>` | Schema override |
| `--json` | Output as JSON |
**Special case:** Use `apply` as the artifact to get task implementation instructions.
**Examples:**
```bash
# Get instructions for next artifact
openspec instructions --change add-dark-mode
# Get specific artifact instructions
openspec instructions design --change add-dark-mode
# Get apply/implementation instructions
openspec instructions apply --change add-dark-mode
# JSON for agent consumption
openspec instructions design --change add-dark-mode --json
```
**Output includes:**
- Template content for the artifact
- Project context from config
- Content from dependency artifacts
- Per-artifact rules from config
---
### `openspec templates`
Show resolved template paths for all artifacts in a schema.
```
openspec templates [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--schema <name>` | Schema to inspect (default: `spec-driven`) |
| `--json` | Output as JSON |
**Examples:**
```bash
# Show template paths for default schema
openspec templates
# Show templates for custom schema
openspec templates --schema my-workflow
# JSON for programmatic use
openspec templates --json
```
**Output (text):**
```
Schema: spec-driven
Templates:
proposal → ~/.openspec/schemas/spec-driven/templates/proposal.md
specs → ~/.openspec/schemas/spec-driven/templates/specs.md
design → ~/.openspec/schemas/spec-driven/templates/design.md
tasks → ~/.openspec/schemas/spec-driven/templates/tasks.md
```
---
### `openspec schemas`
List available workflow schemas with their descriptions and artifact flows.
```
openspec schemas [options]
```
**Options:**
| Option | Description |
|--------|-------------|
| `--json` | Output as JSON |
**Example:**
```bash
openspec schemas
```
**Output:**
```
Available schemas:
spec-driven (package)
The default spec-driven development workflow
Flow: proposal → specs → design → tasks
my-custom (project)
Custom workflow for this project
Flow: research → proposal → tasks
```
---
## Workspace Commands
Use workspace mode when one change spans multiple repos or you need a neutral planning home for cross-repo coordination. Stay repo-local when one repo owns the full change end to end.
For the supported v0 flow, re-entry path, and owner or handoff guidance, see [Workspace Mode](workspace.md).
Start with the guided setup path unless you already know the exact workspace shape you want:
- `openspec workspace setup`
The setup wizard is interactive and asks for:
- workspace name
- repo paths
- repo aliases
- optional owner or handoff notes
- whether to open the planning surface immediately
The current workspace command group includes:
- `openspec workspace setup`
- `openspec workspace list`
- `openspec workspace create <name>`
- `openspec workspace add-repo <alias> <path> [--owner ...] [--handoff ...]`
- `openspec workspace update-repo <alias> [--owner ...] [--handoff ...]`
- `openspec workspace targets <id> [--add <a,b,c>] [--remove <x,y,z>]`
- `openspec workspace doctor`
- `openspec workspace open [--change <id>] [--name <workspace>] [--agent <claude|codex|github-copilot>] [--prepare-only]`
`openspec workspace targets` only mutates workspace-owned planning state. If the same change ID already exists or was already archived in a target repo, the command fails instead of silently rewriting the target set around repo-local authority handoff.
Workspace planning still uses the normal workflow commands around that command group:
- `openspec new change <id> --targets <a,b,c>`
- `openspec apply --change <id> --repo <alias>`
- `openspec status --change <id>`
- `openspec archive <id> --workspace`
---
## Schema Commands
Commands for creating and managing custom workflow schemas.
### `openspec schema init`
Create a new project-local schema.
```
openspec schema init <name> [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `name` | Yes | Schema name (kebab-case) |
**Options:**
| Option | Description |
|--------|-------------|
| `--description <text>` | Schema description |
| `--artifacts <list>` | Comma-separated artifact IDs (default: `proposal,specs,design,tasks`) |
| `--default` | Set as project default schema |
| `--no-default` | Don't prompt to set as default |
| `--force` | Overwrite existing schema |
| `--json` | Output as JSON |
**Examples:**
```bash
# Interactive schema creation
openspec schema init research-first
# Non-interactive with specific artifacts
openspec schema init rapid \
--description "Rapid iteration workflow" \
--artifacts "proposal,tasks" \
--default
```
**What it creates:**
```
openspec/schemas/<name>/
├── schema.yaml # Schema definition
└── templates/
├── proposal.md # Template for each artifact
├── specs.md
├── design.md
└── tasks.md
```
---
### `openspec schema fork`
Copy an existing schema to your project for customization.
```
openspec schema fork <source> [name] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `source` | Yes | Schema to copy |
| `name` | No | New schema name (default: `<source>-custom`) |
**Options:**
| Option | Description |
|--------|-------------|
| `--force` | Overwrite existing destination |
| `--json` | Output as JSON |
**Example:**
```bash
# Fork the built-in spec-driven schema
openspec schema fork spec-driven my-workflow
```
---
### `openspec schema validate`
Validate a schema's structure and templates.
```
openspec schema validate [name] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `name` | No | Schema to validate (validates all if omitted) |
**Options:**
| Option | Description |
|--------|-------------|
| `--verbose` | Show detailed validation steps |
| `--json` | Output as JSON |
**Example:**
```bash
# Validate a specific schema
openspec schema validate my-workflow
# Validate all schemas
openspec schema validate
```
---
### `openspec schema which`
Show where a schema resolves from (useful for debugging precedence).
```
openspec schema which [name] [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `name` | No | Schema name |
**Options:**
| Option | Description |
|--------|-------------|
| `--all` | List all schemas with their sources |
| `--json` | Output as JSON |
**Example:**
```bash
# Check where a schema comes from
openspec schema which spec-driven
```
**Output:**
```
spec-driven resolves from: package
Source: /usr/local/lib/node_modules/@fission-ai/openspec/schemas/spec-driven
```
**Schema precedence:**
1. Project: `openspec/schemas/<name>/`
2. User: `~/.local/share/openspec/schemas/<name>/`
3. Package: Built-in schemas
---
## Configuration Commands
### `openspec config`
View and modify global OpenSpec configuration.
```
openspec config <subcommand> [options]
```
**Subcommands:**
| Subcommand | Description |
|------------|-------------|
| `path` | Show config file location |
| `list` | Show all current settings |
| `get <key>` | Get a specific value |
| `set <key> <value>` | Set a value |
| `unset <key>` | Remove a key |
| `reset` | Reset to defaults |
| `edit` | Open in `$EDITOR` |
| `profile [preset]` | Configure workflow profile interactively or via preset |
**Examples:**
```bash
# Show config file path
openspec config path
# List all settings
openspec config list
# Get a specific value
openspec config get telemetry.enabled
# Set a value
openspec config set telemetry.enabled false
# Set a string value explicitly
openspec config set user.name "My Name" --string
# Remove a custom setting
openspec config unset user.name
# Reset all configuration
openspec config reset --all --yes
# Edit config in your editor
openspec config edit
# Configure profile with action-based wizard
openspec config profile
# Fast preset: switch workflows to core (keeps delivery mode)
openspec config profile core
```
`openspec config profile` starts with a current-state summary, then lets you choose:
- Change delivery + workflows
- Change delivery only
- Change workflows only
- Keep current settings (exit)
If you keep current settings, no changes are written and no update prompt is shown.
If there are no config changes but the current project files are out of sync with your global profile/delivery, OpenSpec will show a warning and suggest running `openspec update`.
Pressing `Ctrl+C` also cancels the flow cleanly (no stack trace) and exits with code `130`.
In the workflow checklist, `[x]` means the workflow is selected in global config. To apply those selections to project files, run `openspec update` (or choose `Apply changes to this project now?` when prompted inside a project).
**Interactive examples:**
```bash
# Delivery-only update
openspec config profile
# choose: Change delivery only
# choose delivery: Skills only
# Workflows-only update
openspec config profile
# choose: Change workflows only
# toggle workflows in the checklist, then confirm
```
---
## Utility Commands
### `openspec feedback`
Submit feedback about OpenSpec. Creates a GitHub issue.
```
openspec feedback <message> [options]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `message` | Yes | Feedback message |
**Options:**
| Option | Description |
|--------|-------------|
| `--body <text>` | Detailed description |
**Requirements:** GitHub CLI (`gh`) must be installed and authenticated.
**Example:**
```bash
openspec feedback "Add support for custom artifact types" \
--body "I'd like to define my own artifact types beyond the built-in ones."
```
---
### `openspec completion`
Manage shell completions for the OpenSpec CLI.
```
openspec completion <subcommand> [shell]
```
**Subcommands:**
| Subcommand | Description |
|------------|-------------|
| `generate [shell]` | Output completion script to stdout |
| `install [shell]` | Install completion for your shell |
| `uninstall [shell]` | Remove installed completions |
**Supported shells:** `bash`, `zsh`, `fish`, `powershell`
**Examples:**
```bash
# Install completions (auto-detects shell)
openspec completion install
# Install for specific shell
openspec completion install zsh
# Generate script for manual installation
openspec completion generate bash > ~/.bash_completion.d/openspec
# Uninstall
openspec completion uninstall
```
---
## Exit Codes
| Code | Meaning |
|------|---------|
| `0` | Success |
| `1` | Error (validation failure, missing files, etc.) |
---
## Environment Variables
| Variable | Description |
|----------|-------------|
| `OPENSPEC_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 |
---
## Related Documentation
- [Commands](commands.md) - AI slash commands (`/opsx:propose`, `/opsx:apply`, etc.)
- [Workflows](workflows.md) - Common patterns and when to use each command
- [Workspace Mode](workspace.md) - When to use cross-repo workspaces and the supported CLI flow
- [Customization](customization.md) - Create custom schemas and templates
- [Getting Started](getting-started.md) - First-time setup guide
+704
View File
@@ -0,0 +1,704 @@
# Commands
This is the reference for OpenSpec's slash commands. These commands are invoked in your AI coding assistant's chat interface (e.g., Claude Code, Cursor, Windsurf).
For workflow patterns and when to use each command, see [Workflows](workflows.md). For CLI commands, see [CLI](cli.md).
## Quick Reference
### Default Quick Path (`core` profile)
| Command | Purpose |
|---------|---------|
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
| `/opsx:explore` | Think through ideas before committing to a change |
| `/opsx:apply` | Implement tasks from the change |
| `/opsx:archive` | Archive a completed change |
### Expanded Workflow Commands (custom workflow selection)
| Command | Purpose |
|---------|---------|
| `/opsx:new` | Start a new change scaffold |
| `/opsx:continue` | Create the next artifact based on dependencies |
| `/opsx:ff` | Fast-forward: create all planning artifacts at once |
| `/opsx:verify` | Validate implementation matches artifacts |
| `/opsx:sync` | Merge delta specs into main specs |
| `/opsx:bulk-archive` | Archive multiple changes at once |
| `/opsx:onboard` | Guided tutorial through the complete workflow |
The default global profile is `core`. To enable expanded workflow commands, run `openspec config profile`, select workflows, then run `openspec update` in your project.
---
## Command Reference
### `/opsx:propose`
Create a new change and generate planning artifacts in one step. This is the default start command in the `core` profile.
**Syntax:**
```text
/opsx:propose [change-name-or-description]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name-or-description` | No | Kebab-case name or plain-language change description |
**What it does:**
- Creates `openspec/changes/<change-name>/`
- Generates artifacts needed before implementation (for `spec-driven`: proposal, specs, design, tasks)
- Stops when the change is ready for `/opsx:apply`
**Example:**
```text
You: /opsx:propose add-dark-mode
AI: Created openspec/changes/add-dark-mode/
✓ proposal.md
✓ specs/ui/spec.md
✓ design.md
✓ tasks.md
Ready for implementation. Run /opsx:apply.
```
**Tips:**
- Use this for the fastest end-to-end path
- If you want step-by-step artifact control, enable expanded workflows and use `/opsx:new` + `/opsx:continue`
---
### `/opsx:explore`
Think through ideas, investigate problems, and clarify requirements before committing to a change.
**Syntax:**
```
/opsx:explore [topic]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `topic` | No | What you want to explore or investigate |
**What it does:**
- Opens an exploratory conversation with no structure required
- Investigates the codebase to answer questions
- Compares options and approaches
- Creates visual diagrams to clarify thinking
- Can transition to `/opsx:propose` (default) or `/opsx:new` (expanded workflow) when insights crystallize
**Example:**
```text
You: /opsx:explore
AI: What would you like to explore?
You: How should we handle authentication for the mobile app?
AI: Let me investigate your current auth setup...
[Analyzes codebase]
I see you're using session-based auth for the web app.
For mobile, we have three main options:
1. JWT tokens (stateless, works offline)
2. OAuth2 (if you need third-party login)
3. Extend current sessions (simpler, but requires connectivity)
Your API already has CORS configured. Which direction interests you?
You: Let's go with JWT. Can we start a change for that?
AI: Ready when you are. Run /opsx:propose add-jwt-auth to begin.
```
**Tips:**
- Use when requirements are unclear or you need to investigate
- No artifacts are created during exploration
- Good for comparing multiple approaches before deciding
- Can read files and search the codebase
---
### `/opsx:new`
Start a new change scaffold. Creates the change folder and waits for you to generate artifacts with `/opsx:continue` or `/opsx:ff`.
This command is part of the expanded workflow set (not included in the default `core` profile).
**Syntax:**
```
/opsx:new [change-name] [--schema <schema-name>]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Name for the change folder (prompted if not provided) |
| `--schema` | No | Workflow schema to use (default: from config or `spec-driven`) |
**What it does:**
- Creates `openspec/changes/<change-name>/` directory
- Creates `.openspec.yaml` metadata file in the change folder
- Shows the first artifact template ready for creation
- Prompts for change name and schema if not provided
**What it creates:**
```
openspec/changes/<change-name>/
└── .openspec.yaml # Change metadata (schema, created date)
```
**Example:**
```
You: /opsx:new add-dark-mode
AI: Created openspec/changes/add-dark-mode/
Schema: spec-driven
Ready to create: proposal
Use /opsx:continue to create it, or /opsx:ff to create all artifacts.
```
**Tips:**
- Use descriptive names: `add-feature`, `fix-bug`, `refactor-module`
- Avoid generic names like `update`, `changes`, `wip`
- Schema can also be set in project config (`openspec/config.yaml`)
---
### `/opsx:continue`
Create the next artifact in the dependency chain. Creates one artifact at a time for incremental progress.
**Syntax:**
```
/opsx:continue [change-name]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to continue (inferred from context if not provided) |
**What it does:**
- Queries the artifact dependency graph
- Shows which artifacts are ready vs blocked
- Creates the first ready artifact
- Reads dependency files for context
- Shows what becomes available after creation
**Example:**
```
You: /opsx:continue
AI: Change: add-dark-mode
Artifact status:
✓ proposal (done)
◆ specs (ready)
◆ design (ready)
○ tasks (blocked - needs: specs)
Creating specs...
[Reads proposal.md, creates specs based on requirements]
✓ Created openspec/changes/add-dark-mode/specs/ui/spec.md
Now available: tasks
Run /opsx:continue to create the next artifact.
```
**Tips:**
- Use when you want to review each artifact before proceeding
- Good for complex changes where you want control
- Multiple artifacts may become ready simultaneously
- You can edit created artifacts before continuing
---
### `/opsx:ff`
Fast-forward through artifact creation. Creates all planning artifacts at once.
**Syntax:**
```
/opsx:ff [change-name]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to fast-forward (inferred from context if not provided) |
**What it does:**
- Creates all artifacts in dependency order
- Tracks progress via todo list
- Stops when all `apply-required` artifacts are complete
- Reads each dependency before creating the next artifact
**Example:**
```
You: /opsx:ff add-dark-mode
AI: Fast-forwarding add-dark-mode...
✓ Creating proposal.md
✓ Creating specs/ui/spec.md
✓ Creating design.md
✓ Creating tasks.md
All planning artifacts complete!
Ready for implementation. Run /opsx:apply to begin.
```
**Tips:**
- Use when you have a clear picture of what you're building
- Faster than `/opsx:continue` for straightforward changes
- You can still edit artifacts afterward
- Good for small to medium features
---
### `/opsx:apply`
Implement tasks from the change. Works through the task list, writing code and checking off items.
**Syntax:**
```
/opsx:apply [change-name]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to implement (inferred from context if not provided) |
**What it does:**
- Reads `tasks.md` and identifies incomplete tasks
- Works through tasks one by one
- Writes code, creates files, runs tests as needed
- Marks tasks complete with checkboxes `[x]`
**Example:**
```
You: /opsx:apply
AI: Implementing add-dark-mode...
Reading tasks.md:
- [ ] 1.1 Create ThemeContext
- [ ] 1.2 Add CSS custom properties
- [ ] 1.3 Implement localStorage persistence
Working on 1.1: Create ThemeContext...
[Creates src/context/ThemeContext.tsx]
✓ 1.1 Complete
Working on 1.2: Add CSS custom properties...
[Updates src/styles/globals.css]
✓ 1.2 Complete
...
```
**Tips:**
- Can resume where you left off if interrupted
- Use for parallel changes by specifying the change name
- Completion state is tracked in `tasks.md` checkboxes
---
### `/opsx:verify`
Validate that implementation matches your change artifacts. Checks completeness, correctness, and coherence.
**Syntax:**
```
/opsx:verify [change-name]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to verify (inferred from context if not provided) |
**What it does:**
- Checks three dimensions of implementation quality
- Searches codebase for implementation evidence
- Reports issues categorized as CRITICAL, WARNING, or SUGGESTION
- Does not block archive, but surfaces issues
**Verification dimensions:**
| Dimension | What it validates |
|-----------|-------------------|
| **Completeness** | All tasks done, all requirements implemented, scenarios covered |
| **Correctness** | Implementation matches spec intent, edge cases handled |
| **Coherence** | Design decisions reflected in code, patterns consistent |
**Example:**
```
You: /opsx:verify
AI: Verifying add-dark-mode...
COMPLETENESS
✓ All 8 tasks in tasks.md are checked
✓ All requirements in specs have corresponding code
⚠ Scenario "System preference detection" has no test coverage
CORRECTNESS
✓ Implementation matches spec intent
✓ Edge cases from scenarios are handled
✓ Error states match spec definitions
COHERENCE
✓ Design decisions reflected in code structure
✓ Naming conventions consistent with design.md
⚠ Design mentions "CSS variables" but implementation uses Tailwind classes
SUMMARY
─────────────────────────────
Critical issues: 0
Warnings: 2
Ready to archive: Yes (with warnings)
Recommendations:
1. Add test for system preference detection
2. Update design.md to reflect Tailwind usage, or refactor to use CSS variables
```
**Tips:**
- Run before archiving to catch mismatches early
- Warnings don't block archive but indicate potential issues
- Good for reviewing AI's work before committing
- Can reveal drift between artifacts and implementation
---
### `/opsx:sync`
**Optional command.** Merge delta specs from a change into main specs. Archive will prompt to sync if needed, so you typically don't need to run this manually.
**Syntax:**
```
/opsx:sync [change-name]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to sync (inferred from context if not provided) |
**What it does:**
- Reads delta specs from change folder
- Parses ADDED/MODIFIED/REMOVED/RENAMED sections
- Merges changes into main `openspec/specs/` directory
- Preserves existing content not mentioned in delta
- Does not archive the change (remains active)
**Example:**
```text
You: /opsx:sync
AI: Syncing add-dark-mode delta specs...
Reading: openspec/changes/add-dark-mode/specs/ui/spec.md
Target: openspec/specs/ui/spec.md
Changes to apply:
✓ ADDED: Theme Selection requirement (2 scenarios)
✓ ADDED: Accessibility requirement (1 scenario)
Merging...
✓ openspec/specs/ui/spec.md updated
Change remains active. Run /opsx:archive when ready to complete.
```
**When to use manually:**
| Scenario | Use sync? |
|----------|-----------|
| Long-running change, want specs in main before archiving | Yes |
| Multiple parallel changes need the updated base specs | Yes |
| Want to preview/review the merge separately | Yes |
| Quick change, going straight to archive | No (archive handles it) |
**Tips:**
- Sync is intelligent, not copy-paste
- Can add scenarios to existing requirements without duplicating
- Change stays active after sync (not archived)
- Most users will never need to call this directly—archive prompts if needed
---
### `/opsx:archive`
Archive a completed change. Finalizes the change and moves it to the archive folder.
**Syntax:**
```
/opsx:archive [change-name]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-name` | No | Which change to archive (inferred from context if not provided) |
**What it does:**
- Checks artifact completion status
- Checks task completion (warns if incomplete)
- Offers to sync delta specs if not already synced
- Moves change folder to `openspec/changes/archive/YYYY-MM-DD-<name>/`
- Preserves all artifacts for audit trail
**Example:**
```text
You: /opsx:archive
AI: Archiving add-dark-mode...
Artifact status:
✓ proposal.md exists
✓ specs/ exists
✓ design.md exists
✓ tasks.md exists (8/8 tasks complete)
Delta specs: Not yet synced
→ Sync now? (recommended)
You: Yes
AI: ✓ Synced specs to openspec/specs/ui/spec.md
✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/
Change archived successfully.
```
**Tips:**
- Archive won't block on incomplete tasks, but will warn
- Delta specs can be synced during archive or beforehand
- Archived changes are preserved for history
- Use `/opsx:verify` first to catch issues
---
### `/opsx:bulk-archive`
Archive multiple completed changes at once. Handles spec conflicts between changes.
**Syntax:**
```
/opsx:bulk-archive [change-names...]
```
**Arguments:**
| Argument | Required | Description |
|----------|----------|-------------|
| `change-names` | No | Specific changes to archive (prompts to select if not provided) |
**What it does:**
- Lists all completed changes
- Validates each change before archiving
- Detects spec conflicts across changes
- Resolves conflicts by checking what's actually implemented
- Archives in chronological order
**Example:**
```
You: /opsx:bulk-archive
AI: Found 3 completed changes:
- add-dark-mode (8/8 tasks complete)
- fix-login-bug (3/3 tasks complete)
- update-footer (2/2 tasks complete)
Checking for spec conflicts...
⚠ add-dark-mode and update-footer both touch specs/ui/
Inspecting codebase to resolve...
Both changes are implemented. Will merge in chronological order:
1. add-dark-mode (created Jan 20)
2. update-footer (created Jan 22)
Archive all 3 changes?
You: Yes
AI: ✓ Archived add-dark-mode
✓ Archived fix-login-bug
✓ Archived update-footer
Specs merged: add-dark-mode → update-footer
```
**Tips:**
- Good for parallel work streams
- Conflict resolution is agentic (checks codebase)
- Changes are archived in order of creation
- Prompts before overwriting spec content
---
### `/opsx:onboard`
Guided onboarding through the complete OpenSpec workflow. An interactive tutorial using your actual codebase.
**Syntax:**
```
/opsx:onboard
```
**What it does:**
- Walks through a complete workflow cycle with narration
- Scans your codebase for real improvement opportunities
- Creates an actual change with real artifacts
- Implements actual work (small, safe changes)
- Archives the completed change
- Explains each step as it happens
**Phases:**
1. Welcome and codebase analysis
2. Finding an improvement opportunity
3. Creating a change (`/opsx:new`)
4. Writing the proposal
5. Creating specs
6. Writing the design
7. Creating tasks
8. Implementing tasks (`/opsx:apply`)
9. Verifying implementation
10. Archiving the change
11. Summary and next steps
**Example:**
```
You: /opsx:onboard
AI: Welcome to OpenSpec!
I'll walk you through the complete workflow using your actual codebase.
We'll find something small to improve, create a proper change for it,
implement it, and archive it.
Let me scan your codebase for opportunities...
[Analyzes codebase]
I found a few things we could work on:
1. Add input validation to the contact form
2. Improve error messages in the auth flow
3. Add loading states to async buttons
Which interests you? (or suggest something else)
```
**Tips:**
- Best for new users learning the workflow
- Uses real code, not toy examples
- Creates a real change you can keep or discard
- Takes 15-30 minutes to complete
---
## Command Syntax by AI Tool
Different AI tools use slightly different command syntax. Use the format that matches your tool:
| Tool | Syntax Example |
|------|----------------|
| Claude Code | `/opsx:propose`, `/opsx:apply` |
| Cursor | `/opsx-propose`, `/opsx-apply` |
| Windsurf | `/opsx-propose`, `/opsx-apply` |
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
| Trae | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |
The intent is the same across tools, but how commands are surfaced can differ by integration.
> **Note:** GitHub Copilot commands (`.github/prompts/*.prompt.md`) are only available in IDE extensions (VS Code, JetBrains, Visual Studio). GitHub Copilot CLI does not currently support custom prompt files — see [Supported Tools](supported-tools.md) for details and workarounds.
---
## Legacy Commands
These commands use the older "all-at-once" workflow. They still work but OPSX commands are recommended.
| Command | What it does |
|---------|--------------|
| `/openspec:proposal` | Create all artifacts at once (proposal, specs, design, tasks) |
| `/openspec:apply` | Implement the change |
| `/openspec:archive` | Archive the change |
**When to use legacy commands:**
- Existing projects using the old workflow
- Simple changes where you don't need incremental artifact creation
- Preference for the all-or-nothing approach
**Migrating to OPSX:**
Legacy changes can be continued with OPSX commands. The artifact structure is compatible.
---
## Troubleshooting
### "Change not found"
The command couldn't identify which change to work on.
**Solutions:**
- Specify the change name explicitly: `/opsx:apply add-dark-mode`
- Check that the change folder exists: `openspec list`
- Verify you're in the right project directory
### "No artifacts ready"
All artifacts are either complete or blocked by missing dependencies.
**Solutions:**
- Run `openspec status --change <name>` to see what's blocking
- Check if required artifacts exist
- Create missing dependency artifacts first
### "Schema not found"
The specified schema doesn't exist.
**Solutions:**
- List available schemas: `openspec schemas`
- Check spelling of schema name
- Create the schema if it's custom: `openspec schema init <name>`
### Commands not recognized
The AI tool doesn't recognize OpenSpec commands.
**Solutions:**
- Ensure OpenSpec is initialized: `openspec init`
- Regenerate skills: `openspec update`
- Check that `.claude/skills/` directory exists (for Claude Code)
- Restart your AI tool to pick up new skills
### Artifacts not generating properly
The AI creates incomplete or incorrect artifacts.
**Solutions:**
- Add project context in `openspec/config.yaml`
- Add per-artifact rules for specific guidance
- Provide more detail in your change description
- Use `/opsx:continue` instead of `/opsx:ff` for more control
---
## Next Steps
- [Workflows](workflows.md) - Common patterns and when to use each command
- [CLI](cli.md) - Terminal commands for management and validation
- [Customization](customization.md) - Create custom schemas and workflows
+628
View File
@@ -0,0 +1,628 @@
# Concepts
This guide explains the core ideas behind OpenSpec and how they fit together. For practical usage, see [Getting Started](getting-started.md) and [Workflows](workflows.md).
## Philosophy
OpenSpec is built around four principles:
```
fluid not rigid — no phase gates, work on what makes sense
iterative not waterfall — learn as you build, refine as you go
easy not complex — lightweight setup, minimal ceremony
brownfield-first — works with existing codebases, not just greenfield
```
### Why These Principles Matter
**Fluid not rigid.** Traditional spec systems lock you into phases: first you plan, then you implement, then you're done. OpenSpec is more flexible — you can create artifacts in any order that makes sense for your work.
**Iterative not waterfall.** Requirements change. Understanding deepens. What seemed like a good approach at the start might not hold up after you see the codebase. OpenSpec embraces this reality.
**Easy not complex.** Some spec frameworks require extensive setup, rigid formats, or heavyweight processes. OpenSpec stays out of your way. Initialize in seconds, start working immediately, customize only if you need to.
**Brownfield-first.** Most software work isn't building from scratch — it's modifying existing systems. OpenSpec's delta-based approach makes it easy to specify changes to existing behavior, not just describe new systems.
## The Big Picture
OpenSpec organizes your work into two main areas:
```
┌────────────────────────────────────────────────────────────────────┐
│ openspec/ │
│ │
│ ┌─────────────────────┐ ┌───────────────────────────────┐ │
│ │ specs/ │ │ changes/ │ │
│ │ │ │ │ │
│ │ Source of truth │◄─────│ Proposed modifications │ │
│ │ How your system │ merge│ Each change = one folder │ │
│ │ currently works │ │ Contains artifacts + deltas │ │
│ │ │ │ │ │
│ └─────────────────────┘ └───────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────┘
```
**Specs** are the source of truth — they describe how your system currently behaves.
**Changes** are proposed modifications — they live in separate folders until you're ready to merge them.
This separation is key. You can work on multiple changes in parallel without conflicts. You can review a change before it affects the main specs. And when you archive a change, its deltas merge cleanly into the source of truth.
## Specs
Specs describe your system's behavior using structured requirements and scenarios.
### Structure
```
openspec/specs/
├── auth/
│ └── spec.md # Authentication behavior
├── payments/
│ └── spec.md # Payment processing
├── notifications/
│ └── spec.md # Notification system
└── ui/
└── spec.md # UI behavior and themes
```
Organize specs by domain — logical groupings that make sense for your system. Common patterns:
- **By feature area**: `auth/`, `payments/`, `search/`
- **By component**: `api/`, `frontend/`, `workers/`
- **By bounded context**: `ordering/`, `fulfillment/`, `inventory/`
### Spec Format
A spec contains requirements, and each requirement has scenarios:
```markdown
# Auth Specification
## Purpose
Authentication and session management for the application.
## Requirements
### Requirement: User Authentication
The system SHALL issue a JWT token upon successful login.
#### Scenario: Valid credentials
- GIVEN a user with valid credentials
- WHEN the user submits login form
- THEN a JWT token is returned
- AND the user is redirected to dashboard
#### Scenario: Invalid credentials
- GIVEN invalid credentials
- WHEN the user submits login form
- THEN an error message is displayed
- AND no token is issued
### Requirement: Session Expiration
The system MUST expire sessions after 30 minutes of inactivity.
#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 30 minutes pass without activity
- THEN the session is invalidated
- AND the user must re-authenticate
```
**Key elements:**
| Element | Purpose |
|---------|---------|
| `## Purpose` | High-level description of this spec's domain |
| `### Requirement:` | A specific behavior the system must have |
| `#### Scenario:` | A concrete example of the requirement in action |
| SHALL/MUST/SHOULD | RFC 2119 keywords indicating requirement strength |
### Why Structure Specs This Way
**Requirements are the "what"** — they state what the system should do without specifying implementation.
**Scenarios are the "when"** — they provide concrete examples that can be verified. Good scenarios:
- Are testable (you could write an automated test for them)
- Cover both happy path and edge cases
- Use Given/When/Then or similar structured format
**RFC 2119 keywords** (SHALL, MUST, SHOULD, MAY) communicate intent:
- **MUST/SHALL** — absolute requirement
- **SHOULD** — recommended, but exceptions exist
- **MAY** — optional
### What a Spec Is (and Is Not)
A spec is a **behavior contract**, not an implementation plan.
Good spec content:
- Observable behavior users or downstream systems rely on
- Inputs, outputs, and error conditions
- External constraints (security, privacy, reliability, compatibility)
- Scenarios that can be tested or explicitly validated
Avoid in specs:
- Internal class/function names
- Library or framework choices
- Step-by-step implementation details
- Detailed execution plans (those belong in `design.md` or `tasks.md`)
Quick test:
- If implementation can change without changing externally visible behavior, it likely does not belong in the spec.
### Keep It Lightweight: Progressive Rigor
OpenSpec aims to avoid bureaucracy. Use the lightest level that still makes the change verifiable.
**Lite spec (default):**
- Short behavior-first requirements
- Clear scope and non-goals
- A few concrete acceptance checks
**Full spec (for higher risk):**
- Cross-team or cross-repo changes
- API/contract changes, migrations, security/privacy concerns
- Changes where ambiguity is likely to cause expensive rework
Most changes should stay in Lite mode.
### Human + Agent Collaboration
In many teams, humans explore and agents draft artifacts. The intended loop is:
1. Human provides intent, context, and constraints.
2. Agent converts this into behavior-first requirements and scenarios.
3. Agent keeps implementation detail in `design.md` and `tasks.md`, not `spec.md`.
4. Validation confirms structure and clarity before implementation.
This keeps specs readable for humans and consistent for agents.
## Changes
A change is a proposed modification to your system, packaged as a folder with everything needed to understand and implement it.
### Change Structure
```
openspec/changes/add-dark-mode/
├── proposal.md # Why and what
├── design.md # How (technical approach)
├── tasks.md # Implementation checklist
├── .openspec.yaml # Change metadata (optional)
└── specs/ # Delta specs
└── ui/
└── spec.md # What's changing in ui/spec.md
```
Each change is self-contained. It has:
- **Artifacts** — documents that capture intent, design, and tasks
- **Delta specs** — specifications for what's being added, modified, or removed
- **Metadata** — optional configuration for this specific change
### Why Changes Are Folders
Packaging a change as a folder has several benefits:
1. **Everything together.** Proposal, design, tasks, and specs live in one place. No hunting through different locations.
2. **Parallel work.** Multiple changes can exist simultaneously without conflicting. Work on `add-dark-mode` while `fix-auth-bug` is also in progress.
3. **Clean history.** When archived, changes move to `changes/archive/` with their full context preserved. You can look back and understand not just what changed, but why.
4. **Review-friendly.** A change folder is easy to review — open it, read the proposal, check the design, see the spec deltas.
## Artifacts
Artifacts are the documents within a change that guide the work.
### The Artifact Flow
```
proposal ──────► specs ──────► design ──────► tasks ──────► implement
│ │ │ │
why what how steps
+ scope changes approach to take
```
Artifacts build on each other. Each artifact provides context for the next.
### Artifact Types
#### Proposal (`proposal.md`)
The proposal captures **intent**, **scope**, and **approach** at a high level.
```markdown
# Proposal: Add Dark Mode
## Intent
Users have requested a dark mode option to reduce eye strain
during nighttime usage and match system preferences.
## Scope
In scope:
- Theme toggle in settings
- System preference detection
- Persist preference in localStorage
Out of scope:
- Custom color themes (future work)
- Per-page theme overrides
## Approach
Use CSS custom properties for theming with a React context
for state management. Detect system preference on first load,
allow manual override.
```
**When to update the proposal:**
- Scope changes (narrowing or expanding)
- Intent clarifies (better understanding of the problem)
- Approach fundamentally shifts
#### Specs (delta specs in `specs/`)
Delta specs describe **what's changing** relative to the current specs. See [Delta Specs](#delta-specs) below.
#### Design (`design.md`)
The design captures **technical approach** and **architecture decisions**.
````markdown
# Design: Add Dark Mode
## Technical Approach
Theme state managed via React Context to avoid prop drilling.
CSS custom properties enable runtime switching without class toggling.
## Architecture Decisions
### Decision: Context over Redux
Using React Context for theme state because:
- Simple binary state (light/dark)
- No complex state transitions
- Avoids adding Redux dependency
### Decision: CSS Custom Properties
Using CSS variables instead of CSS-in-JS because:
- Works with existing stylesheet
- No runtime overhead
- Browser-native solution
## Data Flow
```
ThemeProvider (context)
│
▼
ThemeToggle ◄──► localStorage
│
▼
CSS Variables (applied to :root)
```
## File Changes
- `src/contexts/ThemeContext.tsx` (new)
- `src/components/ThemeToggle.tsx` (new)
- `src/styles/globals.css` (modified)
````
**When to update the design:**
- Implementation reveals the approach won't work
- Better solution discovered
- Dependencies or constraints change
#### Tasks (`tasks.md`)
Tasks are the **implementation checklist** — concrete steps with checkboxes.
```markdown
# Tasks
## 1. Theme Infrastructure
- [ ] 1.1 Create ThemeContext with light/dark state
- [ ] 1.2 Add CSS custom properties for colors
- [ ] 1.3 Implement localStorage persistence
- [ ] 1.4 Add system preference detection
## 2. UI Components
- [ ] 2.1 Create ThemeToggle component
- [ ] 2.2 Add toggle to settings page
- [ ] 2.3 Update Header to include quick toggle
## 3. Styling
- [ ] 3.1 Define dark theme color palette
- [ ] 3.2 Update components to use CSS variables
- [ ] 3.3 Test contrast ratios for accessibility
```
**Task best practices:**
- Group related tasks under headings
- Use hierarchical numbering (1.1, 1.2, etc.)
- Keep tasks small enough to complete in one session
- Check tasks off as you complete them
## Delta Specs
Delta specs are the key concept that makes OpenSpec work for brownfield development. They describe **what's changing** rather than restating the entire spec.
### The Format
```markdown
# Delta for Auth
## ADDED Requirements
### Requirement: Two-Factor Authentication
The system MUST support TOTP-based two-factor authentication.
#### Scenario: 2FA enrollment
- GIVEN a user without 2FA enabled
- WHEN the user enables 2FA in settings
- THEN a QR code is displayed for authenticator app setup
- AND the user must verify with a code before activation
#### Scenario: 2FA login
- GIVEN a user with 2FA enabled
- WHEN the user submits valid credentials
- THEN an OTP challenge is presented
- AND login completes only after valid OTP
## MODIFIED Requirements
### Requirement: Session Expiration
The system MUST expire sessions after 15 minutes of inactivity.
(Previously: 30 minutes)
#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 15 minutes pass without activity
- THEN the session is invalidated
## REMOVED Requirements
### Requirement: Remember Me
(Deprecated in favor of 2FA. Users should re-authenticate each session.)
```
### Delta Sections
| Section | Meaning | What Happens on Archive |
|---------|---------|------------------------|
| `## ADDED Requirements` | New behavior | Appended to main spec |
| `## MODIFIED Requirements` | Changed behavior | Replaces existing requirement |
| `## REMOVED Requirements` | Deprecated behavior | Deleted from main spec |
### Why Deltas Instead of Full Specs
**Clarity.** A delta shows exactly what's changing. Reading a full spec, you'd have to diff it mentally against the current version.
**Conflict avoidance.** Two changes can touch the same spec file without conflicting, as long as they modify different requirements.
**Review efficiency.** Reviewers see the change, not the unchanged context. Focus on what matters.
**Brownfield fit.** Most work modifies existing behavior. Deltas make modifications first-class, not an afterthought.
## Schemas
Schemas define the artifact types and their dependencies for a workflow.
### How Schemas Work
```yaml
# openspec/schemas/spec-driven/schema.yaml
name: spec-driven
artifacts:
- id: proposal
generates: proposal.md
requires: [] # No dependencies, can create first
- id: specs
generates: specs/**/*.md
requires: [proposal] # Needs proposal before creating
- id: design
generates: design.md
requires: [proposal] # Can create in parallel with specs
- id: tasks
generates: tasks.md
requires: [specs, design] # Needs both specs and design first
```
**Artifacts form a dependency graph:**
```
proposal
(root node)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)
```
**Dependencies are enablers, not gates.** They show what's possible to create, not what you must create next. You can skip design if you don't need it. You can create specs before or after design — both depend only on proposal.
### Built-in Schemas
**spec-driven** (default)
The standard workflow for spec-driven development:
```
proposal → specs → design → tasks → implement
```
Best for: Most feature work where you want to agree on specs before implementation.
### Custom Schemas
Create custom schemas for your team's workflow:
```bash
# Create from scratch
openspec schema init research-first
# Or fork an existing one
openspec schema fork spec-driven research-first
```
**Example custom schema:**
```yaml
# openspec/schemas/research-first/schema.yaml
name: research-first
artifacts:
- id: research
generates: research.md
requires: [] # Do research first
- id: proposal
generates: proposal.md
requires: [research] # Proposal informed by research
- id: tasks
generates: tasks.md
requires: [proposal] # Skip specs/design, go straight to tasks
```
See [Customization](customization.md) for full details on creating and using custom schemas.
## Archive
Archiving completes a change by merging its delta specs into the main specs and preserving the change for history.
### What Happens When You Archive
```
Before archive:
openspec/
├── specs/
│ └── auth/
│ └── spec.md ◄────────────────┐
└── changes/ │
└── add-2fa/ │
├── proposal.md │
├── design.md │ merge
├── tasks.md │
└── specs/ │
└── auth/ │
└── spec.md ─────────┘
After archive:
openspec/
├── specs/
│ └── auth/
│ └── spec.md # Now includes 2FA requirements
└── changes/
└── archive/
└── 2025-01-24-add-2fa/ # Preserved for history
├── proposal.md
├── design.md
├── tasks.md
└── specs/
└── auth/
└── spec.md
```
### The Archive Process
1. **Merge deltas.** Each delta spec section (ADDED/MODIFIED/REMOVED) is applied to the corresponding main spec.
2. **Move to archive.** The change folder moves to `changes/archive/` with a date prefix for chronological ordering.
3. **Preserve context.** All artifacts remain intact in the archive. You can always look back to understand why a change was made.
### Why Archive Matters
**Clean state.** Active changes (`changes/`) shows only work in progress. Completed work moves out of the way.
**Audit trail.** The archive preserves the full context of every change — not just what changed, but the proposal explaining why, the design explaining how, and the tasks showing the work done.
**Spec evolution.** Specs grow organically as changes are archived. Each archive merges its deltas, building up a comprehensive specification over time.
## How It All Fits Together
```
┌──────────────────────────────────────────────────────────────────────────────┐
│ OPENSPEC FLOW │
│ │
│ ┌────────────────┐ │
│ │ 1. START │ /opsx:propose (core) or /opsx:new (expanded) │
│ │ CHANGE │ │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 2. CREATE │ /opsx:ff or /opsx:continue (expanded workflow) │
│ │ ARTIFACTS │ Creates proposal → specs → design → tasks │
│ │ │ (based on schema dependencies) │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 3. IMPLEMENT │ /opsx:apply │
│ │ TASKS │ Work through tasks, checking them off │
│ │ │◄──── Update artifacts as you learn │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ 4. VERIFY │ /opsx:verify (optional) │
│ │ WORK │ Check implementation matches specs │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ ┌──────────────────────────────────────────────┐ │
│ │ 5. ARCHIVE │────►│ Delta specs merge into main specs │ │
│ │ CHANGE │ │ Change folder moves to archive/ │ │
│ └────────────────┘ │ Specs are now the updated source of truth │ │
│ └──────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
```
**The virtuous cycle:**
1. Specs describe current behavior
2. Changes propose modifications (as deltas)
3. Implementation makes the changes real
4. Archive merges deltas into specs
5. Specs now describe the new behavior
6. Next change builds on updated specs
## Glossary
| Term | Definition |
|------|------------|
| **Artifact** | A document within a change (proposal, design, tasks, or delta specs) |
| **Archive** | The process of completing a change and merging its deltas into main specs |
| **Change** | A proposed modification to the system, packaged as a folder with artifacts |
| **Delta spec** | A spec that describes changes (ADDED/MODIFIED/REMOVED) relative to current specs |
| **Domain** | A logical grouping for specs (e.g., `auth/`, `payments/`) |
| **Requirement** | A specific behavior the system must have |
| **Scenario** | A concrete example of a requirement, typically in Given/When/Then format |
| **Schema** | A definition of artifact types and their dependencies |
| **Spec** | A specification describing system behavior, containing requirements and scenarios |
| **Source of truth** | The `openspec/specs/` directory, containing the current agreed-upon behavior |
## Next Steps
- [Getting Started](getting-started.md) - Practical first steps
- [Workflows](workflows.md) - Common patterns and when to use each
- [Commands](commands.md) - Full command reference
- [Customization](customization.md) - Create custom schemas and configure your project
+342
View File
@@ -0,0 +1,342 @@
# Customization
OpenSpec provides three levels of customization:
| Level | What it does | Best for |
|-------|--------------|----------|
| **Project Config** | Set defaults, inject context/rules | Most teams |
| **Custom Schemas** | Define your own workflow artifacts | Teams with unique processes |
| **Global Overrides** | Share schemas across all projects | Power users |
---
## Project Configuration
The `openspec/config.yaml` file is the easiest way to customize OpenSpec for your team. It lets you:
- **Set a default schema** - Skip `--schema` on every command
- **Inject project context** - AI sees your tech stack, conventions, etc.
- **Add per-artifact rules** - Custom rules for specific artifacts
### Quick Setup
```bash
openspec init
```
This walks you through creating a config interactively. Or create one manually:
```yaml
# openspec/config.yaml
schema: spec-driven
context: |
Tech stack: TypeScript, React, Node.js, PostgreSQL
API style: RESTful, documented in docs/api.md
Testing: Jest + React Testing Library
We value backwards compatibility for all public APIs
rules:
proposal:
- Include rollback plan
- Identify affected teams
specs:
- Use Given/When/Then format
- Reference existing patterns before inventing new ones
```
### How It Works
**Default schema:**
```bash
# Without config
openspec new change my-feature --schema spec-driven
# With config - schema is automatic
openspec new change my-feature
```
**Context and rules injection:**
When generating any artifact, your context and rules are injected into the AI prompt:
```xml
<context>
Tech stack: TypeScript, React, Node.js, PostgreSQL
...
</context>
<rules>
- Include rollback plan
- Identify affected teams
</rules>
<template>
[Schema's built-in template]
</template>
```
- **Context** appears in ALL artifacts
- **Rules** ONLY appear for the matching artifact
### Schema Resolution Order
When OpenSpec needs a schema, it checks in this order:
1. CLI flag: `--schema <name>`
2. Change metadata (`.openspec.yaml` in the change folder)
3. Project config (`openspec/config.yaml`)
4. Default (`spec-driven`)
---
## Custom Schemas
When project config isn't enough, create your own schema with a completely custom workflow. Custom schemas live in your project's `openspec/schemas/` directory and are version-controlled with your code.
```text
your-project/
├── openspec/
│ ├── config.yaml # Project config
│ ├── schemas/ # Custom schemas live here
│ │ └── my-workflow/
│ │ ├── schema.yaml
│ │ └── templates/
│ └── changes/ # Your changes
└── src/
```
### Fork an Existing Schema
The fastest way to customize is to fork a built-in schema:
```bash
openspec schema fork spec-driven my-workflow
```
This copies the entire `spec-driven` schema to `openspec/schemas/my-workflow/` where you can edit it freely.
**What you get:**
```text
openspec/schemas/my-workflow/
├── schema.yaml # Workflow definition
└── templates/
├── proposal.md # Template for proposal artifact
├── spec.md # Template for specs
├── design.md # Template for design
└── tasks.md # Template for tasks
```
Now edit `schema.yaml` to change the workflow, or edit templates to change what AI generates.
### Create a Schema from Scratch
For a completely fresh workflow:
```bash
# Interactive
openspec schema init research-first
# Non-interactive
openspec schema init rapid \
--description "Rapid iteration workflow" \
--artifacts "proposal,tasks" \
--default
```
### Schema Structure
A schema defines the artifacts in your workflow and how they depend on each other:
```yaml
# openspec/schemas/my-workflow/schema.yaml
name: my-workflow
version: 1
description: My team's custom workflow
artifacts:
- id: proposal
generates: proposal.md
description: Initial proposal document
template: proposal.md
instruction: |
Create a proposal that explains WHY this change is needed.
Focus on the problem, not the solution.
requires: []
- id: design
generates: design.md
description: Technical design
template: design.md
instruction: |
Create a design document explaining HOW to implement.
requires:
- proposal # Can't create design until proposal exists
- id: tasks
generates: tasks.md
description: Implementation checklist
template: tasks.md
requires:
- design
apply:
requires: [tasks]
tracks: tasks.md
```
**Key fields:**
| Field | Purpose |
|-------|---------|
| `id` | Unique identifier, used in commands and rules |
| `generates` | Output filename (supports globs like `specs/**/*.md`) |
| `template` | Template file in `templates/` directory |
| `instruction` | AI instructions for creating this artifact |
| `requires` | Dependencies - which artifacts must exist first |
### Templates
Templates are markdown files that guide the AI. They're injected into the prompt when creating that artifact.
```markdown
<!-- templates/proposal.md -->
## Why
<!-- Explain the motivation for this change. What problem does this solve? -->
## What Changes
<!-- Describe what will change. Be specific about new capabilities or modifications. -->
## Impact
<!-- Affected code, APIs, dependencies, systems -->
```
Templates can include:
- Section headers the AI should fill in
- HTML comments with guidance for the AI
- Example formats showing expected structure
### Validate Your Schema
Before using a custom schema, validate it:
```bash
openspec schema validate my-workflow
```
This checks:
- `schema.yaml` syntax is correct
- All referenced templates exist
- No circular dependencies
- Artifact IDs are valid
### Use Your Custom Schema
Once created, use your schema with:
```bash
# Specify on command
openspec new change feature --schema my-workflow
# Or set as default in config.yaml
schema: my-workflow
```
### Debug Schema Resolution
Not sure which schema is being used? Check with:
```bash
# See where a specific schema resolves from
openspec schema which my-workflow
# List all available schemas
openspec schema which --all
```
Output shows whether it's from your project, user directory, or the package:
```text
Schema: my-workflow
Source: project
Path: /path/to/project/openspec/schemas/my-workflow
```
---
> **Note:** OpenSpec also supports user-level schemas at `~/.local/share/openspec/schemas/` for sharing across projects, but project-level schemas in `openspec/schemas/` are recommended since they're version-controlled with your code.
---
## Examples
### Rapid Iteration Workflow
A minimal workflow for quick iterations:
```yaml
# openspec/schemas/rapid/schema.yaml
name: rapid
version: 1
description: Fast iteration with minimal overhead
artifacts:
- id: proposal
generates: proposal.md
description: Quick proposal
template: proposal.md
instruction: |
Create a brief proposal for this change.
Focus on what and why, skip detailed specs.
requires: []
- id: tasks
generates: tasks.md
description: Implementation checklist
template: tasks.md
requires: [proposal]
apply:
requires: [tasks]
tracks: tasks.md
```
### Adding a Review Artifact
Fork the default and add a review step:
```bash
openspec schema fork spec-driven with-review
```
Then edit `schema.yaml` to add:
```yaml
- id: review
generates: review.md
description: Pre-implementation review checklist
template: review.md
instruction: |
Create a review checklist based on the design.
Include security, performance, and testing considerations.
requires:
- design
- id: tasks
# ... existing tasks config ...
requires:
- specs
- design
- review # Now tasks require review too
```
---
## See Also
- [CLI Reference: Schema Commands](cli.md#schema-commands) - Full command documentation
+253
View File
@@ -0,0 +1,253 @@
# Getting Started
This guide explains how OpenSpec works after you've installed and initialized it. For installation instructions, see the [main README](../README.md#quick-start).
## How It Works
OpenSpec helps you and your AI coding assistant agree on what to build before any code is written.
**Default quick path (core profile):**
```text
/opsx:propose ──► /opsx:apply ──► /opsx:archive
```
**Expanded path (custom workflow selection):**
```text
/opsx:new ──► /opsx:ff or /opsx:continue ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
```
The default global profile is `core`, which includes `propose`, `explore`, `apply`, and `archive`. You can enable the expanded workflow commands with `openspec config profile` and then `openspec update`.
## What OpenSpec Creates
After running `openspec init`, your project has this structure:
```
openspec/
├── specs/ # Source of truth (your system's behavior)
│ └── <domain>/
│ └── spec.md
├── changes/ # Proposed updates (one folder per change)
│ └── <change-name>/
│ ├── proposal.md
│ ├── design.md
│ ├── tasks.md
│ └── specs/ # Delta specs (what's changing)
│ └── <domain>/
│ └── spec.md
└── config.yaml # Project configuration (optional)
```
**Two key directories:**
- **`specs/`** - The source of truth. These specs describe how your system currently behaves. Organized by domain (e.g., `specs/auth/`, `specs/payments/`).
- **`changes/`** - Proposed modifications. Each change gets its own folder with all related artifacts. When a change is complete, its specs merge into the main `specs/` directory.
## Understanding Artifacts
Each change folder contains artifacts that guide the work:
| Artifact | Purpose |
|----------|---------|
| `proposal.md` | The "why" and "what" - captures intent, scope, and approach |
| `specs/` | Delta specs showing ADDED/MODIFIED/REMOVED requirements |
| `design.md` | The "how" - technical approach and architecture decisions |
| `tasks.md` | Implementation checklist with checkboxes |
**Artifacts build on each other:**
```
proposal ──► specs ──► design ──► tasks ──► implement
▲ ▲ ▲ │
└───────────┴──────────┴────────────────────┘
update as you learn
```
You can always go back and refine earlier artifacts as you learn more during implementation.
## How Delta Specs Work
Delta specs are the key concept in OpenSpec. They show what's changing relative to your current specs.
### The Format
Delta specs use sections to indicate the type of change:
```markdown
# Delta for Auth
## ADDED Requirements
### Requirement: Two-Factor Authentication
The system MUST require a second factor during login.
#### Scenario: OTP required
- GIVEN a user with 2FA enabled
- WHEN the user submits valid credentials
- THEN an OTP challenge is presented
## MODIFIED Requirements
### Requirement: Session Timeout
The system SHALL expire sessions after 30 minutes of inactivity.
(Previously: 60 minutes)
#### Scenario: Idle timeout
- GIVEN an authenticated session
- WHEN 30 minutes pass without activity
- THEN the session is invalidated
## REMOVED Requirements
### Requirement: Remember Me
(Deprecated in favor of 2FA)
```
### What Happens on Archive
When you archive a change:
1. **ADDED** requirements are appended to the main spec
2. **MODIFIED** requirements replace the existing version
3. **REMOVED** requirements are deleted from the main spec
The change folder moves to `openspec/changes/archive/` for audit history.
## Example: Your First Change
Let's walk through adding dark mode to an application.
### 1. Start the Change (Default)
```text
You: /opsx:propose add-dark-mode
AI: Created openspec/changes/add-dark-mode/
✓ proposal.md — why we're doing this, what's changing
✓ specs/ — requirements and scenarios
✓ design.md — technical approach
✓ tasks.md — implementation checklist
Ready for implementation!
```
If you've enabled the expanded workflow profile, you can also do this as two steps: `/opsx:new` then `/opsx:ff` (or `/opsx:continue` incrementally).
### 2. What Gets Created
**proposal.md** - Captures the intent:
```markdown
# Proposal: Add Dark Mode
## Intent
Users have requested a dark mode option to reduce eye strain
during nighttime usage.
## Scope
- Add theme toggle in settings
- Support system preference detection
- Persist preference in localStorage
## Approach
Use CSS custom properties for theming with a React context
for state management.
```
**specs/ui/spec.md** - Delta showing new requirements:
```markdown
# Delta for UI
## ADDED Requirements
### Requirement: Theme Selection
The system SHALL allow users to choose between light and dark themes.
#### Scenario: Manual toggle
- GIVEN a user on any page
- WHEN the user clicks the theme toggle
- THEN the theme switches immediately
- AND the preference persists across sessions
#### Scenario: System preference
- GIVEN a user with no saved preference
- WHEN the application loads
- THEN the system's preferred color scheme is used
```
**tasks.md** - Implementation checklist:
```markdown
# Tasks
## 1. Theme Infrastructure
- [ ] 1.1 Create ThemeContext with light/dark state
- [ ] 1.2 Add CSS custom properties for colors
- [ ] 1.3 Implement localStorage persistence
## 2. UI Components
- [ ] 2.1 Create ThemeToggle component
- [ ] 2.2 Add toggle to settings page
- [ ] 2.3 Update Header to include quick toggle
## 3. Styling
- [ ] 3.1 Define dark theme color palette
- [ ] 3.2 Update components to use CSS variables
```
### 3. Implement
```
You: /opsx:apply
AI: Working through tasks...
✓ 1.1 Created ThemeContext with light/dark state
✓ 1.2 Added CSS custom properties to globals.css
✓ 1.3 Implemented localStorage persistence
✓ 2.1 Created ThemeToggle component
...
All tasks complete!
```
During implementation, if you discover the design needs adjustment, just update the artifact and continue.
### 4. Archive
```
You: /opsx:archive
AI: Archiving add-dark-mode...
✓ Merged specs into openspec/specs/ui/spec.md
✓ Moved to openspec/changes/archive/2025-01-24-add-dark-mode/
Done! Ready for the next feature.
```
Your delta specs are now part of the main specs, documenting how your system works.
## Verifying and Reviewing
Use the CLI to check on your changes:
```bash
# List active changes
openspec list
# View change details
openspec show add-dark-mode
# Validate spec formatting
openspec validate add-dark-mode
# Interactive dashboard
openspec view
```
## Next Steps
- [Workflows](workflows.md) - Common patterns and when to use each command
- [Commands](commands.md) - Full reference for all slash commands
- [Concepts](concepts.md) - Deeper understanding of specs, changes, and schemas
- [Customization](customization.md) - Make OpenSpec work your way
+79
View File
@@ -0,0 +1,79 @@
# Installation
## Prerequisites
- **Node.js 20.19.0 or higher** — Check your version: `node --version`
## Package Managers
### npm
```bash
npm install -g @fission-ai/openspec@latest
```
### pnpm
```bash
pnpm add -g @fission-ai/openspec@latest
```
### yarn
```bash
yarn global add @fission-ai/openspec@latest
```
### bun
```bash
bun add -g @fission-ai/openspec@latest
```
## Nix
Run OpenSpec directly without installation:
```bash
nix run github:Fission-AI/OpenSpec -- init
```
Or install to your profile:
```bash
nix profile install github:Fission-AI/OpenSpec
```
Or add to your development environment in `flake.nix`:
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
openspec.url = "github:Fission-AI/OpenSpec";
};
outputs = { nixpkgs, openspec, ... }: {
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
buildInputs = [ openspec.packages.x86_64-linux.default ];
};
};
}
```
## Verify Installation
```bash
openspec --version
```
## Next Steps
After installing, initialize OpenSpec in your project:
```bash
cd your-project
openspec init
```
See [Getting Started](getting-started.md) for a full walkthrough.
+595
View File
@@ -0,0 +1,595 @@
# Migrating to OPSX
This guide helps you transition from the legacy OpenSpec workflow to OPSX. The migration is designed to be smooth—your existing work is preserved, and the new system offers more flexibility.
## What's Changing?
OPSX replaces the old phase-locked workflow with a fluid, action-based approach. Here's the key shift:
| Aspect | Legacy | OPSX |
|--------|--------|------|
| **Commands** | `/openspec:proposal`, `/openspec:apply`, `/openspec:archive` | Default: `/opsx:propose`, `/opsx:apply`, `/opsx:archive` (expanded workflow commands optional) |
| **Workflow** | Create all artifacts at once | Create incrementally or all at once—your choice |
| **Going back** | Awkward phase gates | Natural—update any artifact anytime |
| **Customization** | Fixed structure | Schema-driven, fully hackable |
| **Configuration** | `CLAUDE.md` with markers + `project.md` | Clean config in `openspec/config.yaml` |
**The philosophy change:** Work isn't linear. OPSX stops pretending it is.
---
## Before You Begin
### Your Existing Work Is Safe
The migration process is designed with preservation in mind:
- **Active changes in `openspec/changes/`** — Completely preserved. You can continue them with OPSX commands.
- **Archived changes** — Untouched. Your history remains intact.
- **Main specs in `openspec/specs/`** — Untouched. These are your source of truth.
- **Your content in CLAUDE.md, AGENTS.md, etc.** — Preserved. Only the OpenSpec marker blocks are removed; everything you wrote stays.
### What Gets Removed
Only OpenSpec-managed files that are being replaced:
| What | Why |
|------|-----|
| Legacy slash command directories/files | Replaced by the new skills system |
| `openspec/AGENTS.md` | Obsolete workflow trigger |
| OpenSpec markers in `CLAUDE.md`, `AGENTS.md`, etc. | No longer needed |
**Legacy command locations by tool** (examples—your tool may vary):
- Claude Code: `.claude/commands/openspec/`
- Cursor: `.cursor/commands/openspec-*.md`
- Windsurf: `.windsurf/workflows/openspec-*.md`
- Cline: `.clinerules/workflows/openspec-*.md`
- Roo: `.roo/commands/openspec-*.md`
- GitHub Copilot: `.github/prompts/openspec-*.prompt.md` (IDE extensions only; not supported in Copilot CLI)
- And others (Augment, Continue, Amazon Q, etc.)
The migration detects whichever tools you have configured and cleans up their legacy files.
The removal list may seem long, but these are all files that OpenSpec originally created. Your own content is never deleted.
### What Needs Your Attention
One file requires manual migration:
**`openspec/project.md`** — This file isn't deleted automatically because it may contain project context you've written. You'll need to:
1. Review its contents
2. Move useful context to `openspec/config.yaml` (see guidance below)
3. Delete the file when ready
**Why we made this change:**
The old `project.md` was passive—agents might read it, might not, might forget what they read. We found reliability was inconsistent.
The new `config.yaml` context is **actively injected into every OpenSpec planning request**. This means your project conventions, tech stack, and rules are always present when the AI is creating artifacts. Higher reliability.
**The tradeoff:**
Because context is injected into every request, you'll want to be concise. Focus on what really matters:
- Tech stack and key conventions
- Non-obvious constraints the AI needs to know
- Rules that frequently got ignored before
Don't worry about getting it perfect. We're still learning what works best here, and we'll be improving how context injection works as we experiment.
---
## Running the Migration
Both `openspec init` and `openspec update` detect legacy files and guide you through the same cleanup process. Use whichever fits your situation:
- New installs default to profile `core` (`propose`, `explore`, `apply`, `archive`).
- Migrated installs preserve your previously installed workflows by writing a `custom` profile when needed.
### Using `openspec init`
Run this if you want to add new tools or reconfigure which tools are set up:
```bash
openspec init
```
The init command detects legacy files and guides you through cleanup:
```
Upgrading to the new OpenSpec
OpenSpec now uses agent skills, the emerging standard across coding
agents. This simplifies your setup while keeping everything working
as before.
Files to remove
No user content to preserve:
• .claude/commands/openspec/
• openspec/AGENTS.md
Files to update
OpenSpec markers will be removed, your content preserved:
• CLAUDE.md
• AGENTS.md
Needs your attention
• openspec/project.md
We won't delete this file. It may contain useful project context.
The new openspec/config.yaml has a "context:" section for planning
context. This is included in every OpenSpec request and works more
reliably than the old project.md approach.
Review project.md, move any useful content to config.yaml's context
section, then delete the file when ready.
? Upgrade and clean up legacy files? (Y/n)
```
**What happens when you say yes:**
1. Legacy slash command directories are removed
2. OpenSpec markers are stripped from `CLAUDE.md`, `AGENTS.md`, etc. (your content stays)
3. `openspec/AGENTS.md` is deleted
4. New skills are installed in `.claude/skills/`
5. `openspec/config.yaml` is created with a default schema
### Using `openspec update`
Run this if you just want to migrate and refresh your existing tools to the latest version:
```bash
openspec update
```
The update command also detects and cleans up legacy artifacts, then refreshes generated skills/commands to match your current profile and delivery settings.
### Non-Interactive / CI Environments
For scripted migrations:
```bash
openspec init --force --tools claude
```
The `--force` flag skips prompts and auto-accepts cleanup.
---
## Migrating project.md to config.yaml
The old `openspec/project.md` was a freeform markdown file for project context. The new `openspec/config.yaml` is structured and—critically—**injected into every planning request** so your conventions are always present when the AI works.
### Before (project.md)
```markdown
# Project Context
This is a TypeScript monorepo using React and Node.js.
We use Jest for testing and follow strict ESLint rules.
Our API is RESTful and documented in docs/api.md.
## Conventions
- All public APIs must maintain backwards compatibility
- New features should include tests
- Use Given/When/Then format for specifications
```
### After (config.yaml)
```yaml
schema: spec-driven
context: |
Tech stack: TypeScript, React, Node.js
Testing: Jest with React Testing Library
API: RESTful, documented in docs/api.md
We maintain backwards compatibility for all public APIs
rules:
proposal:
- Include rollback plan for risky changes
specs:
- Use Given/When/Then format for scenarios
- Reference existing patterns before inventing new ones
design:
- Include sequence diagrams for complex flows
```
### Key Differences
| project.md | config.yaml |
|------------|-------------|
| Freeform markdown | Structured YAML |
| One blob of text | Separate context and per-artifact rules |
| Unclear when it's used | Context appears in ALL artifacts; rules appear in matching artifacts only |
| No schema selection | Explicit `schema:` field sets default workflow |
### What to Keep, What to Drop
When migrating, be selective. Ask yourself: "Does the AI need this for *every* planning request?"
**Good candidates for `context:`**
- Tech stack (languages, frameworks, databases)
- Key architectural patterns (monorepo, microservices, etc.)
- Non-obvious constraints ("we can't use library X because...")
- Critical conventions that often get ignored
**Move to `rules:` instead**
- Artifact-specific formatting ("use Given/When/Then in specs")
- Review criteria ("proposals must include rollback plans")
- These only appear for the matching artifact, keeping other requests lighter
**Leave out entirely**
- General best practices the AI already knows
- Verbose explanations that could be summarized
- Historical context that doesn't affect current work
### Migration Steps
1. **Create config.yaml** (if not already created by init):
```yaml
schema: spec-driven
```
2. **Add your context** (be concise—this goes into every request):
```yaml
context: |
Your project background goes here.
Focus on what the AI genuinely needs to know.
```
3. **Add per-artifact rules** (optional):
```yaml
rules:
proposal:
- Your proposal-specific guidance
specs:
- Your spec-writing rules
```
4. **Delete project.md** once you've moved everything useful.
**Don't overthink it.** Start with the essentials and iterate. If you notice the AI missing something important, add it. If context feels bloated, trim it. This is a living document.
### Need Help? Use This Prompt
If you're unsure how to distill your project.md, ask your AI assistant:
```
I'm migrating from OpenSpec's old project.md to the new config.yaml format.
Here's my current project.md:
[paste your project.md content]
Please help me create a config.yaml with:
1. A concise `context:` section (this gets injected into every planning request, so keep it tight—focus on tech stack, key constraints, and conventions that often get ignored)
2. `rules:` for specific artifacts if any content is artifact-specific (e.g., "use Given/When/Then" belongs in specs rules, not global context)
Leave out anything generic that AI models already know. Be ruthless about brevity.
```
The AI will help you identify what's essential vs. what can be trimmed.
---
## The New Commands
Command availability is profile-dependent:
**Default (`core` profile):**
| Command | Purpose |
|---------|---------|
| `/opsx:propose` | Create a change and generate planning artifacts in one step |
| `/opsx:explore` | Think through ideas with no structure |
| `/opsx:apply` | Implement tasks from tasks.md |
| `/opsx:archive` | Finalize and archive the change |
**Expanded workflow (custom selection):**
| Command | Purpose |
|---------|---------|
| `/opsx:new` | Start a new change scaffold |
| `/opsx:continue` | Create the next artifact (one at a time) |
| `/opsx:ff` | Fast-forward—create planning artifacts at once |
| `/opsx:verify` | Validate implementation matches specs |
| `/opsx:sync` | Preview/spec-merge without archiving |
| `/opsx:bulk-archive` | Archive multiple changes at once |
| `/opsx:onboard` | Guided end-to-end onboarding workflow |
Enable expanded commands with `openspec config profile`, then run `openspec update`.
### Command Mapping from Legacy
| Legacy | OPSX Equivalent |
|--------|-----------------|
| `/openspec:proposal` | `/opsx:propose` (default) or `/opsx:new` then `/opsx:ff` (expanded) |
| `/openspec:apply` | `/opsx:apply` |
| `/openspec:archive` | `/opsx:archive` |
### New Capabilities
These capabilities are part of the expanded workflow command set.
**Granular artifact creation:**
```
/opsx:continue
```
Creates one artifact at a time based on dependencies. Use this when you want to review each step.
**Exploration mode:**
```
/opsx:explore
```
Think through ideas with a partner before committing to a change.
---
## Understanding the New Architecture
### From Phase-Locked to Fluid
The legacy workflow forced linear progression:
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ PLANNING │ ───► │ IMPLEMENTING │ ───► │ ARCHIVING │
│ PHASE │ │ PHASE │ │ PHASE │
└──────────────┘ └──────────────┘ └──────────────┘
If you're in implementation and realize the design is wrong?
Too bad. Phase gates don't let you go back easily.
```
OPSX uses actions, not phases:
```
┌───────────────────────────────────────────────┐
│ ACTIONS (not phases) │
│ │
│ new ◄──► continue ◄──► apply ◄──► archive │
│ │ │ │ │ │
│ └──────────┴───────────┴─────────────┘ │
│ any order │
└───────────────────────────────────────────────┘
```
### Dependency Graph
Artifacts form a directed graph. Dependencies are enablers, not gates:
```
proposal
(root node)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)
```
When you run `/opsx:continue`, it checks what's ready and offers the next artifact. You can also create multiple ready artifacts in any order.
### Skills vs Commands
The legacy system used tool-specific command files:
```
.claude/commands/openspec/
├── proposal.md
├── apply.md
└── archive.md
```
OPSX uses the emerging **skills** standard:
```
.claude/skills/
├── openspec-explore/SKILL.md
├── openspec-new-change/SKILL.md
├── openspec-continue-change/SKILL.md
├── openspec-apply-change/SKILL.md
└── ...
```
Skills are recognized across multiple AI coding tools and provide richer metadata.
---
## Continuing Existing Changes
Your in-progress changes work seamlessly with OPSX commands.
**Have an active change from the legacy workflow?**
```
/opsx:apply add-my-feature
```
OPSX reads the existing artifacts and continues from where you left off.
**Want to add more artifacts to an existing change?**
```
/opsx:continue add-my-feature
```
Shows what's ready to create based on what already exists.
**Need to see status?**
```bash
openspec status --change add-my-feature
```
---
## The New Config System
### config.yaml Structure
```yaml
# Required: Default schema for new changes
schema: spec-driven
# Optional: Project context (max 50KB)
# Injected into ALL artifact instructions
context: |
Your project background, tech stack,
conventions, and constraints.
# Optional: Per-artifact rules
# Only injected into matching artifacts
rules:
proposal:
- Include rollback plan
specs:
- Use Given/When/Then format
design:
- Document fallback strategies
tasks:
- Break into 2-hour maximum chunks
```
### Schema Resolution
When determining which schema to use, OPSX checks in order:
1. **CLI flag**: `--schema <name>` (highest priority)
2. **Change metadata**: `.openspec.yaml` in the change directory
3. **Project config**: `openspec/config.yaml`
4. **Default**: `spec-driven`
### Available Schemas
| Schema | Artifacts | Best For |
|--------|-----------|----------|
| `spec-driven` | proposal → specs → design → tasks | Most projects |
List all available schemas:
```bash
openspec schemas
```
### Custom Schemas
Create your own workflow:
```bash
openspec schema init my-workflow
```
Or fork an existing one:
```bash
openspec schema fork spec-driven my-workflow
```
See [Customization](customization.md) for details.
---
## Troubleshooting
### "Legacy files detected in non-interactive mode"
You're running in a CI or non-interactive environment. Use:
```bash
openspec init --force
```
### Commands not appearing after migration
Restart your IDE. Skills are detected at startup.
### "Unknown artifact ID in rules"
Check that your `rules:` keys match your schema's artifact IDs:
- **spec-driven**: `proposal`, `specs`, `design`, `tasks`
Run this to see valid artifact IDs:
```bash
openspec schemas --json
```
### Config not being applied
1. Ensure the file is at `openspec/config.yaml` (not `.yml`)
2. Validate YAML syntax
3. Config changes take effect immediately—no restart needed
### project.md not migrated
The system intentionally preserves `project.md` because it may contain your custom content. Review it manually, move useful parts to `config.yaml`, then delete it.
### Want to see what would be cleaned up?
Run init and decline the cleanup prompt—you'll see the full detection summary without any changes being made.
---
## Quick Reference
### Files After Migration
```
project/
├── openspec/
│ ├── specs/ # Unchanged
│ ├── changes/ # Unchanged
│ │ └── archive/ # Unchanged
│ └── config.yaml # NEW: Project configuration
├── .claude/
│ └── skills/ # NEW: OPSX skills
│ ├── openspec-propose/ # default core profile
│ ├── openspec-explore/
│ ├── openspec-apply-change/
│ └── ... # expanded profile adds new/continue/ff/etc.
├── CLAUDE.md # OpenSpec markers removed, your content preserved
└── AGENTS.md # OpenSpec markers removed, your content preserved
```
### What's Gone
- `.claude/commands/openspec/` — replaced by `.claude/skills/`
- `openspec/AGENTS.md` — obsolete
- `openspec/project.md` — migrate to `config.yaml`, then delete
- OpenSpec marker blocks in `CLAUDE.md`, `AGENTS.md`, etc.
### Command Cheatsheet
```text
/opsx:propose Start quickly (default core profile)
/opsx:apply Implement tasks
/opsx:archive Finish and archive
# Expanded workflow (if enabled):
/opsx:new Scaffold a change
/opsx:continue Create next artifact
/opsx:ff Create planning artifacts
```
---
## Getting Help
- **Discord**: [discord.gg/YctCnvvshC](https://discord.gg/YctCnvvshC)
- **GitHub Issues**: [github.com/Fission-AI/OpenSpec/issues](https://github.com/Fission-AI/OpenSpec/issues)
- **Documentation**: [docs/opsx.md](opsx.md) for the full OPSX reference
+115
View File
@@ -0,0 +1,115 @@
# Multi-Language Guide
Configure OpenSpec to generate artifacts in languages other than English.
## Quick Setup
Add a language instruction to your `openspec/config.yaml`:
```yaml
schema: spec-driven
context: |
Language: Portuguese (pt-BR)
All artifacts must be written in Brazilian Portuguese.
# Your other project context below...
Tech stack: TypeScript, React, Node.js
```
That's it. All generated artifacts will now be in Portuguese.
## Language Examples
### Portuguese (Brazil)
```yaml
context: |
Language: Portuguese (pt-BR)
All artifacts must be written in Brazilian Portuguese.
```
### Spanish
```yaml
context: |
Idioma: Español
Todos los artefactos deben escribirse en español.
```
### Chinese (Simplified)
```yaml
context: |
语言:中文(简体)
所有产出物必须用简体中文撰写。
```
### Japanese
```yaml
context: |
言語:日本語
すべての成果物は日本語で作成してください。
```
### French
```yaml
context: |
Langue : Français
Tous les artefacts doivent être rédigés en français.
```
### German
```yaml
context: |
Sprache: Deutsch
Alle Artefakte müssen auf Deutsch verfasst werden.
```
## Tips
### Handle Technical Terms
Decide how to handle technical terminology:
```yaml
context: |
Language: Japanese
Write in Japanese, but:
- Keep technical terms like "API", "REST", "GraphQL" in English
- Code examples and file paths remain in English
```
### Combine with Other Context
Language settings work alongside your other project context:
```yaml
schema: spec-driven
context: |
Language: Portuguese (pt-BR)
All artifacts must be written in Brazilian Portuguese.
Tech stack: TypeScript, React 18, Node.js 20
Database: PostgreSQL with Prisma ORM
```
## Verification
To verify your language config is working:
```bash
# Check the instructions - should show your language context
openspec instructions proposal --change my-change
# Output will include your language context
```
## Related Documentation
- [Customization Guide](./customization.md) - Project configuration options
- [Workflows Guide](./workflows.md) - Full workflow documentation
+659
View File
@@ -0,0 +1,659 @@
# OPSX Workflow
> Feedback welcome on [Discord](https://discord.gg/YctCnvvshC).
## What Is It?
OPSX is now the standard workflow for OpenSpec.
It's a **fluid, iterative workflow** for OpenSpec changes. No more rigid phases — just actions you can take anytime.
## Why This Exists
The legacy OpenSpec workflow works, but it's **locked down**:
- **Instructions are hardcoded** — buried in TypeScript, you can't change them
- **All-or-nothing** — one big command creates everything, can't test individual pieces
- **Fixed structure** — same workflow for everyone, no customization
- **Black box** — when AI output is bad, you can't tweak the prompts
**OPSX opens it up.** Now anyone can:
1. **Experiment with instructions** — edit a template, see if the AI does better
2. **Test granularly** — validate each artifact's instructions independently
3. **Customize workflows** — define your own artifacts and dependencies
4. **Iterate quickly** — change a template, test immediately, no rebuild
```
Legacy workflow: OPSX:
┌────────────────────────┐ ┌────────────────────────┐
│ Hardcoded in package │ │ schema.yaml │◄── You edit this
│ (can't change) │ │ templates/*.md │◄── Or this
│ ↓ │ │ ↓ │
│ Wait for new release │ │ Instant effect │
│ ↓ │ │ ↓ │
│ Hope it's better │ │ Test it yourself │
└────────────────────────┘ └────────────────────────┘
```
**This is for everyone:**
- **Teams** — create workflows that match how you actually work
- **Power users** — tweak prompts to get better AI outputs for your codebase
- **OpenSpec contributors** — experiment with new approaches without releases
We're all still learning what works best. OPSX lets us learn together.
## The User Experience
**The problem with linear workflows:**
You're "in planning phase", then "in implementation phase", then "done". But real work doesn't work that way. You implement something, realize your design was wrong, need to update specs, continue implementing. Linear phases fight against how work actually happens.
**OPSX approach:**
- **Actions, not phases** — create, implement, update, archive — do any of them anytime
- **Dependencies are enablers** — they show what's possible, not what's required next
```
proposal ──→ specs ──→ design ──→ tasks ──→ implement
```
## Setup
```bash
# Make sure you have openspec installed — skills are automatically generated
openspec init
```
This creates skills in `.claude/skills/` (or equivalent) that AI coding assistants auto-detect.
By default, OpenSpec uses the `core` workflow profile (`propose`, `explore`, `apply`, `archive`). If you want the expanded workflow commands (`new`, `continue`, `ff`, `verify`, `sync`, `bulk-archive`, `onboard`), configure them with `openspec config profile` and apply with `openspec update`.
During setup, you'll be prompted to create a **project config** (`openspec/config.yaml`). This is optional but recommended.
## Project Configuration
Project config lets you set defaults and inject project-specific context into all artifacts.
### Creating Config
Config is created during `openspec init`, or manually:
```yaml
# openspec/config.yaml
schema: spec-driven
context: |
Tech stack: TypeScript, React, Node.js
API conventions: RESTful, JSON responses
Testing: Vitest for unit tests, Playwright for e2e
Style: ESLint with Prettier, strict TypeScript
rules:
proposal:
- Include rollback plan
- Identify affected teams
specs:
- Use Given/When/Then format for scenarios
design:
- Include sequence diagrams for complex flows
```
### Config Fields
| Field | Type | Description |
|-------|------|-------------|
| `schema` | string | Default schema for new changes (e.g., `spec-driven`) |
| `context` | string | Project context injected into all artifact instructions |
| `rules` | object | Per-artifact rules, keyed by artifact ID |
### How It Works
**Schema precedence** (highest to lowest):
1. CLI flag (`--schema <name>`)
2. Change metadata (`.openspec.yaml` in change directory)
3. Project config (`openspec/config.yaml`)
4. Default (`spec-driven`)
**Context injection:**
- Context is prepended to every artifact's instructions
- Wrapped in `<context>...</context>` tags
- Helps AI understand your project's conventions
**Rules injection:**
- Rules are only injected for matching artifacts
- Wrapped in `<rules>...</rules>` tags
- Appear after context, before the template
### Artifact IDs by Schema
**spec-driven** (default):
- `proposal` — Change proposal
- `specs` — Specifications
- `design` — Technical design
- `tasks` — Implementation tasks
### Config Validation
- Unknown artifact IDs in `rules` generate warnings
- Schema names are validated against available schemas
- Context has a 50KB size limit
- Invalid YAML is reported with line numbers
### Troubleshooting
**"Unknown artifact ID in rules: X"**
- Check artifact IDs match your schema (see list above)
- Run `openspec schemas --json` to see artifact IDs for each schema
**Config not being applied:**
- Ensure file is at `openspec/config.yaml` (not `.yml`)
- Check YAML syntax with a validator
- Config changes take effect immediately (no restart needed)
**Context too large:**
- Context is limited to 50KB
- Summarize or link to external docs instead
## Commands
| Command | What it does |
|---------|--------------|
| `/opsx:propose` | Create a change and generate planning artifacts in one step (default quick path) |
| `/opsx:explore` | Think through ideas, investigate problems, clarify requirements |
| `/opsx:new` | Start a new change scaffold (expanded workflow) |
| `/opsx:continue` | Create the next artifact (expanded workflow) |
| `/opsx:ff` | Fast-forward planning artifacts (expanded workflow) |
| `/opsx:apply` | Implement tasks, updating artifacts as needed |
| `/opsx:verify` | Validate implementation against artifacts (expanded workflow) |
| `/opsx:sync` | Sync delta specs to main (expanded workflow, optional) |
| `/opsx:archive` | Archive when done |
| `/opsx:bulk-archive` | Archive multiple completed changes (expanded workflow) |
| `/opsx:onboard` | Guided walkthrough of an end-to-end change (expanded workflow) |
## Usage
### Explore an idea
```
/opsx:explore
```
Think through ideas, investigate problems, compare options. No structure required - just a thinking partner. When insights crystallize, transition to `/opsx:propose` (default) or `/opsx:new`/`/opsx:ff` (expanded).
### Start a new change
```
/opsx:propose
```
Creates the change and generates planning artifacts needed before implementation.
If you've enabled expanded workflows, you can instead use:
```text
/opsx:new # scaffold only
/opsx:continue # create one artifact at a time
/opsx:ff # create all planning artifacts at once
```
### Create artifacts
```
/opsx:continue
```
Shows what's ready to create based on dependencies, then creates one artifact. Use repeatedly to build up your change incrementally.
```
/opsx:ff add-dark-mode
```
Creates all planning artifacts at once. Use when you have a clear picture of what you're building.
### Implement (the fluid part)
```
/opsx:apply
```
Works through tasks, checking them off as you go. If you're juggling multiple changes, you can run `/opsx:apply <name>`; otherwise it should infer from the conversation and prompt you to choose if it can't tell.
### Finish up
```
/opsx:archive # Move to archive when done (prompts to sync specs if needed)
```
## When to Update vs. Start Fresh
You can always edit your proposal or specs before implementation. But when does refining become "this is different work"?
### What a Proposal Captures
A proposal defines three things:
1. **Intent** — What problem are you solving?
2. **Scope** — What's in/out of bounds?
3. **Approach** — How will you solve it?
The question is: which changed, and by how much?
### Update the Existing Change When:
**Same intent, refined execution**
- You discover edge cases you didn't consider
- The approach needs tweaking but the goal is unchanged
- Implementation reveals the design was slightly off
**Scope narrows**
- You realize full scope is too big, want to ship MVP first
- "Add dark mode" → "Add dark mode toggle (system preference in v2)"
**Learning-driven corrections**
- Codebase isn't structured how you thought
- A dependency doesn't work as expected
- "Use CSS variables" → "Use Tailwind's dark: prefix instead"
### Start a New Change When:
**Intent fundamentally changed**
- The problem itself is different now
- "Add dark mode" → "Add comprehensive theme system with custom colors, fonts, spacing"
**Scope exploded**
- Change grew so much it's essentially different work
- Original proposal would be unrecognizable after updates
- "Fix login bug" → "Rewrite auth system"
**Original is completable**
- The original change can be marked "done"
- New work stands alone, not a refinement
- Complete "Add dark mode MVP" → Archive → New change "Enhance dark mode"
### The Heuristics
```
┌─────────────────────────────────────┐
│ Is this the same work? │
└──────────────┬──────────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
Same intent? >50% overlap? Can original
Same problem? Same scope? be "done" without
│ │ these changes?
│ │ │
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
│ │ │ │ │ │
YES NO YES NO NO YES
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
UPDATE NEW UPDATE NEW UPDATE NEW
```
| Test | Update | New Change |
|------|--------|------------|
| **Identity** | "Same thing, refined" | "Different work" |
| **Scope overlap** | >50% overlaps | <50% overlaps |
| **Completion** | Can't be "done" without changes | Can finish original, new work stands alone |
| **Story** | Update chain tells coherent story | Patches would confuse more than clarify |
### The Principle
> **Update preserves context. New change provides clarity.**
>
> Choose update when the history of your thinking is valuable.
> Choose new when starting fresh would be clearer than patching.
Think of it like git branches:
- Keep committing while working on the same feature
- Start a new branch when it's genuinely new work
- Sometimes merge a partial feature and start fresh for phase 2
## What's Different?
| | Legacy (`/openspec:proposal`) | OPSX (`/opsx:*`) |
|---|---|---|
| **Structure** | One big proposal document | Discrete artifacts with dependencies |
| **Workflow** | Linear phases: plan → implement → archive | Fluid actions — do anything anytime |
| **Iteration** | Awkward to go back | Update artifacts as you learn |
| **Customization** | Fixed structure | Schema-driven (define your own artifacts) |
**The key insight:** work isn't linear. OPSX stops pretending it is.
## Architecture Deep Dive
This section explains how OPSX works under the hood and how it compares to the legacy workflow.
Examples in this section use the expanded command set (`new`, `continue`, etc.); default `core` users can map the same flow to `propose → apply → archive`.
### Philosophy: Phases vs Actions
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ LEGACY WORKFLOW │
│ (Phase-Locked, All-or-Nothing) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PLANNING │ ───► │ IMPLEMENTING │ ───► │ ARCHIVING │ │
│ │ PHASE │ │ PHASE │ │ PHASE │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ /openspec:proposal /openspec:apply /openspec:archive │
│ │
│ • Creates ALL artifacts at once │
│ • Can't go back to update specs during implementation │
│ • Phase gates enforce linear progression │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ OPSX WORKFLOW │
│ (Fluid Actions, Iterative) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ ACTIONS (not phases) │ │
│ │ │ │
│ │ new ◄──► continue ◄──► apply ◄──► archive │ │
│ │ │ │ │ │ │ │
│ │ └──────────┴───────────┴───────────┘ │ │
│ │ any order │ │
│ └────────────────────────────────────────────┘ │
│ │
│ • Create artifacts one at a time OR fast-forward │
│ • Update specs/design/tasks during implementation │
│ • Dependencies enable progress, phases don't exist │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### Component Architecture
**Legacy workflow** uses hardcoded templates in TypeScript:
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ LEGACY WORKFLOW COMPONENTS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Hardcoded Templates (TypeScript strings) │
│ │ │
│ ▼ │
│ Tool-specific configurators/adapters │
│ │ │
│ ▼ │
│ Generated Command Files (.claude/commands/openspec/*.md) │
│ │
│ • Fixed structure, no artifact awareness │
│ • Change requires code modification + rebuild │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
**OPSX** uses external schemas and a dependency graph engine:
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ OPSX COMPONENTS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Schema Definitions (YAML) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ name: spec-driven │ │
│ │ artifacts: │ │
│ │ - id: proposal │ │
│ │ generates: proposal.md │ │
│ │ requires: [] ◄── Dependencies │ │
│ │ - id: specs │ │
│ │ generates: specs/**/*.md ◄── Glob patterns │ │
│ │ requires: [proposal] ◄── Enables after proposal │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Artifact Graph Engine │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ • Topological sort (dependency ordering) │ │
│ │ • State detection (filesystem existence) │ │
│ │ • Rich instruction generation (templates + context) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Skill Files (.claude/skills/openspec-*/SKILL.md) │
│ │
│ • Cross-editor compatible (Claude Code, Cursor, Windsurf) │
│ • Skills query CLI for structured data │
│ • Fully customizable via schema files │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### Dependency Graph Model
Artifacts form a directed acyclic graph (DAG). Dependencies are **enablers**, not gates:
```
proposal
(root node)
│
┌─────────────┴─────────────┐
│ │
▼ ▼
specs design
(requires: (requires:
proposal) proposal)
│ │
└─────────────┬─────────────┘
│
▼
tasks
(requires:
specs, design)
│
▼
┌──────────────┐
│ APPLY PHASE │
│ (requires: │
│ tasks) │
└──────────────┘
```
**State transitions:**
```
BLOCKED ────────────────► READY ────────────────► DONE
│ │ │
Missing All deps File exists
dependencies are DONE on filesystem
```
### Information Flow
**Legacy workflow** — agent receives static instructions:
```
User: "/openspec:proposal"
│
▼
┌─────────────────────────────────────────┐
│ Static instructions: │
│ • Create proposal.md │
│ • Create tasks.md │
│ • Create design.md │
│ • Create specs/<capability>/spec.md │
│ │
│ No awareness of what exists or │
│ dependencies between artifacts │
└─────────────────────────────────────────┘
│
▼
Agent creates ALL artifacts in one go
```
**OPSX** — agent queries for rich context:
```
User: "/opsx:continue"
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Step 1: Query current state │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ $ openspec status --change "add-auth" --json │ │
│ │ │ │
│ │ { │ │
│ │ "artifacts": [ │ │
│ │ {"id": "proposal", "status": "done"}, │ │
│ │ {"id": "specs", "status": "ready"}, ◄── First ready │ │
│ │ {"id": "design", "status": "ready"}, │ │
│ │ {"id": "tasks", "status": "blocked", "missingDeps": ["specs"]}│ │
│ │ ] │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ Step 2: Get rich instructions for ready artifact │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ $ openspec instructions specs --change "add-auth" --json │ │
│ │ │ │
│ │ { │ │
│ │ "template": "# Specification\n\n## ADDED Requirements...", │ │
│ │ "dependencies": [{"id": "proposal", "path": "...", "done": true}│ │
│ │ "unlocks": ["tasks"] │ │
│ │ } │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ Step 3: Read dependencies → Create ONE artifact → Show what's unlocked │
└──────────────────────────────────────────────────────────────────────────┘
```
### Iteration Model
**Legacy workflow** — awkward to iterate:
```
┌─────────┐ ┌─────────┐ ┌─────────┐
│/proposal│ ──► │ /apply │ ──► │/archive │
└─────────┘ └─────────┘ └─────────┘
│ │
│ ├── "Wait, the design is wrong"
│ │
│ ├── Options:
│ │ • Edit files manually (breaks context)
│ │ • Abandon and start over
│ │ • Push through and fix later
│ │
│ └── No official "go back" mechanism
│
└── Creates ALL artifacts at once
```
**OPSX** — natural iteration:
```
/opsx:new ───► /opsx:continue ───► /opsx:apply ───► /opsx:archive
│ │ │
│ │ ├── "The design is wrong"
│ │ │
│ │ ▼
│ │ Just edit design.md
│ │ and continue!
│ │ │
│ │ ▼
│ │ /opsx:apply picks up
│ │ where you left off
│ │
│ └── Creates ONE artifact, shows what's unlocked
│
└── Scaffolds change, waits for direction
```
### Custom Schemas
Create custom workflows using the schema management commands:
```bash
# Create a new schema from scratch (interactive)
openspec schema init my-workflow
# Or fork an existing schema as a starting point
openspec schema fork spec-driven my-workflow
# Validate your schema structure
openspec schema validate my-workflow
# See where a schema resolves from (useful for debugging)
openspec schema which my-workflow
```
Schemas are stored in `openspec/schemas/` (project-local, version controlled) or `~/.local/share/openspec/schemas/` (user global).
**Schema structure:**
```
openspec/schemas/research-first/
├── schema.yaml
└── templates/
├── research.md
├── proposal.md
└── tasks.md
```
**Example schema.yaml:**
```yaml
name: research-first
artifacts:
- id: research # Added before proposal
generates: research.md
requires: []
- id: proposal
generates: proposal.md
requires: [research] # Now depends on research
- id: tasks
generates: tasks.md
requires: [proposal]
```
**Dependency Graph:**
```
research ──► proposal ──► tasks
```
### Summary
| Aspect | Legacy | OPSX |
|--------|----------|------|
| **Templates** | Hardcoded TypeScript | External YAML + Markdown |
| **Dependencies** | None (all at once) | DAG with topological sort |
| **State** | Phase-based mental model | Filesystem existence |
| **Customization** | Edit source, rebuild | Create schema.yaml |
| **Iteration** | Phase-locked | Fluid, edit anything |
| **Editor Support** | Tool-specific configurator/adapters | Single skills directory |
## Schemas
Schemas define what artifacts exist and their dependencies. Currently available:
- **spec-driven** (default): proposal → specs → design → tasks
```bash
# List available schemas
openspec schemas
# See all schemas with their resolution sources
openspec schema which --all
# Create a new schema interactively
openspec schema init my-workflow
# Fork an existing schema for customization
openspec schema fork spec-driven my-workflow
# Validate schema structure before use
openspec schema validate my-workflow
```
## Tips
- Use `/opsx:explore` to think through an idea before committing to a change
- `/opsx:ff` when you know what you want, `/opsx:continue` when exploring
- During `/opsx:apply`, if something's wrong — fix the artifact, then continue
- Tasks track progress via checkboxes in `tasks.md`
- Check status anytime: `openspec status --change "name"`
## Feedback
This is rough. That's intentional — we're learning what works.
Found a bug? Have ideas? Join us on [Discord](https://discord.gg/YctCnvvshC) or open an issue on [GitHub](https://github.com/Fission-AI/openspec/issues).
+108
View File
@@ -0,0 +1,108 @@
# Supported Tools
OpenSpec works with many AI coding assistants. When you run `openspec init`, OpenSpec configures selected tools using your active profile/workflow selection and delivery mode.
## How It Works
For each selected tool, OpenSpec can install:
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`
- `archive`
You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `sync`, `bulk-archive`, `onboard`) via `openspec config profile`, then run `openspec update`.
## Tool Directory Reference
| Tool (ID) | Skills path pattern | Command path pattern |
|-----------|---------------------|----------------------|
| Amazon Q Developer (`amazon-q`) | `.amazonq/skills/openspec-*/SKILL.md` | `.amazonq/prompts/opsx-<id>.md` |
| Antigravity (`antigravity`) | `.agent/skills/openspec-*/SKILL.md` | `.agent/workflows/opsx-<id>.md` |
| Auggie (`auggie`) | `.augment/skills/openspec-*/SKILL.md` | `.augment/commands/opsx-<id>.md` |
| IBM Bob Shell (`bob`) | `.bob/skills/openspec-*/SKILL.md` | `.bob/commands/opsx-<id>.md` |
| Claude Code (`claude`) | `.claude/skills/openspec-*/SKILL.md` | `.claude/commands/opsx/<id>.md` |
| Cline (`cline`) | `.cline/skills/openspec-*/SKILL.md` | `.clinerules/workflows/opsx-<id>.md` |
| CodeBuddy (`codebuddy`) | `.codebuddy/skills/openspec-*/SKILL.md` | `.codebuddy/commands/opsx/<id>.md` |
| Codex (`codex`) | `.codex/skills/openspec-*/SKILL.md` | `$CODEX_HOME/prompts/opsx-<id>.md`\* |
| ForgeCode (`forgecode`) | `.forge/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
| Continue (`continue`) | `.continue/skills/openspec-*/SKILL.md` | `.continue/prompts/opsx-<id>.prompt` |
| CoStrict (`costrict`) | `.cospec/skills/openspec-*/SKILL.md` | `.cospec/openspec/commands/opsx-<id>.md` |
| Crush (`crush`) | `.crush/skills/openspec-*/SKILL.md` | `.crush/commands/opsx/<id>.md` |
| Cursor (`cursor`) | `.cursor/skills/openspec-*/SKILL.md` | `.cursor/commands/opsx-<id>.md` |
| Factory Droid (`factory`) | `.factory/skills/openspec-*/SKILL.md` | `.factory/commands/opsx-<id>.md` |
| Gemini CLI (`gemini`) | `.gemini/skills/openspec-*/SKILL.md` | `.gemini/commands/opsx/<id>.toml` |
| GitHub Copilot (`github-copilot`) | `.github/skills/openspec-*/SKILL.md` | `.github/prompts/opsx-<id>.prompt.md`\*\* |
| iFlow (`iflow`) | `.iflow/skills/openspec-*/SKILL.md` | `.iflow/commands/opsx-<id>.md` |
| Junie (`junie`) | `.junie/skills/openspec-*/SKILL.md` | `.junie/commands/opsx-<id>.md` |
| Kilo Code (`kilocode`) | `.kilocode/skills/openspec-*/SKILL.md` | `.kilocode/workflows/opsx-<id>.md` |
| Kiro (`kiro`) | `.kiro/skills/openspec-*/SKILL.md` | `.kiro/prompts/opsx-<id>.prompt.md` |
| OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/commands/opsx-<id>.md` |
| Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx-<id>.md` |
| Qoder (`qoder`) | `.qoder/skills/openspec-*/SKILL.md` | `.qoder/commands/opsx/<id>.md` |
| Qwen Code (`qwen`) | `.qwen/skills/openspec-*/SKILL.md` | `.qwen/commands/opsx-<id>.toml` |
| RooCode (`roocode`) | `.roo/skills/openspec-*/SKILL.md` | `.roo/commands/opsx-<id>.md` |
| Trae (`trae`) | `.trae/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
| Windsurf (`windsurf`) | `.windsurf/skills/openspec-*/SKILL.md` | `.windsurf/workflows/opsx-<id>.md` |
\* Codex commands are installed in the global Codex home (`$CODEX_HOME/prompts/` if set, otherwise `~/.codex/prompts/`), not your project directory.
\*\* GitHub Copilot prompt files are recognized as custom slash commands in IDE extensions (VS Code, JetBrains, Visual Studio). `openspec workspace open --agent github-copilot` targets VS Code Copilot and emits a managed `.code-workspace` file under `.openspec/workspace-open/github-copilot/`. Copilot CLI does not currently consume `.github/prompts/*.prompt.md` directly.
## Non-Interactive Setup
For CI/CD or scripted setup, use `--tools` (and optionally `--profile`):
```bash
# Configure specific tools
openspec init --tools claude,cursor
# Configure all supported tools
openspec init --tools all
# Skip tool configuration
openspec init --tools none
# Override profile for this init run
openspec init --profile core
```
**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `forgecode`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
## Workflow-Dependent Installation
OpenSpec installs workflow artifacts based on selected workflows:
- **Core profile (default):** `propose`, `explore`, `apply`, `archive`
- **Custom selection:** any subset of all workflow IDs:
`propose`, `explore`, `new`, `continue`, `apply`, `ff`, `sync`, `archive`, `bulk-archive`, `verify`, `onboard`
In other words, skill/command counts are profile-dependent and delivery-dependent, not fixed.
## Generated Skill Names
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
- [CLI Reference](cli.md) — Terminal commands
- [Commands](commands.md) — Slash commands and skills
- [Getting Started](getting-started.md) — First-time setup
+451
View File
@@ -0,0 +1,451 @@
# Workflows
This guide covers common workflow patterns for OpenSpec and when to use each one. For basic setup, see [Getting Started](getting-started.md). For command reference, see [Commands](commands.md).
## Philosophy: Actions, Not Phases
Traditional workflows force you through phases: planning, then implementation, then done. But real work doesn't fit neatly into boxes.
OPSX takes a different approach:
```text
Traditional (phase-locked):
PLANNING ────────► IMPLEMENTING ────────► DONE
│ │
│ "Can't go back" │
└────────────────────┘
OPSX (fluid actions):
proposal ──► specs ──► design ──► tasks ──► implement
```
**Key principles:**
- **Actions, not phases** - Commands are things you can do, not stages you're stuck in
- **Dependencies are enablers** - They show what's possible, not what's required next
> **Customization:** OPSX workflows are driven by schemas that define artifact sequences. See [Customization](customization.md) for details on creating custom schemas.
## Two Modes
### Default Quick Path (`core` profile)
New installs default to `core`, which provides:
- `/opsx:propose`
- `/opsx:explore`
- `/opsx:apply`
- `/opsx:archive`
Typical flow:
```text
/opsx:propose ──► /opsx:apply ──► /opsx:archive
```
### Expanded/Full Workflow (custom selection)
If you want explicit scaffold-and-build commands (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:sync`, `/opsx:bulk-archive`, `/opsx:onboard`), enable them with:
```bash
openspec config profile
openspec update
```
## Workflow Patterns (Expanded Mode)
### Quick Feature
When you know what you want to build and just need to execute:
```text
/opsx:new ──► /opsx:ff ──► /opsx:apply ──► /opsx:verify ──► /opsx:archive
```
**Example conversation:**
```text
You: /opsx:new add-logout-button
AI: Created openspec/changes/add-logout-button/
Ready to create: proposal
You: /opsx:ff
AI: Creating all planning artifacts...
✓ proposal.md
✓ specs/
✓ design.md
✓ tasks.md
Ready for implementation!
You: /opsx:apply
AI: Working through tasks...
✓ Added logout button to header
✓ Implemented session clearing
✓ Added confirmation dialog
All tasks complete!
You: /opsx:archive
AI: ✓ Merged specs
✓ Archived change
```
**Best for:** Small to medium features, bug fixes, straightforward changes.
### Exploratory
When requirements are unclear or you need to investigate first:
```text
/opsx:explore ──► /opsx:new ──► /opsx:continue ──► ... ──► /opsx:apply
```
**Example conversation:**
```text
You: /opsx:explore
AI: What would you like to explore?
You: I want to improve page load performance but I'm not sure
where the bottlenecks are.
AI: Let me help investigate...
[Analyzes bundle sizes, identifies slow queries, reviews
component render patterns]
I found three main bottlenecks:
1. Large unoptimized images
2. Synchronous data fetching in ProductList
3. Re-renders from context changes
Which would you like to address first?
You: Let's tackle the data fetching issue.
You: /opsx:new optimize-product-list-fetching
AI: Created change. Ready to create: proposal
You: /opsx:continue
AI: Creating proposal based on our exploration...
[Writes proposal incorporating investigation insights]
Ready to create: specs, design
Which would you like next?
You: /opsx:continue
AI: Creating specs...
```
**Best for:** Performance optimization, debugging, architectural decisions, unclear requirements.
### Parallel Changes
Work on multiple changes at once:
```text
Change A: /opsx:new ──► /opsx:ff ──► /opsx:apply (in progress)
│
context switch
│
Change B: /opsx:new ──► /opsx:ff ──────► /opsx:apply
```
**Example conversation:**
```text
You: I'm working on add-dark-mode but got pulled into a bug fix
You: /opsx:new fix-login-redirect
AI: Created openspec/changes/fix-login-redirect/
You: /opsx:ff
AI: ✓ Created planning artifacts
You: /opsx:apply
AI: Working on fix-login-redirect...
[Implements the fix]
All tasks complete!
You: /opsx:archive
AI: ✓ Archived fix-login-redirect
You: Let's get back to dark mode
You: /opsx:apply add-dark-mode
AI: Resuming add-dark-mode...
Picking up at task 2.3: Update Header...
```
**Best for:** Parallel work streams, urgent interrupts, team collaboration.
When you have multiple completed changes, use `/opsx:bulk-archive`:
```text
You: /opsx:bulk-archive
AI: Found 3 completed changes:
- add-dark-mode (all tasks done)
- fix-login-redirect (all tasks done)
- update-footer (all tasks done)
Checking for spec conflicts...
⚠ add-dark-mode and update-footer both touch specs/ui/
Inspecting codebase to resolve...
Both changes are implemented. Will apply in chronological order.
Archive all 3 changes?
You: Yes
AI: ✓ Archived add-dark-mode
✓ Archived fix-login-redirect
✓ Archived update-footer
Specs merged in order: add-dark-mode → update-footer
```
Bulk archive detects when multiple changes touch the same specs and resolves conflicts by checking what's actually implemented.
### Completing a Change
The recommended completion flow:
```text
/opsx:apply ──► /opsx:verify ──► /opsx:archive
│ │
validates prompts to sync
implementation if needed
```
#### Verify: Check Your Work
`/opsx:verify` validates implementation against your artifacts across three dimensions:
```text
You: /opsx:verify
AI: Verifying add-auth...
COMPLETENESS
✓ All 12 tasks in tasks.md are checked
✓ All requirements in specs have corresponding code
⚠ Scenario "Session timeout after inactivity" not tested
CORRECTNESS
✓ Implementation matches spec intent
✓ Edge cases from scenarios are handled
✓ Error states match spec definitions
COHERENCE
✓ Design decisions reflected in code structure
✓ Naming conventions consistent with design.md
⚠ Design mentions "event-driven" but implementation uses polling
SUMMARY
─────────────────────────────
Critical issues: 0
Warnings: 2
Ready to archive: Yes (with warnings)
Recommendations:
1. Add test for session timeout scenario
2. Consider refactoring to event-driven as designed, or update design.md
```
**What verify checks:**
| Dimension | What it validates |
|-----------|------------------|
| Completeness | All tasks done, all requirements implemented, scenarios covered |
| Correctness | Implementation matches spec intent, edge cases handled |
| Coherence | Design decisions reflected in code, patterns consistent |
Verify won't block archive, but it surfaces issues you might want to address first.
#### Archive: Finalize the Change
`/opsx:archive` completes the change and moves it to the archive:
```text
You: /opsx:archive
AI: Archiving add-auth...
Artifact status:
✓ proposal.md exists
✓ specs/ exists
✓ design.md exists
✓ tasks.md exists (12/12 tasks complete)
Delta specs: Not yet synced to main
→ Would you like to sync now?
You: Yes
AI: ✓ Synced specs to openspec/specs/auth/spec.md
✓ Moved to openspec/changes/archive/2025-01-24-add-auth/
Change archived successfully.
```
Archive will prompt if specs aren't synced. It won't block on incomplete tasks, but it will warn you.
## When to Use What
### `/opsx:ff` vs `/opsx:continue`
| Situation | Use |
|-----------|-----|
| Clear requirements, ready to build | `/opsx:ff` |
| Exploring, want to review each step | `/opsx:continue` |
| Want to iterate on proposal before specs | `/opsx:continue` |
| Time pressure, need to move fast | `/opsx:ff` |
| Complex change, want control | `/opsx:continue` |
**Rule of thumb:** If you can describe the full scope upfront, use `/opsx:ff`. If you're figuring it out as you go, use `/opsx:continue`.
### When to Update vs Start Fresh
A common question: when is updating an existing change okay, and when should you start a new one?
**Update the existing change when:**
- Same intent, refined execution
- Scope narrows (MVP first, rest later)
- Learning-driven corrections (codebase isn't what you expected)
- Design tweaks based on implementation discoveries
**Start a new change when:**
- Intent fundamentally changed
- Scope exploded to different work entirely
- Original change can be marked "done" standalone
- Patches would confuse more than clarify
```text
┌─────────────────────────────────────┐
│ Is this the same work? │
└──────────────┬──────────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
▼ ▼ ▼
Same intent? >50% overlap? Can original
Same problem? Same scope? be "done" without
│ │ these changes?
│ │ │
┌────────┴────────┐ ┌──────┴──────┐ ┌───────┴───────┐
│ │ │ │ │ │
YES NO YES NO NO YES
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
UPDATE NEW UPDATE NEW UPDATE NEW
```
**Example: "Add dark mode"**
- "Need to also support custom themes" → New change (scope exploded)
- "System preference detection is harder than expected" → Update (same intent)
- "Let's ship toggle first, add preferences later" → Update then archive, then new change
## Best Practices
### Keep Changes Focused
One logical unit of work per change. If you're doing "add feature X and also refactor Y", consider two separate changes.
**Why it matters:**
- Easier to review and understand
- Cleaner archive history
- Can ship independently
- Simpler rollback if needed
### Use `/opsx:explore` for Unclear Requirements
Before committing to a change, explore the problem space:
```text
You: /opsx:explore
AI: What would you like to explore?
You: How should we handle rate limiting for our API?
AI: Let me investigate your current setup and options...
[Researches codebase, considers patterns]
I see three approaches we could take:
1. Middleware-based (simple, per-endpoint)
2. Redis-backed (scalable, shared state)
3. Token bucket per user (fair, complex)
Your current stack suggests #1 or #2. What's your scale?
```
Exploration clarifies thinking before you create artifacts.
### Verify Before Archiving
Use `/opsx:verify` to check implementation matches artifacts:
```text
You: /opsx:verify
AI: Verifying add-dark-mode...
✓ All tasks in tasks.md are checked
✓ Requirements in specs have corresponding code
✓ Design decisions are reflected in implementation
Ready to archive!
```
Catches mismatches before you close out the change.
### Name Changes Clearly
Good names make `openspec list` useful:
```text
Good: Avoid:
add-dark-mode feature-1
fix-login-redirect update
optimize-product-query changes
implement-2fa wip
```
## Command Quick Reference
For full command details and options, see [Commands](commands.md).
| Command | Purpose | When to Use |
|---------|---------|-------------|
| `/opsx:propose` | Create change + planning artifacts | Fast default path (`core` profile) |
| `/opsx:explore` | Think through ideas | Unclear requirements, investigation |
| `/opsx:new` | Start a change scaffold | Expanded mode, explicit artifact control |
| `/opsx:continue` | Create next artifact | Expanded mode, step-by-step artifact creation |
| `/opsx:ff` | Create all planning artifacts | Expanded mode, clear scope |
| `/opsx:apply` | Implement tasks | Ready to write code |
| `/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 | Expanded mode, parallel work |
## Next Steps
- [Commands](commands.md) - Full command reference with options
- [Concepts](concepts.md) - Deep dive into specs, artifacts, and schemas
- [Customization](customization.md) - Create custom workflows
+494
View File
@@ -0,0 +1,494 @@
# Workspace Demo
This guide is for using workspace mode with **real repos on your machine**.
It is written as a dogfood tutorial:
- use the actual `openspec` repo checkout you already have
- optionally add one or two more real repos if you want to exercise the multi-repo parts more fully
- create a real managed workspace
- try the commands in the order a real user would
If you only have the `openspec` repo available right now, you can still run the core flow. If you also have a second or third repo handy, the guide points out the extra things worth trying.
## What you will exercise
- creating a managed workspace
- registering real repos with stable aliases
- using `workspace doctor`
- creating a workspace change with explicit targets
- workspace-root and change-scoped `workspace open`
- Codex and GitHub Copilot workspace-open flows
- `status` as the coordination view
- `apply` as the handoff into repo-local execution
- optional target mutation before apply
- optional guardrails after apply
- optional workspace archive at the end
## Prerequisites
- `openspec` is installed and available on your `PATH`
- Node.js `20.19.0+`
- `git` is available
- optional: VS Code with GitHub Copilot if you want to try the Copilot path
If you are running from this repo checkout instead of a global install, replace `openspec` below with:
```bash
node /absolute/path/to/openspec/bin/openspec.js
```
## 1. Pick the real repos you want to coordinate
Start in the root of the real `openspec` repo you want to use:
```bash
cd /path/to/your/openspec/repo
pwd
```
Notes:
- this repo path is the one repo this guide assumes you definitely have
- additional repos are optional, but they make workspace mode much more interesting
- You can use any real repos here, not just repos related to OpenSpec.
## 2. Make sure each repo has repo-local OpenSpec state
`workspace add-repo` only accepts repos that already contain repo-local OpenSpec state, which means the repo has an `openspec/` directory.
Check the `openspec` repo:
```bash
test -d /path/to/your/openspec/repo/openspec && echo "openspec repo is ready"
```
If you are adding other repos, initialize them if needed:
```bash
openspec init /absolute/path/to/another/repo --tools none --force
```
Only run that command for repos that do not already have `openspec/`.
## 3. Use the setup wizard the way a real user would
The recommended onboarding path is:
```bash
openspec workspace setup
```
Use these answers when prompted:
```text
Workspace name: openspec-dogfood
Repo path: /absolute/path/to/your/openspec/repo
Repo alias: openspec
Owner (optional): OpenSpec Core
Handoff note (optional): Apply when the shared plan is ready
Add another repo? n
Open the workspace now? y
Which agent should OpenSpec prepare for? codex
```
If you also want to register more repos, answer `y` to `Add another repo?` and keep going until the wizard reaches the summary.
At the end of the wizard, `cd` into the created workspace. If you used the workspace name above, the default path is:
```bash
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
pwd
```
What to check:
- you are now inside the managed workspace root
- these files exist:
- `.openspec/workspace.yaml`
- `.openspec/local.yaml`
- `changes/`
Quick inspection:
```bash
find . -maxdepth 2 -type f | sort
sed -n '1,200p' .gitignore
```
What to notice:
- the workspace is separate from any one repo
- `.openspec/local.yaml` is machine-local state
- `/.openspec/workspace-open/` is ignored because workspace-open may generate local artifacts there
If you want to understand the lower-level equivalent, it is:
```bash
openspec workspace create openspec-dogfood
openspec workspace add-repo openspec /absolute/path/to/your/openspec/repo --owner "OpenSpec Core" --handoff "Apply when the shared plan is ready"
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
```
## 4. Register additional real repos if you want a broader test
If you only want to test the single-repo flow, you can skip this section because the wizard already registered `openspec`.
If you have more repos, register them now:
```bash
openspec workspace add-repo consumer /absolute/path/to/another/repo --owner "Consumer Team" --handoff "Pick up once the core contract is stable"
openspec workspace add-repo docs /absolute/path/to/a/docs-repo --owner "Docs Team" --handoff "Document the rollout after implementation lands"
```
Now validate the workspace registry:
```bash
openspec workspace doctor
sed -n '1,200p' .openspec/workspace.yaml
sed -n '1,200p' .openspec/local.yaml
```
What to notice:
- `workspace.yaml` holds alias metadata you could share or commit
- `local.yaml` holds machine-local repo paths
- `workspace doctor` is the first thing to run if the registry feels wrong later
## 5. Create a real workspace change
Choose one of these commands based on the aliases you actually want to coordinate.
Single-repo flow:
```bash
openspec new change workspace-dogfood --targets openspec
```
Two-repo flow:
```bash
openspec new change workspace-dogfood --targets openspec,consumer
```
Three-repo flow:
```bash
openspec new change workspace-dogfood --targets openspec,consumer,docs
```
Inspect what was created:
```bash
find changes/workspace-dogfood -maxdepth 3 -type f | sort
sed -n '1,200p' changes/workspace-dogfood/proposal.md
sed -n '1,200p' changes/workspace-dogfood/design.md
sed -n '1,200p' changes/workspace-dogfood/tasks/coordination.md
```
If you targeted more than one repo, also inspect the draft slices:
```bash
find changes/workspace-dogfood/targets -maxdepth 2 -type f | sort
```
What to notice:
- the workspace owns the shared planning artifacts
- the target repo drafts live under `targets/<alias>/`
- no repo-local change exists yet in any repo
Confirm that for the `openspec` repo:
```bash
test ! -e /path/to/your/openspec/repo/openspec/changes/workspace-dogfood && echo "openspec repo not materialized yet"
```
## 6. Try `workspace open` in the order a real user would
### 6a. Root coordination open
```bash
openspec workspace open
```
What to look for:
- your preferred agent should launch
- the session should open in workspace-root mode
- `Attached repos:` should list the registered repos with valid local paths
- the agent should have the registered repos, repo inventory, and active workspace changes available for coordination
If you want to inspect the prepared surface without launching the agent:
```bash
openspec workspace open --prepare-only
```
### 6b. Change-scoped open for the default agent
```bash
openspec workspace open --change workspace-dogfood
```
What to look for:
- your preferred agent should launch again, now change-scoped
- only the targeted aliases should appear
- owner and handoff notes should appear
- non-targeted repos should not appear
If you want to inspect the prepared surface without launching the agent:
```bash
openspec workspace open --change workspace-dogfood --prepare-only
```
### 6c. Change-scoped open for Codex
```bash
openspec workspace open --change workspace-dogfood --agent codex
```
What to look for:
- Codex should launch with the workspace root plus only the targeted repos attached
- the session should stay scoped to the targeted repos
If you want to inspect the generated prompt surface without launching Codex:
```bash
openspec workspace open --change workspace-dogfood --agent codex --prepare-only
```
### 6d. Change-scoped open for GitHub Copilot in VS Code
```bash
openspec workspace open --change workspace-dogfood --agent github-copilot
```
Inspect the generated artifacts:
```bash
sed -n '1,200p' .github/prompts/opsx-workspace-open.prompt.md
sed -n '1,200p' .openspec/workspace-open/github-copilot/workspace-dogfood.code-workspace
```
What to notice:
- the prompt file lives under `.github/prompts/`
- the VS Code workspace file lives under `.openspec/workspace-open/github-copilot/`
- the `.code-workspace` file includes:
- the workspace root
- only the targeted repos
If you have VS Code installed, open the generated workspace:
```bash
code .openspec/workspace-open/github-copilot/workspace-dogfood.code-workspace
```
This is the real Copilot path: open the generated VS Code workspace and use Copilot there.
## 7. Use `status` as your control plane
Run:
```bash
openspec status --change workspace-dogfood
openspec status --change workspace-dogfood --json
```
What to look for:
- overall change state
- target-by-target progress
- owner and handoff notes
- the next recommended step
This is the main command to re-enter an in-flight cross-repo change later.
## 8. Optional: try target-set changes before apply
This section is only interesting if you registered at least one repo that is **not** already in the change target list.
For example, if you registered `docs` but did not target it yet:
```bash
openspec workspace targets workspace-dogfood --add docs
find changes/workspace-dogfood/targets -maxdepth 2 -type f | sort
openspec status --change workspace-dogfood
```
What to notice:
- the `docs` target draft gets scaffolded
- `status` now includes `docs`
Now remove it again before any apply:
```bash
openspec workspace targets workspace-dogfood --remove docs
find changes/workspace-dogfood/targets -maxdepth 2 -type f | sort
openspec status --change workspace-dogfood
```
What to notice:
- removing an unmaterialized target is allowed
- the remaining targets stay intact
## 9. Materialize one real repo
Now hand execution off into the `openspec` repo:
```bash
openspec apply --change workspace-dogfood --repo openspec
openspec status --change workspace-dogfood
find /path/to/your/openspec/repo/openspec/changes/workspace-dogfood -maxdepth 3 -type f | sort
sed -n '1,200p' /path/to/your/openspec/repo/openspec/changes/workspace-dogfood/tasks.md
```
What to notice:
- the workspace change still exists
- the `openspec` repo now has a repo-local change
- the source of truth for execution of that slice has moved into the repo
This is the core handoff:
- plan centrally
- execute locally
## 10. Optional: trigger a guardrail after apply
Once a repo has crossed into repo-local execution, try to remove it from the target set:
```bash
openspec workspace targets workspace-dogfood --remove openspec
```
This should fail.
What to learn:
- workspace target mutation is allowed only while the alias is still workspace-owned
- after apply, the workspace refuses to silently rewrite the target set around a repo-local slice
## 11. Continue from inside the real repo
Now switch into the `openspec` repo and look at the repo-local change directly:
```bash
cd /path/to/your/openspec/repo
find openspec/changes/workspace-dogfood -maxdepth 3 -type f | sort
sed -n '1,200p' openspec/changes/workspace-dogfood/tasks.md
```
This is where you would now do real implementation work.
When you want the workspace view again:
```bash
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
openspec status --change workspace-dogfood
```
## 12. Optional: test `workspace doctor` on a real broken path
If you want to see the repair flow, temporarily break one alias in `.openspec/local.yaml`.
The simplest safe way is:
1. open `.openspec/local.yaml`
2. replace one repo path with a missing path like `/tmp/does-not-exist`
3. run:
```bash
openspec workspace doctor
openspec status --change workspace-dogfood
```
Then repair the path in `.openspec/local.yaml` and run:
```bash
openspec workspace doctor
```
What to learn:
- broken local paths are a **doctor** problem
- the fix belongs in `local.yaml`, not in the shared workspace metadata
## 13. Optional: complete and archive the full flow
If you want to exercise the whole lifecycle, finish the tasks and archive the repo-local change.
In the `openspec` repo:
```bash
cd /path/to/your/openspec/repo
perl -0pi -e 's/- \[ \]/- [x]/g' openspec/changes/workspace-dogfood/tasks.md
openspec archive workspace-dogfood --yes --skip-specs --no-validate
```
Back in the workspace:
```bash
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
perl -0pi -e 's/- \[ \]/- [x]/g' changes/workspace-dogfood/tasks/coordination.md
openspec status --change workspace-dogfood
openspec archive workspace-dogfood --workspace
openspec status --change workspace-dogfood
```
What to notice:
- repo-local archive and workspace archive are distinct
- the workspace archive is the explicit “this cross-repo change is done” step
## 14. The re-entry flow you will actually use later
Once you have a real workspace in use, this is the normal re-entry sequence:
```bash
cd "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
openspec status --change workspace-dogfood
openspec workspace open --change workspace-dogfood
openspec workspace open --change workspace-dogfood --agent codex
openspec workspace open --change workspace-dogfood --agent github-copilot
```
Use:
- `status` to understand current state and next action
- `workspace open` to relaunch the root or change-scoped session
- `workspace doctor` if aliases or paths look stale
- `apply` only when you are ready to hand execution off into a repo
## If you want to remove the workspace later
The workspace is just a managed directory under:
```bash
$HOME/.local/share/openspec/workspaces/
```
So if you want to discard this dogfood workspace after testing:
```bash
rm -rf "$HOME/.local/share/openspec/workspaces/openspec-dogfood"
```
That does **not** delete your registered repos. It only deletes the coordination root.
## Optional convenience shortcuts
If you end up using the same repos repeatedly, you can set shell variables to avoid retyping long paths:
```bash
export OPENSPEC_REPO="/path/to/your/openspec/repo"
export WORKSPACE_ROOT="$HOME/.local/share/openspec/workspaces/openspec-dogfood"
```
Those shortcuts are optional. They are not required for the walkthrough above.
+130
View File
@@ -0,0 +1,130 @@
# Workspace Mode
Workspace mode is the cross-repo coordination path for OpenSpec. It gives you one planning home for a change that spans multiple repositories, while keeping canonical specs and execution owned by the real repos.
## When To Use Workspace Mode
Use workspace mode when repo-local OpenSpec is no longer an honest representation of the work.
Typical signals:
- one change spans two or more repos
- the canonical contract owner is different from one or more implementation repos
- repos or teams need to move at different cadences
- you need one place to pause, resume, or hand off a cross-repo change
Stay repo-local when:
- the work fits in one repo
- the same repo owns planning, implementation, and archive
- you do not need a separate coordination surface
Rule of thumb:
> Plan centrally, execute locally, preserve repo ownership.
Need a runnable walkthrough instead of a reference page? See [Workspace Demo](workspace-demo.md).
## Recommended First Run
Most people should start with the guided setup wizard:
```bash
openspec workspace setup
```
That flow:
1. creates the managed workspace root
2. prompts for one or more repo paths and aliases
3. stores optional owner and handoff notes
4. runs `openspec workspace doctor`
5. stores a preferred workspace-open agent in `.openspec/local.yaml`
6. offers to open the workspace immediately using that preferred agent
Use the lower-level commands directly when you already know the exact workspace shape you want or when you are scripting against the workspace model.
## Supported CLI Flow
The current supported v0 flow is:
```bash
openspec workspace setup
openspec workspace list
openspec new change <id> --targets <alias-a,alias-b>
openspec workspace targets <id> --add <alias-c> --remove <alias-d>
openspec workspace open [--change <id>] [--name <workspace>] [--agent claude|codex|github-copilot] [--prepare-only]
openspec apply --change <id> --repo <alias>
openspec status --change <id>
```
The equivalent manual setup path is:
```bash
openspec workspace create <name>
openspec workspace add-repo <alias> <path> [--owner "<team or person>"] [--handoff "<next step>"]
```
What each step does:
1. `workspace setup` is the onboarding path. It creates the workspace, registers repos, validates the registry, stores a preferred workspace-open agent, and can optionally launch the workspace immediately.
2. `workspace list` shows the locally managed workspaces OpenSpec knows about.
3. `workspace create` and `workspace add-repo` remain the manual setup path. `workspace create` creates a managed coordination root with `.openspec/` metadata and top-level `changes/`. `workspace add-repo` registers stable repo aliases. Repo paths stay local in `.openspec/local.yaml`. Optional owner and handoff notes are committed in `.openspec/workspace.yaml`.
4. `new change --targets` creates one workspace change with shared planning artifacts plus per-target draft slices.
5. `workspace targets <id>` adjusts the target set without manual file edits. It scaffolds added draft slices, removes unmaterialized draft slices, and refuses add or remove mutations once the same change ID already has repo-local execution or archive state for that alias.
6. `workspace open` launches a workspace-root coordination session. If you are already inside a workspace root, it uses that workspace. If you are outside a workspace and only one managed workspace exists, it uses that automatically. If multiple managed workspaces exist, it prompts interactively or you can pass `--name <workspace>`. When you omit `--agent`, OpenSpec uses the preferred agent stored during setup, or prompts once and persists it for older workspaces with no stored preference.
7. Workspace-root mode opens the workspace working set: the coordination root plus registered repos with valid local paths. It also gives the agent the registered repo inventory, owner or handoff notes, and active workspace changes so it can explore before proposal creation.
8. `workspace open --change <id>` adds focused change context for an existing workspace change. Use `--agent codex` when you want Codex launched with the workspace working set attached, or `--agent github-copilot` when you want VS Code opened on a generated `.code-workspace` file.
9. `workspace open --prepare-only` or `workspace open --json` prepares the surfaces without launching an external tool. Use that when you want to inspect or script the generated state.
10. `apply --change <id> --repo <alias>` materializes one repo-local execution surface. After that point, repo-local execution remains local to that repo.
11. `status --change <id>` from the workspace root rolls up coordination state, repo progress, blockers, owner or handoff notes, and the next action.
## Re-Enter An Existing Workspace
When you return to an in-flight cross-repo change:
1. Run `openspec status --change <id>` to see the overall state, affected repos, owner or handoff notes, and the next step.
2. Run `openspec workspace open` when you want the root coordination session. You can run this from anywhere if OpenSpec can uniquely resolve the workspace. Add `--name <workspace>` when more than one managed workspace exists.
3. Run `openspec workspace open --change <id>` when you want the current planning context reopened with just the targeted repos in view.
4. Run `openspec workspace targets <id> --add <alias>` or `--remove <alias>` if the repo scope changed and that alias has not already crossed into repo-local execution for the same change ID.
5. Run `openspec workspace doctor` if `status` reports a stale or missing repo alias.
If you need to explore or plan across the workspace, `openspec workspace open` without `--change` launches the workspace-root session with registered repo roots attached. The supported workspace-open agents are `claude`, `codex`, and `github-copilot`. The default agent comes from the workspace-local preferred agent stored in `.openspec/local.yaml`.
If you create a targeted workspace change from a launched root session, stop after the change is created. OpenSpec records that scope upgrade and reopens the next session change-scoped. Today that automatic upgrade is implemented as a relaunch or continue flow for Claude and Codex, not a live directory attach inside the existing TUI.
For GitHub Copilot, `workspace open` targets VS Code rather than Copilot CLI:
- it writes the scoped prompt file to `.github/prompts/opsx-workspace-open.prompt.md`
- it writes a managed `.code-workspace` file under `.openspec/workspace-open/github-copilot/`
- in workspace-root mode that workspace file includes the coordination root plus registered repos with valid local paths
- in change-scoped mode it includes the coordination root plus only the targeted repos
## Hand Off Work To Another Repo Owner
Owner and handoff metadata are lightweight coordination notes for the workspace registry:
- `--owner` is the repo owner, primary contact, or team that should own the repo-local slice.
- `--handoff` is the short next-step note another engineer should follow when they pick up that repo.
You can add or update those notes later without changing local repo paths:
```bash
openspec workspace update-repo <alias> --owner "<team or person>" --handoff "<next step>"
```
You can also adjust the target set later without editing `.openspec.yaml` by hand:
```bash
openspec workspace targets <id> --add <alias-a,alias-b>
openspec workspace targets <id> --remove <alias-c>
```
That command keeps authority handoff explicit. If the same change ID already exists or was already archived in a target repo, `workspace targets` fails instead of silently mutating the workspace target set around repo-local execution.
The committed workspace metadata stays machine-safe:
- `.openspec/workspace.yaml` stores aliases plus optional owner or handoff notes
- `.openspec/local.yaml` stores machine-specific repo paths
That split keeps shared workspace state portable while still letting each machine resolve local repo roots.
+42
View File
@@ -0,0 +1,42 @@
import tseslint from 'typescript-eslint';
export default tseslint.config(
{
files: ['src/**/*.ts'],
extends: [...tseslint.configs.recommended],
rules: {
// Prevent static imports of @inquirer modules to avoid pre-commit hook hangs.
// These modules have side effects that can keep the Node.js event loop alive
// when stdin is piped. Use dynamic import() instead.
// See: https://github.com/Fission-AI/OpenSpec/issues/367
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['@inquirer/*'],
message:
'Use dynamic import() for @inquirer modules to prevent pre-commit hook hangs. See #367.',
},
],
},
],
// Disable rules that need broader cleanup - focus on critical issues only
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'no-empty': 'off',
'prefer-const': 'off',
},
},
{
// init.ts is dynamically imported from cli/index.ts, so static @inquirer
// imports there are safe - they won't be loaded at CLI startup
files: ['src/core/init.ts'],
rules: {
'no-restricted-imports': 'off',
},
},
{
ignores: ['dist/**', 'node_modules/**', '*.js', '*.mjs'],
}
);
Generated
+27
View File
@@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1767640445,
"narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
+114
View File
@@ -0,0 +1,114 @@
{
description = "OpenSpec - AI-native system for spec-driven development";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs =
{ self, nixpkgs }:
let
supportedSystems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system);
in
{
packages = forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
inherit (pkgs) lib;
in
{
default = pkgs.stdenv.mkDerivation (finalAttrs: {
pname = "openspec";
version = (builtins.fromJSON (builtins.readFile ./package.json)).version;
src = lib.fileset.toSource {
root = ./.;
fileset = lib.fileset.unions [
./src
./bin
./schemas
./scripts
./test
./package.json
./pnpm-lock.yaml
./tsconfig.json
./build.js
./vitest.config.ts
./vitest.setup.ts
./eslint.config.js
];
};
pnpmDeps = pkgs.fetchPnpmDeps {
inherit (finalAttrs) pname version src;
pnpm = pkgs.pnpm_9;
fetcherVersion = 3;
hash = "sha256-9s2kdvd7svK4hofnD66HkDc86WTQeayfF5y7L2dmjNg=";
};
nativeBuildInputs = with pkgs; [
nodejs_20
npmHooks.npmInstallHook
pnpmConfigHook
pnpm_9
];
buildPhase = ''
runHook preBuild
pnpm run build
runHook postBuild
'';
dontNpmPrune = true;
meta = with pkgs.lib; {
description = "AI-native system for spec-driven development";
homepage = "https://github.com/Fission-AI/OpenSpec";
license = licenses.mit;
maintainers = [ ];
mainProgram = "openspec";
};
});
}
);
apps = forAllSystems (system: {
default = {
type = "app";
program = "${self.packages.${system}.default}/bin/openspec";
};
});
devShells = forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
default = pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_20
pnpm_9
];
shellHook = ''
echo "OpenSpec development environment"
echo "Node version: $(node --version)"
echo "pnpm version: $(pnpm --version)"
echo "Run 'pnpm install' to install dependencies"
'';
};
}
);
};
}
@@ -0,0 +1,206 @@
# Decision Space Navigation — Research Session
**Date:** 2026-04-07
## Context
Exploring whether OpenSpec's linear assembly-line workflow (requirements → design → tasks) can be replaced with a more iterative, non-linear system where users work on any component in any order with continuous feedback.
---
## 1. The Starting Point: Assembly Line vs Iterative
**Current model:** OpenSpec enforces ordering via an ArtifactGraph DAG. Artifacts have hard gates — tasks are blocked until both specs and design are "done."
**Desired model:** User can work on any part in any order. System provides feedback on what's incomplete/inconsistent, but never blocks.
### Patterns explored:
- **Blackboard Architecture** (1970s, Hearsay-II) — multiple specialists read/write shared state, controller suggests what to work on
- **Stigmergy** — agents coordinate by modifying the environment (workspace is the pheromone trail)
- **Tuple Spaces / Linda** — decoupled communication through shared memory
- **ECS (Entity Component System)** — game engine pattern where systems process entities matching their component signature
- **Society of Mind** (Minsky) — intelligence from many simple agents each handling a narrow concern
### Key design:
- **Workspace** — shared state, items with maturity levels (sketch/draft/solid/complete)
- **Concerns** — pluggable perspectives defined as YAML prompt files (security, PM, QA, etc.)
- **The Loop** — classify → capture → dispatch concerns → surface findings
---
## 2. The IDE Analogy — Tested and Found Wanting
### Hypothesis
Background LLM agents act as "language servers" that continuously analyze a shared workspace, like how IDEs surface type errors and lint warnings.
### Agent debate results (4 agents ran in parallel):
**The analogy breaks down on the properties that matter most:**
| IDE Property | Transfers to Specs? | Why |
|---|---|---|
| Formal grammar | NO | Specs are natural language, no AST |
| Objective correctness | PARTIALLY | Some checks are objective (dangling refs), high-value ones are subjective |
| Low false positive rate | NO | LLMs hallucinate. >67% false positive rate = users stop looking (IBM SOC research) |
| Deterministic trust | NO | Same input → different output. Users can't trust it like a type checker |
| Speed (<100ms) | NO | LLM calls are 5-30s. Not ambient, just slow consultation |
| Incrementality | PARTIALLY | Specs are small enough for brute-force re-analysis |
| Actionability | PARTIALLY | "Add return type here" vs "this section may conflict with section 3" |
| Progressive disclosure | YES | Pure UX pattern, transfers cleanly |
| Composability | NO | Multiple LLM concerns will contradict each other |
**Market research confirmed:** No one has shipped a true "IDE for specs" that stuck for general product work. QVscribe works in aerospace/medical (bad requirements kill people). ChatPRD works because it's on-demand, not ambient.
### What survived the critique:
The shift from **review-time to authoring-time** feedback is genuinely valuable. Finding contradictions while writing — not days later in review — is better. The question is delivery mechanism.
---
## 3. Ambient Suggestions — The Graveyard and Survivors
### What died:
- **Clippy (1997-2003)** — interruption without intelligence, high dismissal cost, couldn't learn
- **Cortana proactive suggestions** — 10% usage, generic, required dedicated pane
- **Google Now cards** — ambient card deck abandoned within 4 years
- **Apple Siri Suggestions** — 73% of users say "little to no value"
### What survived:
- **Grammarly** — 40M+ users. Inline underlines, zero cost to ignore, passive/contextual
- **Gmail Smart Compose** — 70% adoption. Ghost text, Tab to accept, zero dismissal cost
- **GitHub Copilot** — 21-30% acceptance rate. Same inline ghost text pattern. BUT sentiment dropping (70% → 60%)
- **Nest thermostat** — Gold standard: invisible when correct. You see outcomes, not suggestions
### The fundamental law:
**The cost of ignoring a suggestion must be lower than the cost of evaluating it, or users disable the system.**
### The pattern:
| Factor | Survives | Dies |
|---|---|---|
| Where | Inline, in workflow | Separate pane, pop-up |
| Ignore cost | Zero | Must actively dismiss |
| Accuracy | High precision | High recall, many false positives |
| Learning | Adapts over time | Same for everyone |
| Agency | User chooses | System interrupts |
---
## 4. The Reframe: Decision Space Navigation
### Key insight
Specs aren't about **construction** (like code). They're about **deciding** — navigating a problem space with many open dimensions. Gaps aren't errors to fix; they're unmade decisions.
The right question isn't "how do we show inline errors" — it's "how do we help someone navigate a large decision space efficiently?"
### The good collaborator model
A good PM doesn't present a list of 12 open questions. They follow your thread and pull you toward the adjacent unexplored area:
> "Solid. What happens when they deny the permission?"
Gaps are the agent's **internal state, not a UI element.** Surface ONE thing at a time, the most relevant to the user's current train of thought.
### Two types of gaps:
- **Decision gaps** — only the user can resolve ("should we support multiple providers?"). Surface as questions.
- **Research gaps** — system can explore autonomously ("what OAuth libraries does the project use?"). Run in background.
### The model: Research team, not IDE
- **Lead agent** (foreground) — follows your thread, asks the next relevant question
- **Research agents** (background) — explore research gaps, report findings
- **Internal state** (never shown raw) — full map of all gaps, dependencies, priorities
---
## 5. UX: Spatial vs Temporal
### The fundamental tension
Chat is temporal (sequential). Decision spaces are spatial (multi-dimensional). Can't represent a map in a line.
### Three models explored:
**Model 1: Workspace file as passive map**
Agent maintains a markdown file open in user's editor. Chat is focused work, file is the map. Works today, zero infrastructure.
**Model 2: Named focus areas**
`/focus auth` — switch between dimensions. Agent gives a briefing on entry ("here's where we are, what changed since last time"). Still a single chat thread.
**Model 3: Parallel conversations**
Each dimension is its own persistent agent conversation. Map view shows the landscape. Cross-impacts propagate automatically. Requires new runtime model.
### Core structure all models share:
```
MAP (spatial, always available, shows whole landscape)
├── DIMENSION (focused workspace, deep conversation)
├── DIMENSION
├── DIMENSION
CROSS-CUTS (propagation layer, how decisions ripple)
```
### What's genuinely new:
**Decision propagation.** When you make a decision in one dimension, the system understands implications for other dimensions, updates their state, and briefs you when you arrive. No existing tool does this well.
---
## 6. Desktop App — Not Worth It
### Agent debate results (4 agents):
**Market evidence on spatial tools:**
| Tool | Approach | Outcome |
|---|---|---|
| Muse (Ink & Switch) | Spatial-first | Dead ($120K ARR peak) |
| Roam Research | Graph-first | Collapsed from $200M hype |
| Scapple, TheBrain, Kinopio | Spatial/graph | Permanent niche |
| Obsidian Canvas | Canvas as feature | "Half-baked," minimal sustained use |
| Miro | Spatial whiteboard | $665M ARR but only for brainstorming |
| Linear | Structured-first | Won |
| Notion | Structured-first | Won |
| Claude Code, Cursor | Text/chat-first | Won |
**Cognitive Fit Theory (Vessey, 1991):** Spatial helps with spatial tasks (seeing relationships). Hurts analytical tasks (prioritizing, sequencing). Planning requires both. Answer: **structured-first with spatial views as a lens.**
**The Muse lesson:** Spatial was great for ideation but users couldn't bridge to execution. Exactly the transition our product needs.
**Engineering cost:** 70% of effort goes to UI, 30% to AI. Inverted from where value lives.
### Recommendation:
1. **Weeks 1-4:** Build the AI. Ship as Claude Code skill. Markdown workspace as map.
2. **Months 2-3:** Add lightweight web viz (ReactFlow). Browser tab alongside terminal.
3. **Months 4-6:** Invest in whatever surface drives retention.
4. **Probably never:** Desktop app. Moat is in AI judgment, not renderer.
---
## 7. Where's the Moat? (The Uncomfortable Truth)
### What the "judgment layer" actually is:
| Component | What it really is |
|---|---|
| Detect cross-impacts | A prompt |
| Rank gaps by importance | A prompt |
| Decide when to speak | A prompt with rules |
| Propagate decisions | A prompt |
| Choose which concern to consult | A few lines of routing code |
| Classify user input | A prompt |
**Day one, it's prompts and files. No moat.** Someone with Claude and a markdown file gets 80% of the value.
### Where real brain could emerge over time:
| Timeline | Component | Moat type |
|---|---|---|
| Day 1 | Prompts + files | None |
| Month 3 | Formal decision graph with deterministic constraint propagation | Structural — code enforces what LLM guesses |
| Month 6 | Learned silence model from usage patterns | Data — when to speak, trained on real sessions |
| Month 12 | Temporal provenance + decision decay | Product — tracking how decisions evolve over weeks |
### The honest framing:
The moat isn't in technology on day one. It's in **product design** — getting the conversation rhythm right. When to ask, how to bridge dimensions, how to surface cross-impacts. Design moats are real (Linear, Figma) but defended by taste and iteration speed, not patents.
---
## Open Questions
1. Is the "good collaborator" conversational model enough, or do users actually need to see the decision map?
2. Does the formal decision graph (month 3 milestone) actually improve over LLM reasoning, or is it unnecessary engineering?
3. How many dimensions does a typical feature planning session actually have? If it's 4-6, markdown is fine. If it's 15, we need something more.
4. Can the "silence problem" (when to speak vs stay quiet) be solved with heuristics, or does it genuinely require learned models?
5. Is this a product or a feature? Could this be a mode within an existing tool (Claude Code, Linear, Notion) rather than standalone?
@@ -0,0 +1,27 @@
# Phase 00 Manual Test
## Scenarios Run
- Copied the committed `happy-path` fixture into two fresh temp roots by cloning both `workspace/` and `repos/` outside Vitest.
- Confirmed one copied workspace root contains `.openspec/` and `changes/`, and does not contain a repo-local `openspec/` directory.
- Ran `node "$OPENSPEC_REPO/dist/cli/index.js" list --json` from the copied `repos/app` root, with `OPENSPEC_REPO` set to the current OpenSpec checkout, and parsed stdout as JSON.
- Mutated `repos/app/README.md` in the first temp root and confirmed the same file in the second temp root remained unchanged.
- Ran `rg -n -F "$OPENSPEC_REPO" test/fixtures/workspace-poc` to confirm the current checkout path is not committed into the workspace fixtures.
## Results
- All manual smoke scenarios passed.
- The workspace copy preserved the expected Phase 00 layout: `.openspec/` and `changes/` exist at the workspace root, and no nested repo-local `openspec/` directory exists there.
- The direct CLI invocation exited `0`, produced empty `stderr`, and returned parseable JSON from the attached repo fixture. The current payload shape is an object with a `changes` array containing the fixture-backed `app-ui-polish` change.
- Mutating one fresh fixture copy did not affect the second copy, which confirms the Phase 00 isolation property outside the automated test harness.
- The committed fixture seeds do not contain the current checkout path.
## Fixes Applied
- No product-code fixes were needed from this manual pass.
- Corrected the first smoke attempt to use the attached repo as the real process working directory; `openspec list` does not expose a `--cwd` flag.
## Residual Risks
- No residual risks were found within the implemented Phase 00 scope.
- This manual smoke still validates attached-repo execution rather than future workspace command entrypoints, because workspace commands land in later phases.
@@ -0,0 +1,24 @@
# Phase 00 Summary
## Changes Made
- Added `test/helpers/workspace-sandbox.ts` to clone workspace fixtures into unique temp roots, split managed workspace state from attached repos, and rewrite `.openspec/local.yaml` repo paths to canonical absolute paths at runtime.
- Added `test/helpers/workspace-assertions.ts` with reusable checks for workspace layout, committed absolute-path leakage, target membership, and materialization invariants.
- Added workspace fixture seeds under `test/fixtures/workspace-poc/` for `empty`, `happy-path`, and `dirty`.
- Reserved workspace test suite locations with new coverage in `test/core/workspace/`, `test/commands/workspace/`, and `test/cli-e2e/workspace/`.
- Added focused Phase 00 tests in `test/core/workspace/workspace-sandbox.test.ts` and `test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`.
## Tests Performed
- `pnpm vitest run test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
## Results
- All 6 Phase 00 tests passed under the current forked Vitest worker configuration.
- The harness creates `.openspec/` plus `changes/` at the workspace root and does not create an inner repo-local `openspec/`.
- Fixture clones mutate independently, committed fixture seeds stay free of absolute repo paths, and `runCLI()` can execute JSON commands inside sandbox repos without spinner noise in stderr.
## Blockers And Next-Step Notes
- No blockers in this phase.
- The harness is ready for Phase 01 and later workspace command coverage to reuse the same `workspaceSandbox()` helper and fixture seeds.
@@ -0,0 +1,25 @@
# Phase 00 Verification
## Checks Performed
- Re-read the Phase 00 block in `ROADMAP.md` plus the current `SUMMARY.md`, `VERIFY.md`, and `MANUAL_TEST.md` artifacts in fresh context.
- Inspected the Phase 00 implementation in `test/helpers/workspace-sandbox.ts`, `test/helpers/workspace-assertions.ts`, `test/core/workspace/workspace-sandbox.test.ts`, `test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`, and the committed fixtures under `test/fixtures/workspace-poc/`.
- Re-ran the focused Phase 00 suite with `pnpm vitest run test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`.
- Reproduced the manual smoke by copying the committed `happy-path` fixture into a fresh temp root, confirming the workspace layout, running `node "$OPENSPEC_REPO/dist/cli/index.js" list --json` from `repos/app`, and parsing the JSON output.
- Ran `rg -n -F "$(pwd)" test/fixtures/workspace-poc || true` to confirm the committed fixture seeds do not embed the current checkout path.
- Ran `git diff --check -- test/helpers/workspace-sandbox.ts test/helpers/workspace-assertions.ts test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts test/fixtures/workspace-poc notes/workspace-poc/phase-00-test-harness ROADMAP.md` after the note updates to confirm the phase files remain whitespace-clean.
## Issues Found
- Documentation quality issue: `MANUAL_TEST.md` recorded a workstation-specific absolute CLI path, which made the smoke instructions less portable than the rest of the phase artifacts.
- No harness, fixture, or acceptance-test defects were found during the verification pass.
## Fixes Applied
- Updated `MANUAL_TEST.md` to describe the CLI smoke with `OPENSPEC_REPO` instead of a machine-specific absolute path.
- Updated this verification note to reflect the fresh-context checks that were actually rerun for Phase 00.
## Residual Risks
- No residual risks were found within the implemented Phase 00 scope.
- `test/commands/workspace/` remains intentionally reserved until later phases add workspace commands, so the current CLI compatibility proof is limited to attached repo roots.
@@ -0,0 +1,33 @@
# Phase 01 Manual Test
## Scenarios Run
- Rebuilt the CLI with `pnpm run build` so the manual pass used the current source tree.
- Ran `node bin/openspec.js --no-color workspace --help` in a fresh temp XDG config/data root with telemetry disabled.
- Ran `node bin/openspec.js --no-color workspace create alpha-team-binmanual` in that same fresh context.
- Inspected the created workspace root on disk, including `.openspec/workspace.yaml`, `.openspec/local.yaml`, `changes/`, and `.gitignore`.
- Re-ran `node bin/openspec.js --no-color workspace create alpha-team-binmanual` to confirm duplicate handling.
- Ran `node bin/openspec.js --no-color workspace create "Alpha Team"` to confirm invalid-name handling.
## Results
- `workspace --help` exposed the `create <name>` entrypoint as expected.
- Successful create produced a managed workspace root under the temporary XDG data directory with:
- `.openspec/workspace.yaml`
- `.openspec/local.yaml`
- `changes/`
- `.gitignore` containing `/.openspec/local.yaml`
- The created workspace root did not contain `openspec/changes` or any inner `openspec/` repo-local layout.
- `workspace.yaml` stored the workspace name and empty repo registry as expected for a new workspace.
- `local.yaml` stored the local overlay version and an empty `repoPaths` map.
- Re-running `workspace create` with the same name failed cleanly with an actionable duplicate-workspace error and did not mutate the existing workspace.
- Creating a workspace with `Alpha Team` failed cleanly with the expected kebab-case validation error.
## Fixes Applied
- None.
## Residual Risks
- None found within the Phase 01 scope.
- Broader automated command and CLI coverage for `workspace create` still belongs to Phase 02.
@@ -0,0 +1,37 @@
# Phase 01 Summary
## Changes Made
- Added `src/commands/workspace.ts` and registered a new `openspec workspace` command group with a `workspace create <name>` entrypoint.
- Added `src/core/workspace/create.ts` to create managed workspace roots under the global OpenSpec data directory at `workspaces/<name>`.
- Added `src/core/setup/bootstrap.ts` and reused it from both `workspace create` and the existing `InitCommand` so writable-target checks and directory bootstrapping stay on one shared setup path.
- `workspace create` now creates a dedicated workspace layout with `.openspec/workspace.yaml`, `.openspec/local.yaml`, and top-level `changes/`, without creating a repo-local `openspec/` tree.
- `workspace create` now writes `/.openspec/local.yaml` into the workspace root `.gitignore` so the local overlay is treated as local-only state.
- Duplicate and invalid workspace names now fail with explicit, actionable errors.
## Tests Performed
- `pnpm run build`
- `pnpm vitest run test/core/init.test.ts test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
- Fresh CLI smoke in temp XDG config/data roots:
- `node dist/cli/index.js --no-color workspace create alpha-team-2`
- repeated create for duplicate handling
- invalid create with `Alpha Team`
## Results
- Build passed.
- 48 focused Vitest checks passed, including existing init coverage and workspace harness compatibility coverage.
- Fresh CLI smoke created a managed workspace at `XDG_DATA_HOME/openspec/workspaces/alpha-team-2` with:
- `.openspec/workspace.yaml`
- `.openspec/local.yaml`
- `changes/`
- `.gitignore` containing `/.openspec/local.yaml`
- The created workspace root did not contain `openspec/changes`.
- Re-running against the same name failed explicitly without mutating the workspace.
- Invalid names failed with a workspace-specific kebab-case error.
## Blockers And Next-Step Notes
- No blockers in Phase 01.
- Automated command/unit/e2e coverage for `workspace create` is still intentionally thin and should be expanded in Phase 02.
@@ -0,0 +1,38 @@
# Phase 01 Verification
## Checks Performed
- Read the Phase 01 block in `ROADMAP.md` plus the current `SUMMARY.md` and `MANUAL_TEST.md` artifacts.
- Reviewed the implementation boundary for this phase in:
- `src/cli/index.ts`
- `src/commands/workspace.ts`
- `src/core/workspace/create.ts`
- `src/core/setup/bootstrap.ts`
- `src/core/init.ts`
- Rebuilt the CLI with `pnpm run build`.
- Ran focused regression coverage:
- `pnpm vitest run test/core/init.test.ts test/core/workspace/workspace-sandbox.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
- Ran fresh CLI verification in temporary XDG config/data roots with telemetry disabled:
- `node dist/cli/index.js --no-color workspace --help`
- `node dist/cli/index.js --no-color workspace create alpha-team-verify`
- repeated create for duplicate handling
- `node dist/cli/index.js --no-color workspace create "Alpha Team"` for invalid-name handling
- Inspected the generated workspace root on disk and confirmed:
- `.openspec/workspace.yaml` exists
- `.openspec/local.yaml` exists
- top-level `changes/` exists
- `.gitignore` contains `/.openspec/local.yaml`
- no nested `openspec/` or `openspec/changes` was created
## Issues Found
- None.
## Fixes Applied
- None.
## Residual Risks
- No blocking issues were found within the Phase 01 scope.
- Dedicated automated command/e2e coverage for `workspace create` is still intentionally deferred to Phase 02, so create-specific confidence still comes from this fresh CLI smoke plus the shared regression suites.
@@ -0,0 +1,34 @@
# Phase 02 Manual Test
Manual pass date: 2026-04-17
Phase cycle: 1
Stage: `manual-test`
## Scenarios Run
- Rebuilt the CLI with `pnpm run build` so the manual pass used the current source tree.
- In a fresh `mktemp` root with isolated `XDG_CONFIG_HOME` and `XDG_DATA_HOME`, and `OPEN_SPEC_TELEMETRY_DISABLED=1`, ran `node bin/openspec.js --no-color workspace --help`.
- Ran `node bin/openspec.js --no-color workspace create alpha-manual`.
- Inspected the created `alpha-manual` workspace root for `.openspec/workspace.yaml`, `.openspec/local.yaml`, `changes/`, `.gitignore`, and absence of any nested repo-local `openspec/` directory.
- Ran `node bin/openspec.js --no-color workspace create beta-json --json` and parsed stdout as JSON.
- Re-ran `node bin/openspec.js --no-color workspace create alpha-manual` and compared file hashes for `.gitignore`, `.openspec/workspace.yaml`, and `.openspec/local.yaml` before and after the duplicate attempt.
## Results
- `workspace --help` exposed `create [options] <name>` under the `workspace` command.
- `workspace create alpha-manual` exited `0`, produced no stderr output, and created a managed workspace root under the isolated XDG data directory.
- The created workspace contained `.openspec/workspace.yaml`, `.openspec/local.yaml`, `changes/`, and `.gitignore` with `/.openspec/local.yaml`.
- `workspace.yaml` contained `version: 1`, `name: alpha-manual`, and `repos: {}`.
- `local.yaml` contained `version: 1` and `repoPaths: {}`.
- The workspace root did not contain any nested repo-local `openspec/` directory.
- `workspace create beta-json --json` exited `0`, emitted parseable JSON on stdout only, and returned the expected absolute paths plus `gitignoreStatus: "created"`.
- Re-running `workspace create alpha-manual` exited `1`, emitted the expected blank line on stdout plus an actionable error on stderr, and left the existing workspace files unchanged.
## Fixes Applied
- None. No product or test changes were required from this manual pass.
- Refreshed this artifact so the manual-test record matches the fresh cycle-1 run.
## Residual Risks
- None found within the Phase 02 scope.
@@ -0,0 +1,34 @@
# Phase 02 Summary
## Changes Made
- Added focused core coverage in `test/core/workspace/workspace-create.test.ts` for managed workspace path resolution plus metadata and overlay initialization.
- Added command-layer coverage in `test/commands/workspace/create.test.ts` for the `workspace create` action, including happy path, duplicate handling, invalid names, and machine-readable output.
- Added CLI e2e coverage in `test/cli-e2e/workspace/workspace-create-cli.test.ts` for help output, JSON cleanliness, exit codes, on-disk layout, and duplicate-create safety.
- Added a minimal `--json` success and error path to `src/commands/workspace.ts` so acceptance 02.6 is concrete and testable instead of hypothetical.
- Updated `test/commands/workspace/README.md` now that the reserved command-layer directory contains real coverage.
## Tests Performed
- `pnpm run build`
- `pnpm vitest run test/core/workspace/workspace-create.test.ts test/core/workspace/workspace-sandbox.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
- Fresh CLI verification and manual smoke in isolated XDG config/data roots with telemetry disabled:
- `node bin/openspec.js --no-color workspace --help`
- `node bin/openspec.js --no-color workspace create alpha-manual`
- `node bin/openspec.js --no-color workspace create beta-json --json`
- repeated `workspace create alpha-manual` for duplicate handling
- `git diff --check -- src/commands/workspace.ts test/core/workspace/workspace-create.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/commands/workspace/README.md`
## Results
- Build passed.
- The focused workspace suite passed with 15/15 tests.
- `workspace --help` now documents `create [options] <name>`.
- Successful create still produces a usable managed workspace root with `.openspec/workspace.yaml`, `.openspec/local.yaml`, top-level `changes/`, and no nested repo-local `openspec/`.
- `workspace create --json` now emits clean parseable JSON with no stderr noise on success.
- Duplicate create attempts still exit `1`, surface an actionable error, and leave the existing workspace files unchanged.
## Blockers And Next-Step Notes
- No blockers in Phase 02.
- No new roadmap phases were required from this pass.
@@ -0,0 +1,43 @@
# Phase 02 Verification
## Checks Performed
- Read the Phase 02 block in `ROADMAP.md` plus the current `SUMMARY.md`, `VERIFY.md`, and `MANUAL_TEST.md` for this phase before running checks.
- Reviewed the current Phase 02 implementation boundary in:
- `src/commands/workspace.ts`
- `src/core/workspace/create.ts`
- `src/cli/index.ts`
- `test/core/workspace/workspace-create.test.ts`
- `test/commands/workspace/create.test.ts`
- `test/cli-e2e/workspace/workspace-create-cli.test.ts`
- `test/helpers/workspace-assertions.ts`
- `test/helpers/run-cli.ts`
- `test/commands/workspace/README.md`
- Rebuilt the CLI with `pnpm run build`.
- Ran the focused regression suite:
- `pnpm vitest run test/core/workspace/workspace-create.test.ts test/core/workspace/workspace-sandbox.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
- Re-ran fresh CLI verification in isolated XDG roots with telemetry disabled:
- `node bin/openspec.js --no-color workspace --help`
- `node bin/openspec.js --no-color workspace create alpha-manual`
- inspected `.openspec/workspace.yaml`, `.openspec/local.yaml`, `.gitignore`, and the top-level `changes/` directory
- confirmed there is no nested repo-local `openspec/` directory
- `node bin/openspec.js --no-color workspace create beta-json --json`
- repeated `workspace create alpha-manual` to verify duplicate handling, exit code `1`, and unchanged workspace files
- Ran `git diff --check` on the Phase 02 source, test, and helper files.
- Validated documentation quality against the live command surface by comparing the current help text and test assertions with the phase notes.
## Issues Found
- No product or test failures were found in the current Phase 02 scope.
- The existing `VERIFY.md` reflected the earlier implementation pass rather than this independent verification pass, so the phase notes were stale.
## Fixes Applied
- Refreshed this verification note so it documents the current independent verification run, the checks actually performed, and the current status of the phase.
- Refreshed `MANUAL_TEST.md` to match the current manual pass and to keep the phase documentation aligned with the live CLI behavior.
## Residual Risks
- No blocking issues remain within the Phase 02 scope.
- Phase 02 still stays within its intended boundary: managed workspace creation, metadata initialization, and validation coverage only. Later workspace behaviors remain outside this phase.
- `--json` discipline is currently proven for `workspace create`; future workspace commands should follow the same stdout/stderr contract when they add machine-readable output.
@@ -0,0 +1,42 @@
# Phase 03 Manual Test
Manual test stage re-run in fresh isolated XDG state on 2026-04-17 for ROADMAP Phase 03, cycle 1.
## Scenarios run
- Built the current CLI with `pnpm run build`.
- Created a managed workspace with `openspec workspace create phase03-manual --json`.
- Registered a repo with `openspec workspace add-repo app <symlink-path> --json`.
- Confirmed the persisted split:
- `.openspec/workspace.yaml` stored only the committed alias entry `app: {}`
- `.openspec/local.yaml` stored only the canonical absolute repo path
- no absolute repo path leaked into `.openspec/workspace.yaml`
- Exercised `workspace add-repo` failure cases from the real CLI:
- duplicate alias registration
- missing repo path
- repo path without repo-local `openspec/`
- Ran `openspec workspace doctor --json` on a healthy workspace and confirmed a clean pass.
- Corrupted fresh workspace metadata to simulate doctor-only recovery scenarios, then ran `openspec workspace doctor --json` and confirmed:
- `missing-local-path` for a committed alias missing from `.openspec/local.yaml`
- `non-canonical-path` for a symlinked local overlay path
- `extra-local-alias` for a local-only alias not present in committed metadata
- non-zero exit and no mutation of `.openspec/workspace.yaml` or `.openspec/local.yaml`
- Removed a previously registered repo directory, reran `openspec workspace doctor --json`, and confirmed `missing-repo-path` with no overlay mutation.
- Removed `openspec/` from a previously registered repo, reran `openspec workspace doctor --json`, and confirmed `missing-openspec-state`.
## Results
- All manual smoke scenarios passed against the current built CLI.
- `workspace add-repo` still persists committed alias metadata separately from local absolute paths.
- Canonicalization still resolves symlink inputs before persistence.
- `workspace doctor` reports healthy state correctly, reports stale or broken registry state with the expected issue codes, exits non-zero on problems, and does not rewrite workspace files during diagnostics.
## Fixes applied
- No product fixes were required from this manual-test pass.
- Updated this manual-test note to reflect the fresh-context run and expanded doctor scenarios.
## Residual risks
- No residual Phase 03 functional issues were found during manual testing.
- Dedicated automated regression coverage for these flows is still expected in Phase 04.
@@ -0,0 +1,48 @@
# Phase 03 Summary
## Changes made
- Added shared workspace metadata helpers in `src/core/workspace/metadata.ts` so committed workspace state and local overlay state are read and written consistently.
- Added repo registry and doctor logic in `src/core/workspace/registry.ts`.
- Extended `src/commands/workspace.ts` with:
- `openspec workspace add-repo <alias> <path>`
- `openspec workspace doctor`
- Kept committed alias registration in `.openspec/workspace.yaml`.
- Kept canonical absolute repo paths in `.openspec/local.yaml`.
- Validated repo registration inputs for:
- kebab-case alias shape
- existing directory paths
- repo-local OpenSpec state via `openspec/`
- Implemented doctor diagnostics for:
- missing local alias mappings
- missing repo paths
- non-canonical local overlay paths
- extra local-only aliases
- missing repo-local OpenSpec state
## Tests or research performed
- `pnpm run build`
- `pnpm vitest run test/core/workspace/workspace-create.test.ts test/core/workspace/workspace-sandbox.test.ts test/commands/workspace/create.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-sandbox-cli.test.ts`
- Fresh CLI smoke in temporary XDG roots covering:
- `workspace create`
- `workspace add-repo` success with a symlinked repo path
- duplicate alias failure
- missing path failure
- missing `openspec/` failure
- `workspace doctor` success on a healthy workspace
- `workspace doctor --json` failure reporting stale path and local-overlay drift without mutating files
## Results
- Build passed.
- Existing workspace regression tests passed: 15/15.
- `workspace add-repo` writes only the alias to `.openspec/workspace.yaml` and only the canonical absolute path to `.openspec/local.yaml`.
- Canonicalization resolved a symlinked repo input to the real absolute path before persistence.
- `workspace doctor` reports missing repos and overlay drift and exits non-zero without rewriting workspace files.
- No absolute repo path leaked into committed workspace metadata during the fresh acceptance run.
## Blockers and next-step notes
- No blockers in Phase 03.
- Phase 04 should add permanent automated coverage for the new registry and doctor behaviors across core, command, and CLI layers.
@@ -0,0 +1,35 @@
# Phase 03 Verification
## Checks performed
- Re-read the Phase 03 block in `ROADMAP.md` and the current phase artifacts in `notes/workspace-poc/phase-03-repo-registry/`.
- Inspected the Phase 03 implementation boundaries in:
- `src/core/workspace/metadata.ts`
- `src/core/workspace/registry.ts`
- `src/commands/workspace.ts`
- `src/cli/index.ts`
- `src/utils/file-system.ts`
- Rebuilt from the current workspace with `pnpm run build`.
- Re-ran the current workspace-focused automated coverage with `pnpm vitest run test/core/workspace test/commands/workspace test/cli-e2e/workspace`.
- Verified the acceptance cases in a fresh temporary XDG workspace using the built CLI:
- `workspace create phase03-verify`
- `workspace add-repo app <symlink-path>`
- confirmed `.openspec/workspace.yaml` stored only the committed alias entry
- confirmed `.openspec/local.yaml` stored only the canonical absolute repo path
- confirmed duplicate alias, missing path, and missing `openspec/` failures
- confirmed `workspace doctor` passes on healthy state
- corrupted `.openspec/local.yaml` and confirmed `workspace doctor --json` reports stale state with a non-zero exit and no YAML mutation
- Reviewed `openspec workspace --help` to confirm the new subcommands are discoverable from the CLI surface.
## Issues found
- No implementation, boundary, or documentation defects were found during this verification pass.
## Fixes applied
- Updated this verification note to reflect the fresh-context verification run.
- No code changes were required.
## Residual risks
- Direct automated coverage for `workspace add-repo` and `workspace doctor` is still deferred to Phase 04, so this phase currently relies on manual verification plus adjacent workspace regression tests.
@@ -0,0 +1,42 @@
# Phase 04 Manual Test
Manual smoke re-run with the built CLI in fresh isolated XDG state on 2026-04-17 for ROADMAP Phase 04, cycle 1.
## Scenarios run
- Built the current CLI with `pnpm run build`.
- Created a managed workspace with `openspec workspace create phase04-manual-cycle1 --json`.
- Created three real repo fixtures with repo-local `openspec/changes` state: `app`, `api`, and `docs`.
- Registered all three repos through the real CLI with:
- `openspec workspace add-repo app <path> --json`
- `openspec workspace add-repo api <path> --json`
- `openspec workspace add-repo docs <path> --json`
- Ran `openspec workspace doctor --json` and confirmed a clean pass with:
- `registeredAliasCount: 3`
- `localAliasCount: 3`
- `issues: []`
- `status: "ok"`
- Edited `.openspec/local.yaml` to replace the `api` path with a relative non-canonical path and reran `openspec workspace doctor --json`.
- Confirmed the drift run returned exit code `1` with a `non-canonical-path` issue for alias `api`.
- Removed `docs/openspec/` from a registered repo and reran `openspec workspace doctor --json`.
- Confirmed the doctor run returned exit code `1` with a `missing-openspec-state` issue for alias `docs`.
- Edited `.openspec/local.yaml` to replace the `app` path with a missing repo root and reran `openspec workspace doctor --json`.
- Confirmed the stale run returned exit code `1` with a `missing-repo-path` issue for alias `app`.
- Repaired `.openspec/local.yaml` by restoring the canonical absolute repo path and restored `docs/openspec/`, then reran `openspec workspace doctor --json`.
- Compared `.openspec/workspace.yaml` before and after the local overlay edits to confirm committed metadata stayed unchanged.
## Results
- All manual smoke scenarios passed.
- Multiple repo additions remained readable and doctor-clean in one workspace.
- Doctor detected alias/path drift, missing repo-local `openspec/`, and missing repo roots with the expected non-zero exit behavior.
- Repairing the stale `local.yaml` entry restored doctor success.
- `.openspec/workspace.yaml` remained unchanged across local path mutations, so committed metadata stayed stable while only the local overlay changed.
## Fixes applied
- No additional product fixes were required during this manual smoke pass.
## Residual risks
- No user-visible Phase 04 issues were found in this manual smoke run.
@@ -0,0 +1,46 @@
# Phase 04 Summary
## Changes made
- Added core registry coverage in `test/core/workspace/registry.test.ts` for:
- alias trimming and invalid alias rejection
- canonical repo-path persistence
- committed metadata stability when `local.yaml` changes
- doctor diagnostics for missing local mappings, missing repo roots, missing `openspec/`, alias/path drift, and extra local aliases
- Added command-surface coverage in `test/commands/workspace/registry.test.ts` for:
- `workspace add-repo`
- healthy `workspace doctor`
- stale `workspace doctor`
- Added CLI e2e coverage in `test/cli-e2e/workspace/workspace-registry-cli.test.ts` for:
- multiple repo additions in one workspace
- healthy doctor JSON output
- stale-path detection and repair via `.openspec/local.yaml`
- Fixed two issues exposed by the new coverage in `src/commands/workspace.ts`:
- corrected pluralized doctor status text for `aliases` and `entries`
- changed doctor issue exits to set `process.exitCode = 1` after printing results instead of calling `process.exit(1)` inside the action body
## Tests or research performed
- `pnpm vitest run test/core/workspace test/commands/workspace test/cli-e2e/workspace`
- `pnpm run build`
- `pnpm vitest run test/core/workspace/registry.test.ts test/commands/workspace/registry.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts`
- Fresh built-CLI smoke on 2026-04-17 covering:
- `workspace create phase04-manual --json`
- two successful `workspace add-repo ... --json` registrations
- healthy `workspace doctor --json`
- forced stale `local.yaml` repo path
- successful doctor recovery after repairing the stale local path
## Results
- All targeted workspace tests passed: 23/23 in the full workspace slice and 8/8 in the Phase 04-focused verification slice.
- Build passed.
- Doctor now reports clean human-readable pluralization in healthy output.
- Doctor still exits non-zero when issues are present, while keeping the command-surface control flow stable enough for interception and tests.
- The registry stayed readable after multiple repo additions, committed metadata remained path-free and stable, and stale local overlay repair restored doctor success.
## Blockers and next-step notes
- No blockers remain for Phase 04.
- No new roadmap phases were required from this test pass.
- Phase 05 can build on the now-covered repo registry and doctor behavior.
@@ -0,0 +1,38 @@
# Phase 04 Verification
Verification re-run in a fresh shell context on 2026-04-17 for ROADMAP Phase 04, cycle 1.
## Checks performed
- Re-read the Phase 04 block in `ROADMAP.md`.
- Reviewed the current phase artifacts for scope and documentation quality:
- `notes/workspace-poc/phase-04-test-repo-registry/SUMMARY.md`
- `notes/workspace-poc/phase-04-test-repo-registry/MANUAL_TEST.md`
- Reviewed the implementation and test coverage for this phase:
- `src/core/workspace/registry.ts`
- `src/commands/workspace.ts`
- `test/core/workspace/registry.test.ts`
- `test/commands/workspace/registry.test.ts`
- `test/cli-e2e/workspace/workspace-registry-cli.test.ts`
- Verified that the implementation boundaries still match the phase intent:
- committed repo aliases live in `.openspec/workspace.yaml`
- local absolute repo paths live only in `.openspec/local.yaml`
- doctor reports missing local mappings, missing repo roots, missing `openspec/`, non-canonical path drift, and extra local aliases
- Rebuilt the CLI with `pnpm run build`.
- Re-ran the Phase 04-focused automated slice with:
- `pnpm vitest run test/core/workspace/registry.test.ts test/commands/workspace/registry.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts`
- Re-ran the broader workspace regression slice with:
- `pnpm vitest run test/core/workspace test/commands/workspace test/cli-e2e/workspace`
## Issues found
- None.
## Fixes applied
- None required.
## Residual risks
- None found for Phase 04 in this verification pass.
- The phase artifacts remain consistent with the implemented scope, and the acceptance coverage is in place across core, command, and CLI layers.
@@ -0,0 +1,64 @@
# Phase 05 Manual Test
Manual smoke re-run in a fresh temp/XDG context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 05, cycle 1.
## Scenarios run
- Rebuilt the current CLI with `pnpm run build`.
- Checked `node dist/cli/index.js new change --help` and confirmed the Phase 05 surface still documents:
- `--description <text>` as seeding the initial change artifact
- `--targets <aliases>` for workspace-targeted change creation
- Created a brand-new isolated CLI environment with:
- `OPENSPEC_TELEMETRY=0`
- fresh `XDG_CONFIG_HOME`
- fresh `XDG_DATA_HOME`
- Created three real repo roots under the temp sandbox:
- `app`
- `api`
- `docs`
- Seeded each repo root with repo-local OpenSpec state via `openspec/changes/` so the real `workspace add-repo` path validation would accept them.
- Ran `node dist/cli/index.js workspace create phase05-manual-cycle1 --json`.
- Ran the real repo registration flow from inside that managed workspace:
- `node dist/cli/index.js workspace add-repo app <path> --json`
- `node dist/cli/index.js workspace add-repo api <path> --json`
- `node dist/cli/index.js workspace add-repo docs <path> --json`
- Ran the target-aware create flow:
- `node dist/cli/index.js new change shared-auth --targets app,api --description "Cross-repo auth rollout"`
- Inspected the created workspace change and confirmed:
- `changes/shared-auth/.openspec.yaml` exists
- metadata recorded `schema: spec-driven`
- metadata recorded `targets: [app, api]`
- `proposal.md`, `design.md`, and `tasks/coordination.md` exist
- `targets/app/tasks.md` and `targets/api/tasks.md` exist
- `targets/app/specs/` and `targets/api/specs/` exist
- Verified the untargeted and targeted repos all remained free of repo-local materialization:
- `<app>/openspec/changes/shared-auth` does not exist
- `<api>/openspec/changes/shared-auth` does not exist
- `<docs>/openspec/changes/shared-auth` does not exist
- Exercised the negative CLI cases in the same fresh workspace:
- `node dist/cli/index.js new change dup-targets --targets app,app`
- `node dist/cli/index.js new change unknown-target --targets app,missing`
- reran `node dist/cli/index.js new change shared-auth --targets app,api`
- Re-ran `node dist/cli/index.js workspace doctor --json` after targeted creation.
## Results
- All manual smoke scenarios passed.
- The real targeted-create flow produced the expected central workspace scaffold under `changes/shared-auth/`.
- The workspace change metadata recorded the exact requested target set: `app`, `api`.
- Duplicate target aliases failed with a non-zero exit and the expected actionable message: `Duplicate target alias 'app' in --targets. Remove duplicates and retry.`
- Unknown target aliases failed with a non-zero exit and the expected actionable message naming the missing alias and registered aliases.
- Reusing the same workspace change ID failed predictably with the existing duplicate-change error.
- No repo-local change directories were created in any registered repo during `new change`.
- `workspace doctor --json` still returned `status: "ok"` after targeted creation, so the registry remained healthy.
- The generated metadata still stored `created: 2026-04-16` during this 2026-04-17 Australia/Sydney run because the shared date path remains UTC-based.
## Fixes applied
- No product fixes were required during this manual-test pass.
## Residual risks
- No Phase 05 user-visible regressions were found in this manual smoke cycle.
- The shared metadata `created` field still reflects UTC day boundaries rather than local date boundaries. That was observed again here, but it is existing shared behavior rather than a Phase 05-specific regression.
- Permanent automated coverage for this flow is still expected in Phase 06.
@@ -0,0 +1,52 @@
# Phase 05 Summary
## Changes made
- Added workspace-aware change creation in [src/commands/workflow/new-change.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workflow/new-change.ts) so `openspec new change <id> --targets <a,b,c>` now detects managed workspaces, requires explicit targets there, and still preserves the existing repo-local path outside a workspace.
- Added [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts) to:
- parse and validate `--targets`
- reject duplicate or unknown aliases before writing anything
- create workspace changes under `changes/<id>/`
- scaffold `proposal.md`, `design.md`, `tasks/coordination.md`, and per-target `targets/<alias>/tasks.md` plus `targets/<alias>/specs/`
- Extended change metadata in [src/core/artifact-graph/types.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/artifact-graph/types.ts) and reused the shared metadata writer so workspace changes persist explicit `targets` in `.openspec.yaml`.
- Added `findWorkspaceRoot()` in [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts) so the command can detect workspace topology without disturbing the existing registry and doctor flows.
- Extracted schema resolution into [src/utils/change-utils.ts](/Users/tabishbidiwale/fission/repos/openspec/src/utils/change-utils.ts) so repo-local and workspace change creation both resolve schemas through the same path.
- Updated [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts) to expose `--targets` on `openspec new change`.
- Clarified the `openspec new change --help` text in [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts) so `--description` no longer incorrectly promises a `README.md` write for workspace-targeted changes.
- Expanded [test/utils/change-metadata.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/utils/change-metadata.test.ts) so shared metadata coverage now includes persisted target aliases and duplicate-target rejection.
## Tests or research performed
- `pnpm run build`
- `pnpm vitest run test/utils/change-metadata.test.ts test/utils/change-utils.test.ts test/core/workspace/registry.test.ts`
- `node dist/cli/index.js new change --help`
- Fresh isolated CLI smoke on 2026-04-17 (Australia/Sydney) with telemetry disabled:
- `openspec workspace create phase05-manual`
- `openspec workspace add-repo app <path>`
- `openspec workspace add-repo api <path>`
- `openspec workspace add-repo docs <path>`
- `openspec new change shared-auth --targets app,api --description "Cross-repo auth rollout"`
- verified `changes/shared-auth/.openspec.yaml`
- verified `proposal.md`, `design.md`, `tasks/coordination.md`, and `targets/{app,api}/{tasks.md,specs/}`
- verified no `openspec/changes/shared-auth` directory was created in any registered repo
- verified duplicate-target, unknown-target, and duplicate-change-ID failures
- Fresh isolated post-create health check:
- `openspec workspace doctor --json` after targeted creation
## Results
- Build passed.
- Focused regression coverage passed: 51/51 tests.
- Targeted workspace changes now record the exact target list in `.openspec.yaml`.
- The workspace change layout now includes the central planning scaffold plus per-target task/spec partitions under `changes/<id>/targets/`.
- Unknown targets and duplicate targets fail before any workspace artifacts are written, with actionable error messages.
- Repo-local repos remained untouched during creation; no target repo received a materialized `openspec/changes/<id>` directory.
- Duplicate workspace change IDs still fail predictably at the workspace change path.
- `workspace doctor --json` still reported `status: "ok"` after targeted change creation, so the new flow does not corrupt workspace registry state.
- The CLI help output now describes `--description` generically enough to match both repo-local and workspace-targeted change creation.
## Blockers and next-step notes
- No blockers remain for Phase 05.
- No new roadmap phases were required from this implementation pass.
- Phase 06 should add dedicated permanent unit, command, and CLI coverage for the new workspace-targeted change path instead of relying on the focused shared regressions and CLI smoke used here.
@@ -0,0 +1,43 @@
# Phase 05 Verification
Independent verification re-run in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 05, cycle 1.
## Checks performed
- Re-read the Phase 05 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and the current phase artifacts in [SUMMARY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-05-targeted-change-create/SUMMARY.md) and [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-05-targeted-change-create/MANUAL_TEST.md).
- Reviewed the implementation boundary in:
- [src/commands/workflow/new-change.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workflow/new-change.ts)
- [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts)
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
- [src/utils/change-utils.ts](/Users/tabishbidiwale/fission/repos/openspec/src/utils/change-utils.ts)
- [src/core/artifact-graph/types.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/artifact-graph/types.ts)
- [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts)
- [test/utils/change-metadata.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/utils/change-metadata.test.ts)
- Confirmed `openspec new change --help` documents both `--targets` and the updated generic `--description` behavior.
- Rebuilt the current tree with `pnpm run build`.
- Re-ran focused regressions with `pnpm vitest run test/utils/change-metadata.test.ts test/utils/change-utils.test.ts test/core/workspace/registry.test.ts`.
- Ran a fresh isolated CLI verification with the built CLI and telemetry disabled:
- created a managed workspace
- registered `app`, `api`, and `docs`
- created `shared-auth` with `--targets app,api`
- inspected `changes/shared-auth/.openspec.yaml`
- confirmed `proposal.md`, `design.md`, `tasks/coordination.md`, and per-target `tasks.md` plus `specs/` directories
- confirmed no repo-local `openspec/changes/shared-auth` directory was created in any registered repo
- confirmed duplicate-target, unknown-target, and duplicate-change-ID failures returned non-zero exits with actionable messages
- confirmed `openspec workspace doctor --json` returned `status: "ok"` after targeted creation
- Observed that the generated metadata stored `created: 2026-04-16` during this 2026-04-17 Australia/Sydney verification run because the shared date path still uses UTC `toISOString()`.
## Issues found
- `openspec new change --help` still said `--description` adds text to `README.md`, which was inaccurate for workspace-targeted changes that seed `proposal.md` instead.
## Fixes applied
- Updated [src/cli/index.ts](/Users/tabishbidiwale/fission/repos/openspec/src/cli/index.ts) so `--description` is described as seeding the initial change artifact rather than specifically writing `README.md`.
- Rebuilt the CLI and rechecked both `openspec new change --help` and the fresh targeted-create smoke flow after that text change.
## Residual risks
- No Phase 05 correctness blockers remain after verification.
- Dedicated permanent automated coverage for workspace-targeted change creation is still intentionally deferred to Phase 06.
- The shared metadata `created` date remains UTC-based. On 2026-04-17 in Australia/Sydney, the generated file stored `2026-04-16`. This is existing shared behavior rather than a Phase 05-specific regression.
@@ -0,0 +1,47 @@
# Phase 06 Manual Test
Manual pass date: 2026-04-17
Phase cycle: 1
Stage: `manual-test`
## Scenarios run
- Reused the current built CLI from `pnpm run build`.
- Created a fresh isolated workspace by copying the `happy-path` workspace fixture and repo fixtures into a temporary directory.
- Rewrote `.openspec/local.yaml` in the copied workspace so `app`, `api`, and `docs` pointed to canonical absolute repo paths inside the temporary fixture root.
On this macOS host, that canonicalization resolved the temp repo roots under `/private/var/...`.
- Created repo-local `openspec/changes/` directories in all three attached repos so `workspace doctor` exercised a healthy registered workspace.
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color new change phase06-manual --targets app,api` from the workspace root.
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color status --change phase06-manual --json`.
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color workspace doctor --json`.
- Ran `OPEN_SPEC_TELEMETRY_DISABLED=1 node bin/openspec.js --no-color new change phase06-bad --targets app,missing`.
- Checked that no repo-local `openspec/changes/phase06-manual` or `openspec/changes/phase06-bad` directories existed in `app`, `api`, or `docs`.
## Results
- `new change phase06-manual --targets app,api` exited `0` and created `changes/phase06-manual/` in the workspace root.
- The resulting workspace change kept the expected central planning topology:
- `.openspec.yaml`
- `proposal.md`
- `design.md`
- `tasks/coordination.md`
- `targets/app/{tasks.md,specs/}`
- `targets/api/{tasks.md,specs/}`
- `status --change phase06-manual --json` exited `0` and returned parseable JSON for the workspace change.
- The status JSON reported:
- `proposal: done`
- `design: done`
- `specs: ready`
- `tasks: blocked` by `specs`
- `workspace doctor --json` exited `0` and returned `status: "ok"` with `issues: []`.
- `new change phase06-bad --targets app,missing` exited `1` with `Unknown target alias: missing. Registered aliases: api, app, docs`.
- No repo-local change directories were created in any attached repo for either the successful or rejected create attempt.
## Fixes applied
- No product fixes were required during this manual-test pass.
- The temporary workspace overlay was canonicalized before running `workspace doctor --json` so the copied fixture matched the CLI's expected path form on this macOS host.
## Residual risks
- None found within the Phase 06 scope.
@@ -0,0 +1,57 @@
# Phase 06 Summary
Phase cycle: 1
Stage: `implementation`
## Changes made
- Added workspace-aware change-container helpers in `src/core/workspace/metadata.ts` and reused them from:
- `src/commands/workflow/shared.ts`
- `src/core/artifact-graph/instruction-loader.ts`
- Fixed the workflow path mismatch exposed by the new coverage so `status --change <name>` can read workspace-created changes from top-level `changes/` instead of only repo-local `openspec/changes/`.
- Added an exact workspace-change topology assertion to `test/helpers/workspace-assertions.ts`.
- Added focused core coverage in `test/core/workspace/change-create.test.ts` for:
- `parseWorkspaceTargets()`
- workspace change metadata
- layout-only central planning scaffolds
- unknown alias rejection
- Added command-surface coverage in `test/commands/workflow/new-change.workspace.test.ts` for targeted change creation inside a registered workspace.
- Added CLI e2e coverage in `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts` for:
- successful targeted creation
- unknown alias rejection
- untouched repo-local roots
- healthy `status` and `workspace doctor` after creation
## Tests or research performed
- `pnpm run build`
- `pnpm vitest --run test/core/workspace/change-create.test.ts test/commands/workflow/new-change.workspace.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- `pnpm vitest --run test/core/artifact-graph/instruction-loader.test.ts test/commands/artifact-workflow.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- `git diff --check -- src/core/workspace/metadata.ts src/commands/workflow/shared.ts src/core/artifact-graph/instruction-loader.ts test/helpers/workspace-assertions.ts test/core/workspace/change-create.test.ts test/commands/workflow/new-change.workspace.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Fresh built-CLI smoke in an isolated copied workspace fixture with telemetry disabled:
- `node bin/openspec.js --no-color new change phase06-manual --targets app,api`
- `node bin/openspec.js --no-color status --change phase06-manual --json`
- `node bin/openspec.js --no-color workspace doctor --json`
- `node bin/openspec.js --no-color new change phase06-bad --targets app,missing`
- explicit repo-root checks that no `openspec/changes/phase06-manual` or `openspec/changes/phase06-bad` directories were created under `app`, `api`, or `docs`
## Results
- Build passed.
- The focused Phase 06 slice passed: 9/9 tests.
- The broader regression slice that touches workflow loading and workspace registry behavior passed: 98/98 tests.
- `new change --targets` now has direct coverage for rejecting aliases outside the workspace registry.
- Workspace change creation is now proven to produce only:
- central planning artifacts at the workspace change root
- per-target partitions under `targets/<alias>/`
- Successful targeted creation leaves repo-local `openspec/changes/` roots untouched before any materialization step.
- `status --change` now succeeds for workspace-created changes and reports the expected incomplete planning state:
- `proposal` and `design` are `done`
- `specs` is `ready`
- `tasks` is `blocked` by missing `specs`
- `workspace doctor --json` still reports a healthy workspace after targeted change creation.
## Blockers and next-step notes
- No blockers remain for Phase 06.
- No new bounded follow-up phases were required from this implementation pass.
@@ -0,0 +1,48 @@
# Phase 06 Verification
Verification re-run in a fresh shell context on 2026-04-17 for ROADMAP Phase 06, cycle 1.
## Checks performed
- Re-read the Phase 06 block in `ROADMAP.md`.
- Reviewed the current phase artifacts for scope and note quality:
- `notes/workspace-poc/phase-06-test-targeted-change-create/SUMMARY.md`
- `notes/workspace-poc/phase-06-test-targeted-change-create/MANUAL_TEST.md`
- Reviewed the implementation and tests touched by this phase:
- `src/commands/workflow/new-change.ts`
- `src/core/workspace/change-create.ts`
- `src/core/workspace/metadata.ts`
- `src/commands/workflow/shared.ts`
- `src/core/artifact-graph/instruction-loader.ts`
- `test/helpers/workspace-assertions.ts`
- `test/core/workspace/change-create.test.ts`
- `test/commands/workflow/new-change.workspace.test.ts`
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Rebuilt the CLI with `pnpm run build`.
- Re-ran the focused Phase 06 automated slice:
- `pnpm vitest --run test/core/workspace/change-create.test.ts test/commands/workflow/new-change.workspace.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Re-ran the closest regression slice for shared workflow path resolution and workspace health:
- `pnpm vitest --run test/core/artifact-graph/instruction-loader.test.ts test/commands/artifact-workflow.test.ts test/cli-e2e/workspace/workspace-registry-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Ran `git diff --check` on the Phase 06 source, helper, and test files.
- Re-executed the manual smoke against a freshly copied `happy-path` workspace fixture with telemetry disabled:
- `node bin/openspec.js --no-color new change phase06-manual --targets app,api`
- `node bin/openspec.js --no-color status --change phase06-manual --json`
- `node bin/openspec.js --no-color workspace doctor --json`
- `node bin/openspec.js --no-color new change phase06-bad --targets app,missing`
- explicit repo-root checks that no `openspec/changes/phase06-manual` or `openspec/changes/phase06-bad` directories were created under `app`, `api`, or `docs`
## Issues found
- No remaining product or test failures were found in the current Phase 06 scope.
- During the first manual smoke setup, the temporary workspace overlay used raw `/var/...` paths; on this macOS host `workspace doctor --json` correctly flagged them as `non-canonical-path` drift because the canonical repo roots resolve under `/private/var/...`.
## Fixes applied
- No additional fixes were required during this verification pass.
- Corrected the manual verification setup to rewrite `.openspec/local.yaml` with canonicalized repo paths before the final `workspace doctor --json` check.
- Refreshed this verification artifact so it reflects the current post-fix validation run instead of an empty placeholder.
## Residual risks
- No blocking risks remain within the Phase 06 scope.
- This phase stays bounded to targeted workspace change creation and its pre-materialization stability checks; later workspace-open and materialization behavior remains outside this phase.
@@ -0,0 +1,189 @@
# Phase 07 Decision
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Recommended contract
The minimum honest v0 contract for `workspace open` is:
- `openspec workspace open` is a planning-only session-prep command.
- `openspec workspace open --change <id>` is a change-scoped attached-roots session-prep command.
- v0 produces a usable instruction surface for one supported agent path instead of promising generic external process launch.
- v0 officially supports only `--agent claude`. Omitting `--agent` defaults to `claude`.
- `workspace open --change <id>` resolves only that change's targeted repos and hard-fails if any target repo is unresolved.
- `workspace open` never materializes repo-local changes and never replaces `openspec apply --change <id> --repo <alias>`.
This is the smallest contract that is still real:
- planning-only mode is useful even when no repos are ready
- attached mode is honest only when every targeted repo is actually readable
- the CLI stays responsible for materialization, not the agent
- the POC avoids claiming multi-agent parity that the current code and tool landscape do not prove
## Why this contract
Evidence reviewed for this phase:
- `src/commands/workspace.ts` currently implements only `create`, `add-repo`, and `doctor`; there is no `open` entrypoint yet.
- `src/core/workspace/registry.ts` already defines the concrete repo-resolution failure states the new command can build on.
- `src/core/workspace/change-create.ts` already makes target aliases explicit in workspace change metadata.
- `src/core/command-generation/adapters/claude.ts`, `codex.ts`, and `github-copilot.ts` show that command formatting exists, but not a stable cross-tool attach-at-launch contract.
- `docs/supported-tools.md` already documents that Copilot custom prompts are IDE-only and that Codex commands are global prompts, which is weaker than a clean repo-scoped attach story.
- `WORKSPACE_POC_PRD.md` and `WORKSPACE_POC_DECISION_RECORD.md` both point toward planning-only vs attached-roots mode and a single primary demo path.
The practical conclusion is:
- planning-only mode should exist independently of repo resolution
- change-scoped attached mode should be all-targets-or-fail
- the first shipped path should optimize for one tool, not theoretical parity
## Exact user-visible behavior
### `openspec workspace open`
`workspace open` with no `--change` enters planning-only mode.
Behavior:
- Must be run inside a managed workspace created with `openspec workspace create`.
- Defaults to `--agent claude` when `--agent` is omitted.
- Does not resolve repo aliases and does not attach any repo roots.
- Exits successfully with a planning-only instruction surface rooted at the workspace.
- The surface must state:
- mode: `planning-only`
- workspace root path
- agent target
- attached repos: `none`
- next step: use the workspace for central planning, then run `workspace open --change <id>` when target repos need to be in view
- Does not create or update repo-local change artifacts.
- Does not mutate workspace metadata.
### `openspec workspace open --change <id>`
`workspace open --change <id>` enters change-scoped attached-roots mode.
Behavior:
- Must be run inside a managed workspace created with `openspec workspace create`.
- Defaults to `--agent claude` when `--agent` is omitted.
- Validates that `changes/<id>/` exists in the workspace.
- Reads the workspace change metadata and requires a non-empty `targets` list.
- Resolves only the aliases named in that change's `targets`.
- Treats a target as resolved only when:
- the alias is registered in workspace metadata
- the alias has a local overlay path
- the resolved path exists and is a directory
- the resolved path contains repo-local OpenSpec state at `openspec/`
- On success, exits with a change-scoped instruction surface that states:
- mode: `change-scoped`
- workspace root path
- change ID and change path
- agent target
- attached repos: only the targeted aliases with their resolved absolute paths
- a reminder that `openspec apply --change <id> --repo <alias>` is still the supported materialization step
- Does not attach every registered repo.
- Does not create or update repo-local change artifacts.
### Failure behavior for targeted repos
`workspace open --change <id>` fails the entire command if one or more targeted repos are unresolved.
Behavior:
- Exit code is non-zero.
- No partial success surface is emitted.
- The error names every failing alias and why it failed.
- The error points the user to `openspec workspace doctor` or the exact alias that needs repair.
Fatal failure reasons:
- change does not exist
- change metadata has no `targets`
- target alias is missing from the workspace registry
- target alias is missing from `.openspec/local.yaml`
- target repo path is missing
- target repo path is not a directory
- target repo path exists but lacks `openspec/`
Non-fatal nuance:
- A non-canonical but still valid stored path may be normalized for use and surfaced as drift, but it is not by itself an unresolved-target failure.
## Supported agent targets in v0
Decision:
- `claude` is the only officially supported `workspace open` agent target in v0.
- Omitting `--agent` is equivalent to `--agent claude`.
- Non-primary agents are explicitly out of scope for Phase 08 v0 behavior.
Rationale:
- Phase 08 only needs one primary agent path to produce a real demoable outcome.
- The current codebase has command-format adapters for many tools, but that is not the same as proving stable multi-root session-open behavior.
- Claude is already the clearest documented primary path in the workspace POC docs.
- Supporting more tools now would expand the test matrix faster than the current workspace implementation surface justifies.
Follow-up note:
- Codex is the first revisit candidate after Phase 08 and Phase 09 if the primary path lands cleanly.
- Copilot remains out of scope for v0 because the repo's current support is prompt-file oriented and not a credible one-shot multi-root CLI attach story.
## Rejected alternatives
### Rejected: attach every registered repo
Why rejected:
- it violates the roadmap principle that attachment should be change-scoped, not workspace-wide
- it scales poorly as workspaces grow
- it makes agent context noisy and hides the actual execution set
### Rejected: partial open when some targeted repos are unresolved
Why rejected:
- attached mode is only honest if the agent can see the full targeted working set
- partial success creates a false sense that cross-repo planning is complete
- planning-only mode already covers the "not all repos are ready yet" use case
### Rejected: promise multi-agent parity in v0
Why rejected:
- the repo currently proves command generation, not equal attach semantics across tools
- it would force Phase 08 to solve tool-specific behavior instead of landing one real path
- the roadmap only needs one primary agent path for the POC
### Rejected: auto-launch and manage external agent processes in v0
Why rejected:
- it adds tool-specific process and environment complexity that is not required to prove the contract
- a deterministic instruction surface is enough for the next phase acceptance target
## Testable success and failure cases for Phase 08
### Success cases
- `openspec workspace open` inside a healthy workspace exits `0` and reports `planning-only` with `attached repos: none`.
- `openspec workspace open --change shared-auth` for a change targeting `app,api` exits `0` and lists only `app` and `api`, not other registered aliases like `docs`.
- `openspec workspace open --change shared-auth` reports the workspace root, the change path, and the exact resolved absolute repo paths for the targeted aliases.
- `openspec workspace open --change shared-auth` leaves repo-local `openspec/changes/shared-auth` absent in all targeted repos.
- `openspec workspace open --change shared-auth --agent claude` produces the same usable instruction surface as the default no-flag path.
### Failure cases
- `openspec workspace open` outside a managed workspace exits non-zero with an actionable workspace-root error.
- `openspec workspace open --change missing-change` exits non-zero and names the missing change.
- `openspec workspace open --change planning-only-draft` exits non-zero if the change exists but has no `targets` metadata.
- `openspec workspace open --change shared-auth` exits non-zero when any targeted alias is missing from `.openspec/local.yaml`.
- `openspec workspace open --change shared-auth` exits non-zero when any targeted path is stale, missing, or no longer contains `openspec/`.
- `openspec workspace open --change shared-auth --agent codex` exits non-zero with an unsupported-agent error in v0.
## Blockers and next-step notes
- No new roadmap phase is required from this decision.
- Phase 08 should implement only the recommended contract above and should not broaden agent scope during the build unless a new bounded phase is added first.
@@ -0,0 +1,40 @@
# Phase 07 Manual Test
Manual test stage re-run in a fresh isolated XDG context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 07, cycle 1.
This phase is research-only, so the manual pass combined a real CLI smoke for the current workspace/change workflow boundary with a tabletop review of the proposed `workspace open` contract. `workspace open` is not implemented yet, so the command itself was validated only up to its current user-visible absence (`error: unknown command 'open'`).
## Scenarios run
- Created isolated `XDG_DATA_HOME` and `XDG_CONFIG_HOME` roots under `/tmp` with `OPENSPEC_TELEMETRY=0` so the smoke could exercise the built CLI without writing to the real home directory.
- Ran `node bin/openspec.js --no-color workspace create phase07-manual --json`.
- Created three disposable repo roots with repo-local `openspec/` directories and registered them sequentially:
- `workspace add-repo app ../../../../repos/app --json`
- `workspace add-repo api ../../../../repos/api --json`
- `workspace add-repo docs ../../../../repos/docs --json`
- Ran `workspace doctor --json` to confirm the healthy registry state.
- Ran `node bin/openspec.js --no-color new change shared-auth --targets app,api` inside the managed workspace.
- Inspected `changes/shared-auth/.openspec.yaml` and the generated planning layout under `changes/shared-auth/targets/{app,api}`.
- Ran `node bin/openspec.js --no-color workspace open` and `node bin/openspec.js --no-color workspace open --change shared-auth` to confirm the current CLI surface still rejects `open` as unimplemented.
- Removed `repos/api/openspec`, reran `workspace doctor --json`, restored the directory, and reran `workspace doctor --json` to confirm the existing unresolved-repo diagnostics that Phase 07 relies on.
## Results
- `workspace create`, sequential `workspace add-repo`, `workspace doctor`, and `new change --targets` all worked in the fresh isolated context.
- The created change wrote explicit target metadata to `changes/shared-auth/.openspec.yaml`:
- `schema: spec-driven`
- `targets: app, api`
- The generated planning layout was change-scoped: `changes/shared-auth/targets/app/` and `changes/shared-auth/targets/api/` were created, and no `changes/shared-auth/targets/docs/` directory was created.
- `workspace doctor` reported `status: ok` before the failure injection and then reported a precise `missing-openspec-state` issue for alias `api` after the repo-local `openspec/` directory was removed.
- The current CLI still exposes no `workspace open` subcommand. Both `workspace open` and `workspace open --change shared-auth` failed with `error: unknown command 'open'`.
- Given that runtime boundary, the remaining validation for Phase 07 stayed at the artifact/tabletop level: [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) still matches the current implementation surface and does not overclaim behavior that exists today.
## Fixes applied
- Rewrote this manual-test artifact from the prior authoring-time tabletop note into a fresh-context record with real CLI evidence.
- No product code or roadmap changes were required for Phase 07. The recommended contract in [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) remained valid after the smoke and failure-injection pass.
## Residual risks
- `workspace open` still has no runtime implementation, so this manual pass can only prove the surrounding workflow boundary and the honesty of the proposed contract, not the eventual UX.
- Phase 08 still needs to implement the command exactly as documented, and Phase 09 still needs fixture-backed automated coverage for the success and failure cases listed in [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md).
@@ -0,0 +1,49 @@
# Phase 07 Summary
Phase cycle: 1
Stage: `implementation`
## Changes made
- Added [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) with a concrete v0 contract for `workspace open`.
- Chose the minimum supported behavior for:
- planning-only mode with `openspec workspace open`
- change-scoped attached mode with `openspec workspace open --change <id>`
- hard-fail behavior when one or more targeted repos are unresolved
- official v0 agent support limited to `claude`, with non-primary agents explicitly out of scope
- Added [VERIFY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/VERIFY.md) and [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md) to record the research checks and tabletop/manual review for this phase.
## Tests or research performed
- Re-read the Phase 07 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and confirmed the phase started with no on-disk artifacts.
- Reviewed the current workspace implementation surface in:
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
- [src/core/workspace/metadata.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/metadata.ts)
- [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts)
- Reviewed the existing tool-command surface in:
- [src/core/command-generation/adapters/claude.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/claude.ts)
- [src/core/command-generation/adapters/codex.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/codex.ts)
- [src/core/command-generation/adapters/github-copilot.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/github-copilot.ts)
- [docs/supported-tools.md](/Users/tabishbidiwale/fission/repos/openspec/docs/supported-tools.md)
- Reviewed the higher-level workspace direction in:
- [WORKSPACE_POC_PRD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_PRD.md)
- [WORKSPACE_POC_DECISION_RECORD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_DECISION_RECORD.md)
- Ran focused research verification after drafting:
- content checks against `DECISION.md` for recommended contract, rejected alternatives, exact command behavior, and next-phase success/failure cases
- `git diff --check` on the touched Phase 07 files and `ROADMAP.md`
## Results
- The note now defines one recommended v0 contract instead of leaving `workspace open` underspecified.
- The contract distinguishes planning-only mode from attached-roots mode and keeps repo attachment change-scoped.
- The contract defines exact failure semantics: attached mode is all-targets-or-fail, with actionable diagnostics per failing alias.
- The note explicitly chooses `claude` as the only official v0 agent target and keeps non-primary agents out of scope.
- The note records multiple rejected alternatives so Phase 08 does not accidentally broaden scope.
- The note lists concrete success and failure cases that are directly usable for Phase 08 implementation and Phase 09 test planning.
## Blockers and next-step notes
- No blockers remain for Phase 07.
- No new bounded follow-up phase was required from this research pass.
- Phase 08 should implement only the contract in `DECISION.md` and avoid adding multi-agent or partial-open behavior without a new explicit roadmap phase.
@@ -0,0 +1,54 @@
# Phase 07 Verification
Independent verification completed in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 07, cycle 1.
This phase is research-only. `workspace open` is not implemented yet, so verification here checks the Phase 07 contract against the current codebase, roadmap, and workspace POC docs rather than executing a new CLI command.
## Checks performed
- Re-read the Phase 07 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and verified the completion checklist and acceptance targets for this phase.
- Re-read [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md) and validated the documentation quality for the research output:
- one recommended contract is named
- rejected alternatives are listed
- exact user-visible behavior is defined for both `openspec workspace open` and `openspec workspace open --change <id>`
- concrete success and failure cases are listed for the next build and test phases
- Reviewed the current workspace implementation boundary in:
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
- [src/core/workspace/metadata.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/metadata.ts)
- [src/core/workspace/change-create.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/change-create.ts)
- [src/utils/change-metadata.ts](/Users/tabishbidiwale/fission/repos/openspec/src/utils/change-metadata.ts)
- Confirmed the decision note stays inside the real implementation boundary:
- there is no `workspace open` subcommand yet
- workspace changes already record explicit `targets`
- repo resolution and failure states already exist through workspace registry and doctor behavior
- the note keeps `workspace open` read-only and does not blur into `openspec apply --change <id> --repo <alias>`
- Reviewed the current agent/tool surface in:
- [src/core/command-generation/adapters/claude.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/claude.ts)
- [src/core/command-generation/adapters/codex.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/codex.ts)
- [src/core/command-generation/adapters/github-copilot.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/command-generation/adapters/github-copilot.ts)
- [docs/supported-tools.md](/Users/tabishbidiwale/fission/repos/openspec/docs/supported-tools.md)
- Confirmed the agent-scope choice in the decision note matches the broader workspace POC direction in:
- [WORKSPACE_POC_PRD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_PRD.md)
- [WORKSPACE_POC_DECISION_RECORD.md](/Users/tabishbidiwale/fission/repos/openspec/WORKSPACE_POC_DECISION_RECORD.md)
- Ran `git diff --check -- ROADMAP.md notes/workspace-poc/phase-07-open-contract-research/DECISION.md notes/workspace-poc/phase-07-open-contract-research/SUMMARY.md notes/workspace-poc/phase-07-open-contract-research/VERIFY.md notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md`.
- Ran `rg -n "[[:blank:]]$" ROADMAP.md notes/workspace-poc/phase-07-open-contract-research/DECISION.md notes/workspace-poc/phase-07-open-contract-research/SUMMARY.md notes/workspace-poc/phase-07-open-contract-research/VERIFY.md notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md` and confirmed there is no trailing whitespace in the Phase 07 files.
## Issues found
- The existing `VERIFY.md` was not a clean independent verification artifact. It included stale implementation-stage claims such as "confirmed the phase started with no on-disk artifacts" and authoring-time statements about changes made "during authoring," which do not belong in a fresh verification pass.
- No contract gaps were found in [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md). The acceptance tests for this research phase are satisfied.
## Fixes applied
- Rewrote [VERIFY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/VERIFY.md) to reflect only this fresh-context verification pass.
- Removed stale claims about the prior artifact state and removed authoring-stage commentary that did not belong in independent verification.
- Recorded a direct file-content whitespace check in addition to `git diff --check`, because the Phase 07 files are currently untracked in this worktree.
- No changes were required to [DECISION.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/DECISION.md), [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-07-open-contract-research/MANUAL_TEST.md), or the Phase 07 checklist in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md).
## Residual risks
- No residual research-note gaps were found for Phase 07 itself.
- Runtime proof still belongs to later phases:
- Phase 08 must implement the contract without broadening scope.
- Phase 09 must validate the resulting behavior with fixture-backed tests.
@@ -0,0 +1,50 @@
# Phase 08 Manual Test
Manual smoke re-run in a fresh temp context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 08, cycle 1.
## Scenarios run
- Rebuilt the current CLI with `pnpm run build`.
- Checked `node dist/cli/index.js workspace open --help`.
- Created a brand-new temp sandbox by copying the real fixture state into sibling `workspace/` and `repos/` directories under one temp root, because `.openspec/local.yaml` resolves repo overlays through `../repos/*`:
- `test/fixtures/workspace-poc/dirty/workspace`
- `test/fixtures/workspace-poc/dirty/repos`
- Ran the planning-only flow from inside the copied workspace:
- `node dist/cli/index.js workspace open --json`
- Created a healthy change-scoped case:
- `node dist/cli/index.js new change shared-refresh --targets app,api`
- `node dist/cli/index.js workspace open --change shared-refresh --json`
- Verified the success case output reported:
- `mode: "change-scoped"`
- `change.id: "shared-refresh"`
- attached repos for `app` and `api` only
- no `docs` attachment
- instruction surface path `.claude/commands/opsx/workspace-open.md`
- Verified `workspace open` did not materialize repo-local execution state:
- `repos/app/openspec/changes/shared-refresh` remained absent
- `repos/api/openspec/changes/shared-refresh` remained absent
- `repos/docs/openspec/changes/shared-refresh` remained absent
- Created a stale-target failure case:
- `node dist/cli/index.js new change shared-broken --targets app,docs`
- `node dist/cli/index.js workspace open --change shared-broken`
- Exercised the unsupported-agent path:
- `node dist/cli/index.js workspace open --agent codex`
## Results
- All manual smoke scenarios passed.
- Planning-only open succeeded even though the copied fixture still had a stale `docs` path in `.openspec/local.yaml`, confirming that the no-change path does not attach repo roots.
- Change-scoped open for `shared-refresh` attached only `app` and `api`, not all registered repos.
- Change-scoped open for `shared-broken` failed with a non-zero exit and the expected actionable message naming `docs` plus the `workspace doctor` repair path.
- The unsupported-agent path failed cleanly with `Unsupported agent 'codex' for workspace open in v0. Supported agent: claude.`
- `workspace open` left repo-local `openspec/changes/shared-refresh` directories absent in all copied repos after the smoke run.
- The help surface still exposes the Phase 08 contract cleanly: `--change <id>`, `--agent <tool>` with `claude` as the v0 default, and `--json`.
## Fixes applied
- No product fixes were required during this manual-test pass.
## Residual risks
- No Phase 08 user-visible regressions or residual risks were identified in this manual smoke cycle.
- Phase 09 can still widen the permanent validation matrix, but the shipped Phase 08 user path behaved as intended end to end.
@@ -0,0 +1,56 @@
# Phase 08 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Added [src/core/workspace/open.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/open.ts) so `openspec workspace open` now supports:
- planning-only mode when no `--change` is supplied
- change-scoped mode for `--change <id>`
- defaulting `--agent` to `claude`
- generating a usable Claude instruction surface through the existing command adapter/generator path instead of inventing a separate formatter
- validating that workspace changes exist and have non-empty `targets`
- resolving only the targeted repos for the selected change
- hard-failing with aggregated actionable diagnostics when one or more targeted repos are unresolved
- Extended [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts) with target-specific repo resolution helpers so `workspace open` can reuse the existing registry model while resolving only the change’s requested aliases.
- Extended [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts) with `openspec workspace open`, including both human-readable and `--json` output.
- Added focused Phase 08 coverage in:
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
## Tests or research performed
- `pnpm run build`
- `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
- `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`
- `node dist/cli/index.js workspace open --help`
- Fresh copied-fixture CLI smoke on 2026-04-17 (Australia/Sydney):
- copied `test/fixtures/workspace-poc/dirty/{workspace,repos}` into a fresh temp root
- `node dist/cli/index.js workspace open --json`
- `node dist/cli/index.js new change shared-refresh --targets app,api`
- `node dist/cli/index.js workspace open --change shared-refresh --json`
- verified only `app` and `api` were attached
- verified `repos/{app,api,docs}/openspec/changes/shared-refresh` remained absent after `workspace open`
- `node dist/cli/index.js new change shared-broken --targets app,docs`
- `node dist/cli/index.js workspace open --change shared-broken`
- `node dist/cli/index.js workspace open --agent codex`
## Results
- Build passed.
- Focused Phase 08 tests passed: 7/7.
- Broader workspace regression coverage passed: 37/37.
- `workspace open` without `--change` now succeeds in planning-only mode and reports `attachedRepos: []` / `Attached repos: none`.
- `workspace open --change <id>` now attaches only the change’s targeted repos and does not pull in unrelated registered aliases.
- Change-scoped open now fails clearly when a targeted repo path is stale or missing, and the error names the broken alias plus the `workspace doctor` repair path.
- The primary v0 agent path now produces a usable Claude instruction surface at `.claude/commands/opsx/workspace-open.md`.
- `workspace open` does not materialize repo-local changes during the session-prep flow.
## Blockers and next-step notes
- No blockers remain for Phase 08.
- No new roadmap phases were required from this implementation pass.
- Phase 09 can expand the validation matrix further, but the Phase 08 contract is now implemented, exercised, and manually smoke-tested.
@@ -0,0 +1,41 @@
# Phase 08 Verification
Independent verification re-run in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 08, cycle 1.
## Checks performed
- Re-read the Phase 08 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and the current phase artifacts in [SUMMARY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-08-workspace-open/SUMMARY.md) and [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-08-workspace-open/MANUAL_TEST.md).
- Reviewed the implementation boundary in:
- [src/core/workspace/open.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/open.ts)
- [src/core/workspace/registry.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/registry.ts)
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
- Confirmed `node dist/cli/index.js workspace open --help` documents:
- `--change <id>`
- `--agent <tool>` with `claude` as the default
- `--json`
- Rebuilt the current tree with `pnpm run build`.
- Re-ran the focused Phase 08 suites with `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`.
- Re-ran the broader workspace regression slice with `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`.
- Rechecked the copied-fixture CLI smoke outcomes in a fresh temp root while preserving the expected sibling `workspace/` and `repos/` fixture layout from `.openspec/local.yaml`:
- planning-only open attached no repos even with a stale non-targeted `docs` overlay entry
- change-scoped open for a change targeting `app,api` attached only those repos
- change-scoped open for a change targeting `app,docs` failed non-zero with an aggregated alias-specific diagnostic
- unsupported-agent open failed cleanly with the documented v0 `claude`-only error
## Issues found
- No Phase 08 product correctness issues were found during the independent verification pass.
- The manual test notes were slightly underspecified about fixture layout. Copying the dirty workspace fixture into an arbitrary directory name breaks the smoke harness because the checked-in local overlay uses relative `../repos/*` paths.
## Fixes applied
- No product code changes were required during verification.
- Clarified [MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-08-workspace-open/MANUAL_TEST.md) so the copied-fixture smoke explicitly preserves sibling `workspace/` and `repos/` directories.
## Residual risks
- `workspace open` intentionally supports only `claude` in v0. That is the chosen Phase 08 contract, not an accidental gap.
- Phase 09 can still widen and harden the validation matrix, especially around unsupported-agent coverage and extra edge cases, but no Phase 08 blocker remains.
@@ -0,0 +1,49 @@
# Phase 09 Manual Test
Manual smoke re-run in a fresh temp context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 09, cycle 1.
## Scenarios run
- Rebuilt the current CLI with `pnpm run build`.
- Created a brand-new temp sandbox by copying the real dirty fixture into sibling `workspace/` and `repos/` directories under one temp root:
- `test/fixtures/workspace-poc/dirty/workspace`
- `test/fixtures/workspace-poc/dirty/repos`
- Canonicalized the temp root with `pwd -P` before making path assertions so the smoke matched the CLI's real canonical path output on macOS.
- Confirmed the copied dirty fixture preserved the stale `docs` alias pointing at a missing `repos/docs-missing` path before exercising the failure case.
- Ran the planning-only flow:
- `node dist/cli/index.js workspace open --json`
- Created a healthy change-scoped case:
- `node dist/cli/index.js new change shared-refresh --targets app,api`
- `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
- Verified the success case output reported:
- `Prepared change-scoped workspace open surface for claude.`
- instruction surface path `.claude/commands/opsx/workspace-open.md`
- attached repos for `app` and `api` only
- no `docs` attachment
- the `openspec apply --change shared-refresh --repo <alias>` reminder
- Verified the session-prep contract stayed intact:
- `workspace/.claude/commands/opsx/workspace-open.md` was still absent on disk after the command
- `repos/app/openspec/changes/shared-refresh` was absent
- `repos/api/openspec/changes/shared-refresh` was absent
- Created a stale-target failure case:
- `node dist/cli/index.js new change shared-broken --targets app,docs`
- `node dist/cli/index.js workspace open --change shared-broken`
- Exercised the unsupported-agent path:
- `node dist/cli/index.js workspace open --agent codex`
## Results
- All manual smoke scenarios passed.
- Planning-only open succeeded without exposing attached repo roots, even with the copied fixture still carrying the stale `docs -> repos/docs-missing` alias.
- Change-scoped open for `shared-refresh` attached only `app` and `api`, not all registered repos.
- The Claude demo path remained instruction-surface only; it did not write a `.claude` command file and did not materialize repo-local execution state.
- Change-scoped open for `shared-broken` failed with a non-zero exit and the expected actionable message naming `docs`, the missing `repos/docs-missing` path, and the `workspace doctor` repair path.
- The unsupported-agent path failed cleanly with `Unsupported agent 'codex' for workspace open in v0. Supported agent: claude.`
## Fixes applied
- No product fixes were required during this manual-test pass.
## Residual risks
- No new user-visible residual risks were identified within the Phase 09 validation scope.
@@ -0,0 +1,49 @@
# Phase 09 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Added stronger Phase 09 validation coverage for `workspace open` in:
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
- Strengthened the planning-only assertions so Phase 09 now proves the surface does not leak attached repo roots, including stale overlay paths from the dirty fixture.
- Added command and CLI coverage that proves change-scoped open lists only targeted aliases and excludes unrelated registered repos.
- Added unsupported-agent coverage for the documented v0 contract (`claude` only), using `codex` as the explicit negative case even though that tool has a command adapter elsewhere in the repo.
- Added non-JSON CLI e2e coverage for the primary Claude demo path and asserted that `workspace open` stays session-prep only:
- no `.claude/commands/opsx/workspace-open.md` file is written to disk
- no repo-local `openspec/changes/<id>` materialization is created in attached repos
- Updated the Phase 09 checklist in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md).
## Tests or research performed
- `pnpm run build`
- `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
- `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`
- Fresh copied-fixture CLI smoke on 2026-04-17 (Australia/Sydney):
- copied `test/fixtures/workspace-poc/dirty/{workspace,repos}` into a fresh temp root while preserving sibling `workspace/` and `repos/`
- canonicalized the temp root with `pwd -P` so the smoke assertions matched the CLI's real path normalization on macOS
- ran `node dist/cli/index.js workspace open --json`
- ran `node dist/cli/index.js new change shared-refresh --targets app,api`
- ran `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
- ran `node dist/cli/index.js new change shared-broken --targets app,docs`
- ran `node dist/cli/index.js workspace open --change shared-broken`
- ran `node dist/cli/index.js workspace open --agent codex`
## Results
- Build passed.
- Focused Phase 09 workspace-open validation passed: 12/12 tests.
- Broader workspace regression coverage passed: 42/42 tests.
- Planning-only open now has permanent coverage proving it exposes no attached repo roots in either JSON output or the generated instruction surface.
- Change-scoped open now has permanent coverage proving it attaches only the targeted aliases and excludes unrelated registered repos.
- Failure coverage now proves unresolved target diagnostics include both the failing alias and the `workspace doctor` repair path.
- The primary Claude demo path is covered end to end in CLI e2e without relying on real multi-root writes or repo-local materialization.
## Blockers and next-step notes
- No blockers remain for Phase 09.
- No new roadmap phases were required from this validation pass.
@@ -0,0 +1,47 @@
# Phase 09 Verification
Independent verification re-run in a fresh context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 09, cycle 1.
## Checks performed
- Re-read the Phase 09 block in [ROADMAP.md](/Users/tabishbidiwale/fission/repos/openspec/ROADMAP.md) and the current implementation summary in [notes/workspace-poc/phase-09-test-workspace-open/SUMMARY.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-09-test-workspace-open/SUMMARY.md).
- Reviewed the implementation boundary in:
- [src/core/workspace/open.ts](/Users/tabishbidiwale/fission/repos/openspec/src/core/workspace/open.ts)
- [src/commands/workspace.ts](/Users/tabishbidiwale/fission/repos/openspec/src/commands/workspace.ts)
- [test/core/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/core/workspace/open.test.ts)
- [test/commands/workspace/open.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/commands/workspace/open.test.ts)
- [test/cli-e2e/workspace/workspace-open-cli.test.ts](/Users/tabishbidiwale/fission/repos/openspec/test/cli-e2e/workspace/workspace-open-cli.test.ts)
- Rebuilt the current tree with `pnpm run build`.
- Re-ran the focused Phase 09 suites with `pnpm vitest run test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`.
- Result: 3 files passed, 12/12 tests passed.
- Re-ran the broader workspace regression slice with `pnpm vitest run test/core/workspace/*.test.ts test/commands/workspace/*.test.ts test/cli-e2e/workspace/*.test.ts`.
- Result: 13 files passed, 42/42 tests passed.
- Re-ran a fresh copied-fixture CLI smoke against sibling `workspace/` and `repos/` directories under a new temp root, canonicalized with `pwd -P`, then exercised:
- `node dist/cli/index.js workspace open --json`
- `node dist/cli/index.js new change shared-refresh --targets app,api`
- `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
- `node dist/cli/index.js new change shared-broken --targets app,docs`
- `node dist/cli/index.js workspace open --change shared-broken`
- `node dist/cli/index.js workspace open --agent codex`
- Validated the documented contract and notes quality for this phase:
- planning-only open exposes no attached repo roots
- change-scoped open lists only targeted aliases
- stale-target diagnostics name the failing alias and `workspace doctor`
- the Claude demo path stays session-prep only and does not write a real multi-root command file or repo-local materialization
- [notes/workspace-poc/phase-09-test-workspace-open/MANUAL_TEST.md](/Users/tabishbidiwale/fission/repos/openspec/notes/workspace-poc/phase-09-test-workspace-open/MANUAL_TEST.md) still matches the real CLI behavior exercised in this pass
## Issues found
- No product correctness issues were found.
- No acceptance-test coverage gaps were found for the Phase 09 scope.
- No documentation-quality issues were found in the current summary or manual-test notes.
## Fixes applied
- No product or test changes were required during this verification pass.
- Updated this verification artifact to reflect the fresh-context checks and outcomes above.
## Residual risks
- No residual risks were identified within the Phase 09 verification scope.
- The `claude`-only agent constraint remains an intentional v0 boundary and is explicitly covered by negative tests.
@@ -0,0 +1,185 @@
# Phase 10 Decision
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Recommended v0 contract
The v0 materialization contract for `openspec apply --change <id> --repo <alias>` is:
- create-only at the selected target repo
- zero overwrite behavior
- no refresh or re-materialize path in v0
- reuse the workspace change ID as the repo-local change ID
- keep the repo-local bundle self-contained enough to execute without going back to the workspace
- keep workspace planning artifacts intact after apply
In concrete terms, a successful v0 apply writes exactly one repo-local change at:
`<resolved-repo>/openspec/changes/<change-id>/`
The repo-local bundle should contain:
- `.openspec.yaml` with the workspace change schema and a repo-local `created` date
- `proposal.md` copied from the workspace change root
- `design.md` copied from the workspace change root
- `tasks.md` copied from `targets/<alias>/tasks.md`
- `specs/` copied from `targets/<alias>/specs/`
- `.openspec.materialization.yaml` as the minimum trace sidecar
The trace sidecar should be the smallest machine-readable link needed for later roll-up without redesigning core change metadata:
```yaml
source: workspace
workspaceName: <workspace metadata name>
targetAlias: <alias>
materializedAt: <ISO-8601 timestamp>
```
This file intentionally does not store absolute paths.
What stays in the workspace only:
- `tasks/coordination.md`
- any other workspace-only planning notes outside the selected target slice
- the original `targets/` tree
## Why this contract
Evidence reviewed for this phase:
- `src/core/workspace/open.ts` explicitly keeps `workspace open` read-only and tells the user that repo-local materialization happens later with `openspec apply --change <id> --repo <alias>`.
- `src/core/workspace/change-create.ts` already stores the shared planning truth centrally: schema, created date, and explicit target aliases in the workspace change.
- `src/utils/change-metadata.ts` and `src/core/artifact-graph/types.ts` currently model normal change metadata as `schema`, `created`, and optional `targets`; adding traceability through a sidecar is less invasive than expanding `.openspec.yaml` first.
- `schemas/spec-driven/schema.yaml` expects repo-local execution artifacts in their normal locations, especially root-level `tasks.md` and `specs/`.
- The current CLI surface has schema-aware apply instructions, but no repo-aware `apply --repo` materialization implementation yet, so Phase 11 should land a narrow write contract instead of a refresh engine.
The practical conclusion is:
- create-only is the smallest honest contract for the POC
- repo-local execution should not depend on the workspace remaining mounted in context
- traceability should be explicit, but minimal
## Exact v0 behavior
### Preconditions
`openspec apply --change <id> --repo <alias>` should hard-fail unless all of the following are true:
- the command is run from a managed workspace root
- `changes/<id>/` exists in that workspace
- the workspace change metadata contains `targets`
- `<alias>` is one of those targets
- `<alias>` resolves through workspace metadata and local overlay to a live repo containing `openspec/`
- the workspace change has the source files needed for a repo-local execution bundle:
- `proposal.md`
- `design.md`
- `targets/<alias>/tasks.md`
- `targets/<alias>/specs/` (may be empty, but the directory must exist)
- the destination repo does not already contain `openspec/changes/<id>/`
### Successful materialization
A materialization counts as successful only when:
- the command exits `0`
- only the selected target repo is modified
- the destination repo now contains one complete repo-local change at `openspec/changes/<id>/`
- that repo-local change includes the exact files listed in the recommended contract above
- the workspace change remains intact and unchanged after the write
At the selected-repo scope, success is all-or-nothing:
- validate every source and destination condition before writing
- stage the repo-local bundle in a fresh temp directory
- move it into place only after the bundle is complete
- if staging fails, clean up the temp directory and leave the final destination absent
### Repeat `apply` behavior
The repeat-call behavior in v0 is:
- first successful apply for a target repo creates that repo-local change and transfers execution authority for that target
- repeating apply for the same `<change-id>` and the same `<alias>` fails clearly because v0 is create-only
- repeating apply for a different targeted alias is allowed if that other target repo does not already have `openspec/changes/<id>/`
- editing workspace planning artifacts after one repo has already been materialized does not refresh that repo on a repeat apply; divergence is expected until a future refresh contract exists
The user-facing rule is simple:
- if the repo-local change already exists, OpenSpec protects it and refuses to overwrite it
### Conflict handling
These cases should fail non-zero with no partial success:
- unknown repo alias
- alias registered in the workspace but not targeted by the selected workspace change
- stale or missing target repo path
- target repo missing `openspec/`
- missing workspace source files for the selected target slice
- pre-existing destination change directory or destination file collision
The error should say whether the failure is:
- a target-selection problem
- a repo-resolution problem
- a source-artifact problem
- or a create-only collision
## Explicit non-goals
The v0 contract explicitly does not include:
- refresh or re-materialize behavior
- selective overwrite of existing repo-local files
- sync-back from repo-local execution into workspace drafts
- automatic workspace status updates during apply
- automatic promotion of shared drafts into a canonical owner repo
- copying workspace coordination tasks into repo-local execution bundles
- expanding `.openspec.yaml` with richer workspace-link metadata in this phase
## Rejected alternatives
### Rejected: support refresh in v0
Why rejected:
- refresh immediately forces overwrite rules, merge semantics, and conflict resolution policy
- the roadmap already leans toward create-only unless this phase proved otherwise
- the POC does not need refresh to prove the planning-to-execution handoff
### Rejected: overwrite an existing repo-local change on repeat apply
Why rejected:
- it risks destroying real repo-local execution state
- it hides authority transfer instead of making it explicit
- it makes repeat behavior harder to explain and harder to test honestly
### Rejected: copy coordination tasks into the repo-local change
Why rejected:
- coordination remains a workspace concern
- copying it into one repo would blur local execution with cross-repo planning
- the target repo should receive only the shared context plus its own execution slice
### Rejected: store trace metadata by expanding `.openspec.yaml` first
Why rejected:
- current change metadata support is intentionally small
- a sidecar is enough for Phase 11 and Phase 13 follow-on work
- it avoids coupling the workspace POC to a broader metadata-schema change
## Phase 11 implications
Phase 11 should implement only this contract:
- one selected repo per apply call
- create-only destination semantics
- normal repo-local change layout
- explicit minimal sidecar trace metadata
No new roadmap phase is required from this decision.
@@ -0,0 +1,45 @@
# Phase 10 Manual Test
Manual smoke re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 10, cycle 1.
## Scenarios run
- Built the current CLI with `pnpm run build`.
- Created a fresh temp root and copied:
- `test/fixtures/workspace-poc/happy-path/workspace` to `<tmp>/workspace`
- `test/fixtures/workspace-poc/happy-path/repos` to `<tmp>/repos`
- Ran the real CLI from the copied workspace with telemetry disabled:
```bash
cd <tmp>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change shared-refresh --targets app,api
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js workspace open --change shared-refresh --agent claude
test ! -e <tmp>/repos/app/openspec/changes/shared-refresh
test ! -e <tmp>/repos/api/openspec/changes/shared-refresh
test ! -e <tmp>/repos/docs/openspec/changes/shared-refresh
```
- Inspected the `workspace open` output to confirm:
- only targeted repos were attached
- the instruction surface still said `Do not materialize repo-local changes from this session.`
- the instruction surface still said `openspec apply --change shared-refresh --repo <alias>`
- Checked that the reported `.claude/commands/opsx/workspace-open.md` path was not actually written during the command.
## Results
- `pnpm run build` passed.
- `new change shared-refresh --targets app,api` succeeded and created the workspace change.
- `workspace open --change shared-refresh --agent claude` succeeded and attached exactly `app` and `api`.
- No repo-local change was materialized in `app`, `api`, or `docs`.
- The instruction surface remained advisory only; the reported `.claude/commands/opsx/workspace-open.md` path was not written to disk.
- The current product boundary still matches `DECISION.md`: planning and session prep happen in the workspace, while repo-local execution remains an explicit later step.
## Fixes applied
- No product or test code fixes were required from this manual pass.
- Rewrote this manual-test note to reflect the fresh smoke run and the required stage structure.
## Residual risks
- None found within the scope of Phase 10.
- Phase 11 still needs to implement the create-only materialization contract defined in `DECISION.md`; that is a forward implementation dependency, not a Phase 10 manual-test gap.
@@ -0,0 +1,66 @@
# Phase 10 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Added the Phase 10 research decision in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
- Added Phase 10 verification and manual-test artifacts:
- `notes/workspace-poc/phase-10-materialization-contract-research/VERIFY.md`
- `notes/workspace-poc/phase-10-materialization-contract-research/MANUAL_TEST.md`
- Chose one concrete v0 materialization contract for `openspec apply --change <id> --repo <alias>`:
- create-only
- no overwrite
- no refresh path
- explicit repeat-apply failure for the same target repo
- minimal sidecar trace metadata in `.openspec.materialization.yaml`
- Defined the repo-local bundle shape as:
- shared context copied from workspace root: `proposal.md`, `design.md`
- target slice copied from `targets/<alias>/`: `tasks.md`, `specs/`
- no workspace coordination artifacts copied into the repo-local change
- Updated the Phase 10 checklist in `ROADMAP.md`.
## Tests or research performed
- Re-read the Phase 10 and Phase 11 blocks in `ROADMAP.md`.
- Reviewed the current workspace and apply-adjacent implementation surface in:
- `src/core/workspace/open.ts`
- `src/core/workspace/change-create.ts`
- `src/utils/change-metadata.ts`
- `src/core/artifact-graph/types.ts`
- `schemas/spec-driven/schema.yaml`
- `src/cli/index.ts`
- Re-read prior workspace POC notes and design anchors in:
- `notes/workspace-poc/phase-07-open-contract-research/DECISION.md`
- `notes/workspace-poc/phase-09-test-workspace-open/{SUMMARY.md,VERIFY.md}`
- `WORKSPACE_POC_PRD.md`
- `WORKSPACE_POC_DECISION_RECORD.md`
- Ran focused workspace regression coverage:
- `pnpm vitest run test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
- Ran a fresh copied-fixture CLI smoke against `test/fixtures/workspace-poc/happy-path` using the built CLI:
- `node dist/cli/index.js new change shared-refresh --targets app,api`
- `node dist/cli/index.js workspace open --change shared-refresh --agent claude`
- verified `repos/{app,api,docs}/openspec/changes/shared-refresh` remained absent
- Corrected one invalid manual harness attempt during this run:
- an initial smoke used `pnpm exec` from the copied temp workspace, which is not a package
- reran successfully with `node dist/cli/index.js` from the repository build output
## Results
- Focused workspace tests passed: 5 files, 19/19 tests passed.
- The current implementation boundary still holds:
- workspace changes centralize planning and target metadata
- `workspace open` remains read-only
- the user-facing handoff to `apply --change --repo` is already explicit in the open surface
- The chosen v0 contract is consistent with both the roadmap guardrails and the current implementation surface:
- create-only avoids inventing refresh semantics before they are tested
- copying shared context plus one target slice produces a usable repo-local execution bundle
- a sidecar trace file is enough for later roll-up without broadening core change metadata now
## Blockers and next-step notes
- No blockers remain for Phase 10.
- No new roadmap phases were required from this research pass.
- Phase 11 should implement exactly the create-only contract captured in `DECISION.md` and should not add refresh or overwrite behavior unless the roadmap is expanded first.
@@ -0,0 +1,57 @@
# Phase 10 Verification
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 10, cycle 1.
## Checks performed
- Re-read the Phase 10 roadmap block in `ROADMAP.md`.
- Re-read the phase artifacts under `notes/workspace-poc/phase-10-materialization-contract-research/`, with primary focus on:
- `SUMMARY.md`
- `DECISION.md`
- Re-checked the implementation boundary that Phase 10 depends on:
- `src/core/workspace/open.ts`
- `src/core/workspace/change-create.ts`
- `src/utils/change-metadata.ts`
- `src/core/artifact-graph/types.ts`
- `schemas/spec-driven/schema.yaml`
- `src/commands/workspace.ts`
- Confirmed the decision still matches the current product surface:
- workspace changes record explicit `targets`
- `workspace open` remains session-prep only
- `workspace open` still points repo-local execution to `openspec apply --change <id> --repo <alias>`
- change metadata remains narrow enough that a sidecar trace file is the least invasive Phase 11 follow-on
- Rebuilt the CLI used by the documented smoke path:
- `pnpm run build`
- Result: passed
- Re-ran the focused workspace regression slice:
- `pnpm vitest run test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
- Result: 5 files passed, 19/19 tests passed
- Re-ran a fresh copied-fixture smoke using `test/fixtures/workspace-poc/happy-path`:
- created `shared-refresh` with `new change --targets app,api`
- opened it with `workspace open --change shared-refresh --agent claude`
- confirmed only `app` and `api` were attached
- confirmed the instruction surface still says `Do not materialize repo-local changes from this session.`
- confirmed the instruction surface still says `openspec apply --change shared-refresh --repo <alias>`
- confirmed no repo-local `openspec/changes/shared-refresh` directory was created in `app`, `api`, or `docs`
- confirmed the reported `.claude/commands/opsx/workspace-open.md` instruction-surface path is not actually written during this flow
- Re-validated the Phase 10 acceptance criteria against `DECISION.md`:
- 10.4 one v0 contract is chosen and explicit non-goals are named
- 10.5 successful materialization is defined concretely
- 10.6 repeat `apply` behavior is defined explicitly
## Issues found
- No product correctness issues were found in the reviewed boundary.
- No acceptance-test gaps were found in `DECISION.md`.
- No documentation corrections were required in `SUMMARY.md`, `DECISION.md`, or `MANUAL_TEST.md`.
## Fixes applied
- Rewrote this verification note to reflect the fresh verification pass and the exact checks rerun here.
- No product or test code changes were required.
- No ROADMAP checkbox corrections were needed because the Phase 10 checklist was already accurate.
## Residual risks
- No residual risk remains within the scope of this research phase itself.
- Phase 11 still needs to implement the create-only, all-or-nothing materialization behavior described here; that is a forward implementation dependency, not a Phase 10 verification gap.
@@ -0,0 +1,56 @@
# Phase 11 Manual Test
Manual smoke re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 11, cycle 1.
## Scenarios run
- Rebuilt the CLI with `pnpm run build`.
- Re-ran the focused Phase 11 regression slice to confirm the current tree before the manual smoke:
- `pnpm vitest run test/core/workspace/apply.test.ts test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
- Created a fresh temp root and copied:
- `test/fixtures/workspace-poc/happy-path/workspace` to `<tmp>/workspace`
- `test/fixtures/workspace-poc/happy-path/repos` to `<tmp>/repos`
- Ran the real CLI from the copied workspace with telemetry disabled:
```bash
cd <tmp>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change shared-refresh --targets app,api
# seed proposal.md, design.md, and targets/{app,api}/{tasks.md,specs/**}
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo docs
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo missing
```
- Inspected the copied temp workspace and repos after the run to confirm:
- `repos/app/openspec/changes/shared-refresh/` was created
- `repos/api/openspec/changes/shared-refresh/` remained absent
- `repos/docs/openspec/changes/shared-refresh/` remained absent
- `repos/app/openspec/changes/shared-refresh/` contained `.openspec.yaml`, `proposal.md`, `design.md`, `tasks.md`, `specs/`, and `.openspec.materialization.yaml`
- `workspace/changes/shared-refresh/targets/app/tasks.md` remained present after apply
- Inspected the CLI output to confirm:
- the success path printed the repo-local destination and explicit authority handoff
- the repeat run failed with a create-only collision
- `docs` failed as an untargeted alias
- `missing` failed as an unknown alias
## Results
- `pnpm run build` passed.
- The focused Phase 11 regression slice passed: 7 files, 23/23 tests passed.
- `apply --change shared-refresh --repo app` succeeded and created the repo-local change only in `app`.
- The success output explicitly showed the handoff from workspace planning to repo-local execution.
- The same-alias repeat run failed with the expected create-only collision message.
- The untargeted `docs` run failed with the expected targeted-alias error.
- The unknown `missing` run failed with the expected unregistered-alias error.
- The workspace draft files remained in place after the successful materialization.
## Fixes applied
- No product fixes were required from this manual smoke pass.
- Updated this manual-test note to reflect the exact commands, inspections, and results from the fresh-context run.
## Residual risks
- No residual risks were found within the Phase 11 scope during this pass.
- Broader materialization matrix coverage remains Phase 12 follow-on work rather than a Phase 11 defect.
@@ -0,0 +1,68 @@
# Phase 11 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Added a real top-level `openspec apply` command that materializes one targeted workspace change into one selected repo with `--change <id> --repo <alias>`.
- Added shared workspace-change resolution in `src/core/workspace/change.ts` so `workspace open` and `apply` use the same change lookup and target metadata rules.
- Added the Phase 11 materialization engine in `src/core/workspace/apply.ts`:
- resolves the workspace root and selected repo alias
- validates unknown vs untargeted aliases distinctly
- validates required workspace source artifacts for the selected target slice
- stages a repo-local bundle under `openspec/changes/` and atomically renames it into place
- reuses the workspace change ID in the target repo
- writes `.openspec.materialization.yaml` with the minimum trace metadata from Phase 10
- keeps workspace planning artifacts untouched
- Made the authority handoff explicit in the CLI success output: workspace target slice before `apply`, repo-local execution surface after `apply`.
- Added focused Phase 11 coverage in:
- `test/core/workspace/apply.test.ts`
- `test/cli-e2e/workspace/workspace-apply-cli.test.ts`
- Updated the Phase 11 checklist in `ROADMAP.md`.
## Tests or research performed
- Re-read the Phase 11 block in `ROADMAP.md`.
- Re-read the Phase 10 contract in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
- Reviewed the current workspace implementation boundary in:
- `src/core/workspace/open.ts`
- `src/core/workspace/registry.ts`
- `src/core/workspace/change-create.ts`
- `src/utils/change-metadata.ts`
- Built the CLI:
- `pnpm run build`
- Ran the focused Phase 11 regression slice:
- `pnpm vitest run test/core/workspace/apply.test.ts test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
- Ran a fresh copied-fixture CLI smoke using `test/fixtures/workspace-poc/happy-path`:
- created `shared-refresh` with `new change --targets app,api`
- seeded the target slice files
- ran `apply --change shared-refresh --repo app`
- re-ran `apply` for the same alias to confirm create-only collision behavior
- ran `apply` for `docs` and `missing` to confirm untargeted and unknown alias failures
## Results
- `pnpm run build` passed.
- The focused workspace regression slice passed: 7 files, 23/23 tests passed.
- The new `apply` flow now satisfies the Phase 11 contract:
- repo-local materialization uses the same change ID as the workspace change
- only the selected target repo is modified
- unknown and untargeted aliases fail with distinct target-selection errors
- repeating `apply` for the same target repo fails with a create-only collision
- applying the same change to a different targeted alias still works
- workspace drafts remain intact after successful materialization
- The repo-local bundle shape matches the Phase 10 decision:
- `.openspec.yaml`
- `proposal.md`
- `design.md`
- `tasks.md`
- `specs/`
- `.openspec.materialization.yaml`
## Blockers and next-step notes
- No blockers remain for Phase 11.
- No new roadmap phases were required from this implementation pass.
- Phase 12 can now focus on expanding the materialization test matrix rather than defining or changing the contract.
@@ -0,0 +1,55 @@
# Phase 11 Verification
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 11, cycle 1.
## Checks performed
- Re-read the Phase 11 roadmap block in `ROADMAP.md`.
- Re-read the current phase artifacts:
- `notes/workspace-poc/phase-11-apply-materialization/SUMMARY.md`
- `notes/workspace-poc/phase-11-apply-materialization/MANUAL_TEST.md`
- Re-read the Phase 10 materialization contract in `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`.
- Re-checked the implementation surface added for this phase:
- `src/core/workspace/change.ts`
- `src/core/workspace/apply.ts`
- `src/commands/workflow/apply.ts`
- `src/cli/index.ts`
- `src/core/workspace/open.ts`
- `src/core/workspace/registry.ts`
- Rebuilt the CLI used by the verification and manual smoke path:
- `pnpm run build`
- Result: passed
- Re-ran the focused workspace regression slice:
- `pnpm vitest run test/core/workspace/apply.test.ts test/core/workspace/change-create.test.ts test/core/workspace/open.test.ts test/commands/workspace/open.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-open-cli.test.ts`
- Result: 7 files passed, 23/23 tests passed
- Ran a fresh copied-fixture CLI smoke outside the test harness:
- copied `test/fixtures/workspace-poc/happy-path/workspace` and `test/fixtures/workspace-poc/happy-path/repos` into a temp root
- ran `node dist/cli/index.js new change shared-refresh --targets app,api`
- seeded `proposal.md`, `design.md`, and the per-target `tasks.md` and `specs/` files
- ran `node dist/cli/index.js apply --change shared-refresh --repo app`
- re-ran the same command for `app` to confirm create-only collision behavior
- ran `apply` for `docs` and `missing` to confirm untargeted and unknown alias failures
- Verified the acceptance criteria through the focused suites and the fresh CLI smoke:
- repo-local materialization reuses the workspace change ID
- only the selected target repo gets the materialized change
- unknown and untargeted aliases fail distinctly
- same-alias repeat `apply` fails with a create-only collision while another targeted alias can still materialize
- workspace drafts remain unchanged after successful materialization
- the repo-local bundle contains `.openspec.yaml`, `proposal.md`, `design.md`, `tasks.md`, `specs/`, and `.openspec.materialization.yaml`
- the success output makes the workspace-to-repo authority handoff explicit
## Issues found
- No product correctness issues were found in the implemented materialization flow.
- No acceptance-test gaps remained after the focused verification run.
- Documentation-quality issue: the previous verification note mixed implementation work into the "Fixes applied" section instead of keeping that section scoped to verification-stage changes.
## Fixes applied
- No product code changes were required during this verification pass.
- Updated this verification note so it records the checks run in this pass and keeps the issues and fixes sections scoped to verification work.
## Residual risks
- No known residual risk remains inside the Phase 11 scope.
- Phase 12 still needs to broaden coverage around the materialization matrix, but that is follow-on validation work rather than a correctness gap in the implemented Phase 11 contract.
@@ -0,0 +1,53 @@
# Phase 12 Manual Test
Manual smoke re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 12, cycle 1, stage `manual-test`.
## Scenarios run
- Rebuilt the CLI with `pnpm run build`.
- Re-ran the focused Phase 12 regression slice before the manual smoke:
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/workflow/apply.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Scenario 1: happy-path selective materialization into one repo out of many using copied fixture repos and isolated XDG roots.
- Ran `workspace create phase-12-manual --json`.
- Registered `app`, `api`, and `docs` with `workspace add-repo ... --json`.
- Ran `new change shared-refresh --targets app,api,docs`.
- Ran `apply --change shared-refresh --repo app --json`.
- Re-ran `apply --change shared-refresh --repo app` to confirm repeat-apply collision behavior.
- Inspected the temp repo trees and the JSON payload after apply.
- Scenario 2: dirty-workspace stale alias failure using the committed dirty fixture plus a rewritten temp `local.yaml` overlay with `docs` still pointing at a missing path.
- Copied `test/fixtures/workspace-poc/dirty/workspace` and `test/fixtures/workspace-poc/dirty/repos` into a temp root.
- Rewrote `.openspec/local.yaml` to absolute temp paths for `app` and `api`, while leaving `docs` pointed at `<tmp>/repos/docs-missing`.
- Ran `new change docs-repair --targets docs`.
- Ran `apply --change docs-repair --repo docs`.
- Inspected the temp repo trees to confirm no new repo-local change was created in the healthy repos.
## Results
- `pnpm run build` passed.
- The focused Phase 12 regression slice passed: 5 files, 17/17 tests passed.
- Scenario 1 passed end to end:
- workspace creation and repo registration succeeded
- `new change shared-refresh --targets app,api,docs` succeeded
- `apply --change shared-refresh --repo app --json` succeeded
- the JSON payload reported `change.id = shared-refresh`
- `target.changePath` ended in `/shared-refresh`, so the repo-local change ID exactly matched the workspace change ID
- only `app` received `openspec/changes/shared-refresh/`
- `api` and `docs` kept only their pre-existing fixture changes and did not receive `shared-refresh`
- the materialized app change contained `.openspec.yaml`, `proposal.md`, `design.md`, `tasks.md`, `specs/`, and `.openspec.materialization.yaml`
- the repeat `app` apply exited with code `1` and surfaced the explicit create-only collision
- Scenario 2 passed for the failure path:
- `new change docs-repair --targets docs` succeeded inside the copied dirty workspace
- `apply --change docs-repair --repo docs` exited with code `1`
- the error reported `Target alias 'docs' points to a missing repo path: <tmp>/repos/docs-missing`
- the error also told the user to run `openspec workspace doctor` and repair the failing alias before retrying
- no `docs-repair` repo-local materialization appeared in `app` or `api`, so the stale-path failure did not produce silent partial success
## Fixes applied
- No product fixes were required from this manual smoke pass.
- Updated this manual-test note to capture the exact fresh-context scenarios, outputs, and repo-tree inspections from the current run.
## Residual risks
- No residual risks were found within the Phase 12 scope during this pass.
- Status roll-up and completion semantics remain future work for Phase 13 onward.
@@ -0,0 +1,62 @@
# Phase 12 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Expanded `test/core/workspace/apply.test.ts` to cover:
- missing target-slice source artifacts during materialization plan construction
- stale dirty-workspace alias resolution failures
- pre-existing target change collisions without overwrite
- Added `test/commands/workflow/apply.test.ts` to cover the direct command surface for:
- apply success output
- apply failure on stale repo resolution
- repeat-apply create-only behavior
- Expanded `test/cli-e2e/workspace/workspace-apply-cli.test.ts` to cover:
- dirty-workspace stale-alias failure through the built CLI
- a fresh `workspace create -> add-repo -> new change -> apply` flow using copied `happy-path` fixture repos
- selective materialization into only one repo out of many
- Updated the Phase 12 checklist in `ROADMAP.md`.
## Tests or research performed
- Re-read the Phase 12 roadmap block in `ROADMAP.md`.
- Reviewed the current materialization implementation and existing tests in:
- `src/core/workspace/apply.ts`
- `src/commands/workflow/apply.ts`
- `test/core/workspace/apply.test.ts`
- `test/cli-e2e/workspace/workspace-apply-cli.test.ts`
- `test/helpers/workspace-sandbox.ts`
- Built the CLI:
- `pnpm run build`
- Ran the focused Phase 12 verification slice:
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/workflow/apply.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Ran a fresh manual CLI smoke in an isolated temp root with telemetry disabled:
- `workspace create phase-12-manual --json`
- `workspace add-repo app <tmp>/repos/app --json`
- `workspace add-repo api <tmp>/repos/api --json`
- `new change shared-refresh --targets app,api`
- `apply --change shared-refresh --repo app --json`
- repeated `apply --change shared-refresh --repo app` to confirm collision behavior
## Results
- `pnpm run build` passed.
- The focused Phase 12 verification slice passed: 5 files, 17/17 tests passed.
- The expanded coverage now proves the Phase 12 acceptance surface:
- the repo-local change directory name matches the workspace change ID
- apply writes only to the selected alias
- stale-path and collision failures are explicit and do not produce silent partial success
- the `happy-path` fixture repos support the fresh create/add-repo/new-change/apply flow through the built CLI
- The manual smoke matched the automated results:
- `shared-refresh` materialized only into `app`
- `api` remained untouched
- the repeat `app` apply failed with the expected create-only collision
## Blockers and next-step notes
- No blockers remain for Phase 12.
- No new roadmap phases were required from this pass.
- Phase 13 can build status semantics on top of a materially better-tested handoff surface.
@@ -0,0 +1,57 @@
# Phase 12 Verification
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 12, cycle 1, stage `verification`.
## Checks performed
- Re-read the Phase 12 roadmap block in `ROADMAP.md`.
- Re-read the current phase artifacts to verify scope coverage and documentation quality:
- `notes/workspace-poc/phase-12-test-apply-materialization/SUMMARY.md`
- `notes/workspace-poc/phase-12-test-apply-materialization/MANUAL_TEST.md`
- Re-checked the Phase 12 implementation boundaries in:
- `src/core/workspace/apply.ts`
- `src/commands/workflow/apply.ts`
- `src/core/workspace/change-create.ts`
- `src/core/workspace/registry.ts`
- `test/helpers/workspace-assertions.ts`
- Re-checked the automated Phase 12 coverage in:
- `test/core/workspace/apply.test.ts`
- `test/commands/workflow/apply.test.ts`
- `test/cli-e2e/workspace/workspace-apply-cli.test.ts`
- `test/cli-e2e/workspace/workspace-create-cli.test.ts`
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Rebuilt the CLI used by the e2e and direct CLI paths:
- `pnpm run build`
- Result: passed
- Re-ran the focused Phase 12 regression slice:
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/workflow/apply.test.ts test/cli-e2e/workspace/workspace-apply-cli.test.ts test/cli-e2e/workspace/workspace-create-cli.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Result: 5 files passed, 17/17 tests passed
- Ran an isolated real-CLI smoke in a temp XDG root using copied `happy-path` fixture repos:
- `workspace create phase-12-verify --json`
- `workspace add-repo app <tmp>/repos/app --json`
- `workspace add-repo api <tmp>/repos/api --json`
- `new change shared-refresh --targets app,api`
- `apply --change shared-refresh --repo app --json`
- repeated `apply --change shared-refresh --repo app`
- Confirmed:
- `apply` returned `change.id = shared-refresh`
- the repo-local change directory basename was `shared-refresh`
- only `app` received `openspec/changes/shared-refresh/`
- `api` remained untouched
- repeat apply exited with code `1` and surfaced the explicit create-only collision
## Issues found
- No product correctness issues were found during this verification pass.
- No acceptance-test gaps were found in the current Phase 12 implementation or coverage.
- No documentation-quality issues were found in the phase summary or manual-test notes; both matched the current implementation and rerun results.
## Fixes applied
- No product code changes were required during this verification pass.
- Updated this verification note to capture the exact rerun scope, implementation-boundary review, and direct CLI smoke evidence.
## Residual risks
- No known residual risks remain inside the Phase 12 scope.
- Phase 13 remains the next boundary: status and completion semantics still need their own contract and implementation work.
@@ -0,0 +1,275 @@
# Phase 13 Decision
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Recommended v0 status model
Phase 14 should implement workspace-aware roll-up instead of reusing raw artifact-graph status for workspace changes.
The minimum honest v0 model is:
- overall workspace-change state: `planned`, `in-progress`, `blocked`, `soft-done`, `hard-done`
- per-target state: `planned`, `materialized`, `in-progress`, `blocked`, `complete`
- coordination state: `planned`, `in-progress`, `blocked`, `complete`
This split is necessary because the current generic `status --change` command assumes repo-local topology:
- root-level `tasks.md`
- root-level `specs/`
- artifact completion by file existence
A workspace change does not have that layout. The direct manual probe for this phase showed that running `status --change shared-refresh --json` from a workspace root reports `proposal` and `design` as done, `specs` as ready, and `tasks` as blocked because it is looking for repo-local root artifacts that do not exist in workspace topology. That output is valid for the existing command, but it is not an honest workspace roll-up.
The current implementation surface already gives the right raw signals for a custom roll-up:
- `src/core/workspace/change-create.ts` creates workspace coordination tasks at `tasks/coordination.md` and per-target draft tasks at `targets/<alias>/tasks.md`
- `src/core/workspace/apply.ts` reuses the workspace change ID in the target repo and writes `.openspec.materialization.yaml`
- `src/utils/task-progress.ts` and `src/core/list.ts` already define tracked progress in terms of checkbox counts inside `tasks.md`
The practical conclusion is:
- use task-progress counts for progress and completion
- use repo-local materialization plus trace metadata for execution provenance
- do not infer archive from repo-local task completion
## One precise derivation rule per state
### `planned`
Rule:
- A target is `planned` when it is declared in the workspace change metadata, the target repo alias resolves cleanly, and no valid repo-local materialization exists at `<resolved-repo>/openspec/changes/<change-id>/`.
- The overall workspace change is `planned` only when coordination is `planned` and every target is `planned`.
Why:
- an unmaterialized target is still using the workspace draft as its current authority
- absence of repo-local execution state is not by itself a failure
### `materialized`
Rule:
- A target is `materialized` when a valid repo-local materialization exists and its repo-local task progress is either `0/<n>` or `0/0`.
Why:
- the current repo-local `list --json` surface collapses `0/<n>` into `in-progress`
- the workspace roll-up needs one extra state to distinguish "execution surface exists" from "tracked work has started"
### `in-progress`
Rule:
- A coordination slice or target is `in-progress` when its tracked task progress is `0 < completed < total`.
- The overall workspace change is `in-progress` when it is not `blocked`, `soft-done`, or `hard-done`, and at least one target is `materialized`, `in-progress`, or `complete`, or coordination is `in-progress` or `complete`.
Why:
- task progress is the only current product signal that distinguishes "some execution happened" from "nothing started"
### `blocked`
Rule:
- A coordination slice or target is `blocked` when status cannot classify it honestly because a required workspace or repo-local inspection surface is missing or inconsistent.
- The overall workspace change is `blocked` when coordination is `blocked` or any target is `blocked`.
For v0, target-blocked conditions are:
- the target alias is declared on the workspace change but is missing from workspace repo metadata
- the target alias is missing from `.openspec/local.yaml`
- the resolved repo path is missing, not a directory, or no longer contains `openspec/`
- a same-ID repo-local change exists, but `.openspec.materialization.yaml` is missing, malformed, or does not match this workspace and target alias
- a traced repo-local change exists, but `tasks.md` cannot be read for progress derivation
For v0, coordination-blocked conditions are:
- `tasks/coordination.md` is missing or unreadable
Why:
- `blocked` should mean "the status command cannot tell the truth from the current state"
- v0 should not invent softer warning labels when the underlying surface is actually broken
### `complete`
Rule:
- A coordination slice or target is `complete` when its tracked task progress is `n/n` with `n > 0`.
Why:
- `complete` is task-complete, not archive-complete
- this keeps completion aligned with the current repo-local `list` semantics
### `soft-done`
Rule:
- The overall workspace change is `soft-done` when coordination is `complete` and every target is `complete`.
Why:
- this matches the PRD and decision-record definition of "all known coordination work and tracked target work are complete"
- it still leaves explicit top-level archive for the final lifecycle step
### `hard-done`
Rule:
- The overall workspace change is `hard-done` only when an explicit workspace-level archive/completion marker exists for that workspace change.
Why:
- repo-local archive remains repo-local
- repo-local task completion or repo-local archive alone must never imply top-level finality
## Workspace-only versus repo-local inspection
The minimum source split for v0 is:
### Uses workspace state alone
- workspace metadata and target membership
- coordination task progress from `changes/<id>/tasks/coordination.md`
- pre-materialization draft task progress from `changes/<id>/targets/<alias>/tasks.md`
- overall `hard-done` once Phase 16 adds explicit workspace archive state
### Requires repo-local inspection
- whether a target has been materialized at all
- whether the materialized change belongs to this workspace target rather than just sharing the same change ID
- repo-local execution progress and completion from `<repo>/openspec/changes/<id>/tasks.md`
- blocked states caused by stale repo paths, missing `openspec/`, or malformed materialization traces
### Mixed roll-up states
- overall `planned` depends on workspace coordination plus every target still being `planned`
- overall `in-progress` depends on both workspace coordination and any materialized target state
- overall `blocked` depends on any blocked coordination or target slice
- overall `soft-done` depends on coordination plus every target reaching `complete`
## Reverse-link decision
Decision:
- reverse links are required in v0, but the minimum required reverse link is the existing `.openspec.materialization.yaml` sidecar
What is required:
- keep reusing the workspace change ID as the repo-local change ID
- keep writing `.openspec.materialization.yaml`
- Phase 14 status should validate:
- `source: workspace`
- `workspaceName` matches the current workspace
- `targetAlias` matches the target being inspected
What is not required:
- no new backlink fields in `.openspec.yaml`
- no absolute workspace paths
- no extra workspace change ID field beyond the repo-local directory name, because Phase 11 already made the directory name match the workspace change ID
Why this is the minimum honest choice:
- without the sidecar, a same-ID repo-local change could be mistaken for a materialized workspace target even if it did not originate from this workspace flow
- with the sidecar, Phase 14 can distinguish "materialized from this workspace" from "same change name exists locally for some other reason"
## Minimum JSON shape to lock down in Phase 14
Phase 14 should keep the JSON contract small and stable:
```json
{
"change": {
"id": "shared-refresh",
"state": "planned"
},
"coordination": {
"state": "planned",
"tasks": {
"completed": 0,
"total": 2
}
},
"targets": [
{
"alias": "api",
"state": "planned",
"source": "workspace",
"tasks": {
"completed": 0,
"total": 2
},
"problems": []
},
{
"alias": "app",
"state": "materialized",
"source": "repo",
"tasks": {
"completed": 0,
"total": 2
},
"problems": []
}
]
}
```
Contract notes:
- `change.id` is the workspace change ID
- `change.state` is only `planned`, `in-progress`, `blocked`, `soft-done`, or `hard-done`
- `coordination.state` is only `planned`, `in-progress`, `blocked`, or `complete`
- target `state` is only `planned`, `materialized`, `in-progress`, `blocked`, or `complete`
- `targets` are sorted by alias for deterministic tests
- `source` is `workspace` before materialization and `repo` after materialization
- `tasks` always reflects the authority for the current `source`
- `problems` is empty unless the slice is `blocked`
- the JSON should not include spinner text, ANSI codes, or absolute repo paths
## Rejected alternatives
### Rejected: reuse raw artifact-graph `status --change` for workspace roll-up
Why rejected:
- the current command is correct for repo-local change topology, not workspace topology
- it looks for root `specs/` and root `tasks.md`, which the workspace change intentionally does not have
- it would misreport workspace state instead of clarifying it
### Rejected: treat `0/<n>` repo-local task progress as `in-progress` in workspace roll-up
Why rejected:
- that loses the important distinction between "materialized, but untouched" and "work has actually started"
- the roadmap explicitly wants both `materialized` and `in progress`
### Rejected: trust any same-ID repo-local change without a workspace trace sidecar
Why rejected:
- same-name repo-local changes are not strong enough provenance
- status would risk claiming a workspace target was materialized when it was not
### Rejected: infer `hard-done` from repo-local archive or repo-local task completion
Why rejected:
- the PRD and roadmap keep workspace archive as an explicit top-level action
- different repos can finish or archive at different times without closing the whole workspace change
## Phase 14 implications
Phase 14 should implement only this contract:
- custom workspace-aware roll-up logic
- checkbox-based task progress for coordination and target completion
- materialization provenance validated through `.openspec.materialization.yaml`
- target states distinct from overall workspace states
No new roadmap phase is required from this decision.
@@ -0,0 +1,75 @@
# Phase 13 Manual Test
Phase cycle: 1
Stage: `manual-test`
Date: 2026-04-17 (Australia/Sydney)
Manual smoke run in a fresh local context for ROADMAP Phase 13 only.
## Scenarios run
- Built the current CLI with `pnpm run build`.
- Created a fresh temp root and copied:
- `test/fixtures/workspace-poc/happy-path/workspace` to `<tmp>/workspace`
- `test/fixtures/workspace-poc/happy-path/repos` to `<tmp>/repos`
- Ran the real CLI from the copied workspace and repo roots with telemetry disabled:
```bash
cd <tmp>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change shared-refresh --targets app,api
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change shared-refresh --json
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change shared-refresh --repo app --json
cd <tmp>/repos/app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js list --json
# edit tasks to simulate partial execution
printf '%s\n' '## App Tasks' '- [x] Finish API wiring' '- [ ] Land UI follow-up' > openspec/changes/shared-refresh/tasks.md
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js list --json
# edit tasks to simulate completion
printf '%s\n' '## App Tasks' '- [x] Finish API wiring' '- [x] Land UI follow-up' > openspec/changes/shared-refresh/tasks.md
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js list --json
cat openspec/changes/shared-refresh/.openspec.materialization.yaml
```
- Inspected the raw workspace-root `status --change` JSON before apply.
- Inspected repo-local `list --json` immediately after apply, after a partial task update, and after a full task update.
- Inspected the materialization sidecar contents.
## Results
- `pnpm run build` passed.
- `new change shared-refresh --targets app,api` succeeded and created the workspace change.
- The raw workspace-root `status --change shared-refresh --json` output still reported:
- `proposal: done`
- `design: done`
- `specs: ready`
- `tasks: blocked`
- That confirmed the current generic status command is still interpreting workspace changes as if they had repo-local root `specs/` and `tasks.md`.
- `apply --change shared-refresh --repo app --json` succeeded and wrote one repo-local change under `repos/app/openspec/changes/shared-refresh`.
- Repo-local `list --json` reported `shared-refresh` as:
- `in-progress` at `0/2` immediately after apply
- `in-progress` at `1/2` after one checked task
- `complete` at `2/2` after both tasks were checked
- The fixture also still contained the unrelated baseline entry `app-ui-polish` with `status: no-tasks`; it did not affect the `shared-refresh` probe.
- The materialization sidecar contained:
- `source: workspace`
- `workspaceName: happy-path`
- `targetAlias: app`
- `materializedAt: 2026-04-17T00:44:12.632Z`
- The current product surface therefore supports the Phase 13 decision:
- task checkboxes are the real progress signal
- raw artifact-graph status is not workspace-aware
- the sidecar is the minimum reverse link needed for honest roll-up
## Fixes applied
- No product or test code fixes were required from this manual pass.
- Updated this manual-test note to reflect the fresh smoke run and explicit `manual-test` stage metadata.
## Residual risks
- None found within the scope of Phase 13.
- Phase 14 still needs to implement the actual workspace roll-up behavior defined in `DECISION.md`; that is a forward implementation dependency, not a manual-test gap.
@@ -0,0 +1,68 @@
# Phase 13 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Added the Phase 13 research decision in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
- Added Phase 13 verification and manual-test artifacts:
- `notes/workspace-poc/phase-13-status-research/VERIFY.md`
- `notes/workspace-poc/phase-13-status-research/MANUAL_TEST.md`
- Chose one concrete v0 status roll-up model for the workspace POC:
- overall workspace states: `planned`, `in-progress`, `blocked`, `soft-done`, `hard-done`
- per-target states: `planned`, `materialized`, `in-progress`, `blocked`, `complete`
- coordination states: `planned`, `in-progress`, `blocked`, `complete`
- Decided that Phase 14 must derive progress from task checkboxes plus materialization provenance instead of reusing raw artifact-graph status for workspace changes.
- Decided that reverse links are required in v0, but the existing `.openspec.materialization.yaml` sidecar is the only required backlink.
- Defined the minimum JSON status shape for Phase 14 tests to lock down.
- Updated the Phase 13 checklist in `ROADMAP.md`.
## Tests or research performed
- Re-read the Phase 13, 14, 15, and 16 roadmap blocks in `ROADMAP.md`.
- Reviewed the current implementation surfaces that define the available status signals:
- `src/commands/workflow/status.ts`
- `src/core/artifact-graph/instruction-loader.ts`
- `src/core/view.ts`
- `src/core/list.ts`
- `src/utils/task-progress.ts`
- `src/core/workspace/change-create.ts`
- `src/core/workspace/apply.ts`
- `src/utils/change-metadata.ts`
- `src/core/workspace/metadata.ts`
- Re-read the prior workspace POC anchors:
- `WORKSPACE_POC_PRD.md`
- `WORKSPACE_POC_DECISION_RECORD.md`
- `notes/workspace-poc/phase-07-open-contract-research/DECISION.md`
- `notes/workspace-poc/phase-10-materialization-contract-research/DECISION.md`
- Ran focused automated validation:
- `pnpm run build`
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/artifact-workflow.test.ts test/core/artifact-graph/instruction-loader.test.ts`
- Ran a fresh copied-fixture manual probe against `test/fixtures/workspace-poc/happy-path` with the built CLI:
- created `shared-refresh` in the copied workspace
- ran `status --change shared-refresh --json` from the workspace root before apply
- ran `apply --change shared-refresh --repo app --json`
- ran `list --json` in the copied `app` repo immediately after apply, after `1/2` tasks, and after `2/2` tasks
- inspected `.openspec.materialization.yaml`
## Results
- The generic artifact-graph `status --change` command is not an honest workspace-status implementation because it inspects repo-local root artifact paths that workspace changes do not have.
- The current codebase already exposes the minimum signals needed for Phase 14:
- workspace coordination progress through `tasks/coordination.md`
- target draft progress through `targets/<alias>/tasks.md`
- repo-local execution progress through `openspec/changes/<id>/tasks.md`
- materialization provenance through `.openspec.materialization.yaml`
- The manual probe confirmed the key semantic gap Phase 14 must close:
- immediately after `apply`, repo-local `list --json` reports `shared-refresh` as `in-progress` at `0/2`
- Phase 14 therefore needs a distinct workspace-level `materialized` state for `0/<n>` or `0/0` repo-local task progress
- The existing materialization sidecar is sufficient to act as the required v0 reverse link without expanding `.openspec.yaml`.
- The note now defines one precise derivation rule per requested state, clearly separates workspace-only versus repo-local inspection, and resolves the reverse-link question.
## Blockers and next-step notes
- No blockers remain for Phase 13.
- No new bounded follow-up phase was required from this research pass.
- Phase 14 should implement only the custom roll-up and JSON shape described in `DECISION.md`.
@@ -0,0 +1,55 @@
# Phase 13 Verification
Independent verification re-run in a fresh local context on 2026-04-17 (Australia/Sydney) for ROADMAP Phase 13, cycle 1.
## Checks performed
- Re-read the Phase 13 roadmap block in `ROADMAP.md`.
- Re-read the phase artifacts under `notes/workspace-poc/phase-13-status-research/`, with focus on `SUMMARY.md` and `DECISION.md`.
- Re-checked the implementation boundary the research note depends on:
- `src/commands/workflow/status.ts`
- `src/core/artifact-graph/instruction-loader.ts`
- `src/core/list.ts`
- `src/utils/task-progress.ts`
- `src/core/workspace/change-create.ts`
- `src/core/workspace/apply.ts`
- Confirmed the note still matches the current product surface:
- workspace changes still scaffold coordination work at `tasks/coordination.md`
- workspace changes still scaffold per-target draft work at `targets/<alias>/tasks.md`
- `apply` still reuses the workspace change ID and writes `.openspec.materialization.yaml`
- repo-local progress is still derived from `tasks.md` checkbox counts
- generic `status --change` is still artifact-graph status, not a workspace-aware roll-up
- Rebuilt the CLI:
- `pnpm run build`
- Result: passed
- Re-ran the focused regression slice for the signals this phase depends on:
- `pnpm vitest run test/core/workspace/apply.test.ts test/commands/artifact-workflow.test.ts test/core/artifact-graph/instruction-loader.test.ts`
- Result: 3 files passed, 100/100 tests passed
- Re-ran one fresh temp-fixture CLI probe using `test/fixtures/workspace-poc/happy-path`:
- created `shared-refresh` in the copied workspace
- confirmed workspace-root `status --change shared-refresh --json` still reported `proposal: done`, `design: done`, `specs: ready`, and `tasks: blocked`
- materialized `shared-refresh` into the copied `app` repo with `apply --change shared-refresh --repo app --json`
- confirmed repo-local `list --json` reported `shared-refresh` as `in-progress` at `0/2`, `in-progress` at `1/2`, and `complete` at `2/2`
- confirmed `.openspec.materialization.yaml` still carried `source: workspace`, `workspaceName: happy-path`, and `targetAlias: app`
- Re-validated the Phase 13 acceptance criteria against `DECISION.md`:
- 13.5 one precise derivation rule is present for `planned`, `materialized`, `in-progress`, `blocked`, `complete`, `soft-done`, and `hard-done`
- 13.6 the note explicitly separates workspace-only inspection from repo-local inspection
- 13.7 the note resolves reverse links as required in v0, using the existing sidecar as the minimum backlink
- Confirmed the Phase 13 checklist in `ROADMAP.md` already matched the verified state, so no checkbox changes were required in this pass.
## Issues found
- No product correctness issues were found in the reviewed boundary.
- No acceptance-test gaps were found in `DECISION.md`.
- No documentation-quality issues were found in the phase artifacts.
## Fixes applied
- Updated this verification note to reflect the exact fresh-context checks run in this pass.
- No product, roadmap, or test changes were required.
- No additional roadmap phases were needed.
## Residual risks
- No residual risks were found within the scope of this research phase.
- Phase 14 still needs to implement the custom roll-up described here; that is a forward implementation dependency, not a Phase 13 verification gap.
@@ -0,0 +1,63 @@
# Phase 14 Manual Test
Phase cycle: 1
Stage: `manual-test`
Date: 2026-04-17 (Australia/Sydney)
Manual smoke re-run in a fresh local context for ROADMAP Phase 14 using copied workspace fixtures and the built CLI.
## Scenarios run
- Rebuilt the CLI with `pnpm run build`.
- Copied `test/fixtures/workspace-poc/happy-path/workspace` and `test/fixtures/workspace-poc/happy-path/repos` into a fresh temp root and created repo-local `openspec/changes/` roots for `app`, `api`, and `docs`.
- Ran the real CLI from the copied happy-path workspace with telemetry disabled:
```bash
cd <tmp>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-status --targets app,api
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-status --json
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-status --repo app --json
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-status --json
# mark workspace coordination tasks complete
# mark repos/app/openspec/changes/manual-status/tasks.md complete
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-status --repo api --json
# mark repos/api/openspec/changes/manual-status/tasks.md complete
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-status --json
```
- Validated each raw `status --change <id> --json` output parsed cleanly and contained no ANSI escapes or spinner glyphs.
- Copied `test/fixtures/workspace-poc/dirty/workspace` and `test/fixtures/workspace-poc/dirty/repos` into a second fresh temp root and created repo-local `openspec/changes/` roots for `app` and `api`.
- Ran the real CLI from the copied dirty workspace:
```bash
cd <dirty-tmp>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change docs-repair --targets docs
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change docs-repair --json
```
- Validated the dirty-fixture raw `status --change docs-repair --json` output parsed cleanly and contained no ANSI escapes or spinner glyphs.
## Results
- `pnpm run build` passed.
- In the happy-path smoke:
- the first status output showed `change.state: "planned"` with both `api` and `app` as `planned` via `workspace`
- after `apply --repo app`, status showed `change.state: "in-progress"` with `app: materialized via repo` and `api: planned via workspace`
- after completing coordination plus both repo-local task files, status showed `change.state: "soft-done"` with both targets `complete via repo`
- `hard-done` never appeared during the run
- In the dirty-workspace smoke:
- status showed `change.state: "blocked"`
- the `docs` target reported `blocked via workspace`
- the problem text was `repo alias 'docs' points to a missing repo path`
- All status outputs were valid JSON with no spinner contamination.
- No Phase 14 behavior drift was found between the implementation summary, verification notes, and this manual smoke re-run.
## Fixes applied
- No product fixes were required from this manual smoke pass.
- No manual-test-only fixes were needed beyond updating this artifact with the exact scenarios and observed assertions from the fresh run.
## Residual risks
- No additional Phase 14 residual risks were found in this manual smoke pass.
- Explicit workspace archive and `hard-done` remain deferred to Phase 16 by design.
@@ -0,0 +1,68 @@
# Phase 14 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Added workspace-aware status roll-up in `src/core/workspace/status.ts`.
- Extended `src/commands/workflow/status.ts` so `openspec status --change <id>` detects targeted workspace changes and uses the workspace roll-up instead of the repo-local artifact graph.
- Implemented the Phase 14 state model:
- overall workspace change: `planned`, `in-progress`, `blocked`, `soft-done`, `hard-done`
- coordination: `planned`, `in-progress`, `blocked`, `complete`
- targets: `planned`, `materialized`, `in-progress`, `blocked`, `complete`
- Rolled coordination state from `tasks/coordination.md`.
- Rolled target state from workspace draft tasks before materialization and from repo-local `tasks.md` after validating `.openspec.materialization.yaml`.
- Kept JSON output small and stable:
- `change.id`
- `change.state`
- `coordination.state`
- `coordination.tasks`
- `coordination.problems`
- sorted `targets[]` with `alias`, `state`, `source`, `tasks`, and `problems`
- Kept blocked output honest by reporting missing local overlay entries, stale repo paths, missing repo-local OpenSpec state, invalid materialization traces, and unreadable task files instead of inferring progress.
- Added focused Phase 14 coverage in:
- `test/core/workspace/status.test.ts`
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Updated the Phase 14 checklist in `ROADMAP.md`.
## Tests or research performed
- Re-read the Phase 14 roadmap block in `ROADMAP.md`.
- Re-read the Phase 13 decision in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
- Re-reviewed the current workspace implementation surface:
- `src/core/workspace/change-create.ts`
- `src/core/workspace/apply.ts`
- `src/core/workspace/registry.ts`
- `src/utils/task-progress.ts`
- Built the CLI:
- `pnpm run build`
- Ran the repository test suite after the implementation landed:
- `pnpm test -- test/core/workspace/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Result: Vitest ran the full suite; 87 files passed, 1453/1453 tests passed
- Ran the focused Phase 14 verification slice in a fresh process:
- `pnpm exec vitest run test/core/workspace/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Ran a fresh copied-fixture CLI smoke outside Vitest:
- happy-path fixture: created `manual-status`, checked `planned`, materialized `app`, then completed coordination plus both repo-local task files to confirm `soft-done`
- dirty fixture: created `docs-repair` and confirmed blocked status for the stale `docs` repo path
## Results
- `pnpm run build` passed.
- The full Vitest suite passed: 87 files, 1453/1453 tests.
- The focused Phase 14 verification slice passed: 2 files, 6/6 tests.
- The workspace status contract now behaves as intended:
- planning-only targets stay `planned` with `source: "workspace"`
- valid repo-local materializations show `materialized` at `0/n` or `0/0`
- partial repo-local progress shows `in-progress`
- stale repo paths and invalid materialization traces show `blocked`
- `soft-done` appears only after coordination and every target are task-complete
- `hard-done` is not inferred and remained absent in the manual smoke
- The JSON output stayed machine-readable with no spinner contamination or ANSI escape sequences.
## Blockers and next-step notes
- No blockers remain for Phase 14.
- No new roadmap phases were required from this implementation pass.
- Phase 15 can expand the status validation matrix, but the Phase 14 build contract is now implemented and passing.
@@ -0,0 +1,49 @@
# Phase 14 Verification
Phase cycle: 1
Stage: `verification`
Date: 2026-04-17 (Australia/Sydney)
Independent verification re-run in a fresh local context for ROADMAP Phase 14.
## Checks performed
- Re-read the Phase 14 roadmap block in `ROADMAP.md`.
- Re-read the current implementation summary in `notes/workspace-poc/phase-14-workspace-status/SUMMARY.md`.
- Re-read the Phase 13 status decision in `notes/workspace-poc/phase-13-status-research/DECISION.md`.
- Re-inspected the Phase 14 implementation surface:
- `src/core/workspace/status.ts`
- `src/commands/workflow/status.ts`
- `src/core/workspace/apply.ts`
- `src/core/workspace/metadata.ts`
- `src/utils/task-progress.ts`
- Re-inspected the focused Phase 14 automated coverage:
- `test/core/workspace/status.test.ts`
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Rebuilt the CLI:
- `pnpm run build`
- Result: passed
- Re-ran the focused Phase 14 regression slice in a fresh process:
- `pnpm exec vitest run test/core/workspace/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Result: 2 files passed, 6/6 tests passed
- Re-ran a direct CLI smoke on copied happy-path and dirty workspace fixtures outside Vitest:
- created `manual-status`, confirmed initial `planned`
- materialized `app`, confirmed mixed `in-progress` with `app: materialized` and `api: planned`
- completed coordination plus both repo-local task files, confirmed `soft-done`
- created `docs-repair` in the dirty fixture, confirmed overall `blocked` plus `repo alias 'docs' points to a missing repo path`
- confirmed every `status --change <id> --json` response stayed parseable and wrote no spinner text or ANSI escapes
- Re-reviewed `SUMMARY.md` and `MANUAL_TEST.md` for consistency with the implementation and the re-run checks.
## Issues found
- No Phase 14 product correctness issues were found.
- No acceptance-test failures or documentation contradictions were found.
## Fixes applied
- No product code changes were required during this verification pass.
- Updated this verification record to reflect the fresh-context checks completed in this stage.
## Residual risks
- No additional Phase 14 residual risks were found beyond the intentional deferral of explicit workspace archive and `hard-done` behavior to Phase 16.
@@ -0,0 +1,63 @@
# Phase 15 Manual Test
Phase cycle: 1
Stage: `manual-test`
Date: 2026-04-17 (Australia/Sydney)
Fresh manual smoke run in a copied local fixture context for ROADMAP Phase 15 using the built CLI.
## Scenarios run
- Rebuilt the CLI with `pnpm run build`.
- Copied `test/fixtures/workspace-poc/happy-path/workspace` and `test/fixtures/workspace-poc/happy-path/repos` into a fresh temp root, added an `ops` repo, and updated `.openspec/workspace.yaml` plus `.openspec/local.yaml` so `ops` participated as a fourth target.
- Ran the real CLI from the copied happy-path workspace:
```bash
cd <tmp>/happy-workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-phase15 --targets app,api,docs,ops
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase15 --repo app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase15 --repo api
cd <tmp>/happy-repos/app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase15 --yes --skip-specs --no-validate
rm -rf <tmp>/happy-repos/docs
cd <tmp>/happy-workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase15 --json
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase15
```
- Copied `test/fixtures/workspace-poc/dirty/workspace` and `test/fixtures/workspace-poc/dirty/repos` into a second fresh temp root, keeping the fixture’s stale `docs` path, and ran:
```bash
cd <tmp>/dirty-workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-resume --targets app,api,docs
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-resume --repo app
# mark repos/app/openspec/changes/manual-resume/tasks.md as 1/2 complete
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-resume --json
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-resume
```
- Validated each raw `status --change <id> --json` output parsed cleanly and contained no ANSI escapes, spinner glyphs, or `Loading change status...`.
## Results
- `pnpm run build` passed.
- In the happy-path smoke:
- text and JSON status both showed `api: materialized`, `app: archived`, `docs: blocked`, and `ops: planned`
- the text output rendered the archived target as `- app: archived via repo (0/2 tasks)`, which matches the current command and e2e expectations
- the text output remained readable and listed the stale `docs` problem inline
- the JSON output remained machine-parseable
- In the dirty-fixture smoke:
- text and JSON status both showed `app: in-progress`, `api: planned`, and `docs: blocked`
- overall change state remained `blocked`, which is the honest roll-up while the stale repo path is unresolved
- the JSON output remained machine-parseable
## Fixes applied
- This manual smoke reconfirmed the Phase 15 product fix: archived repo-local targets are surfaced as `archived` instead of being misreported as `planned`.
- No product code changes were required during this manual-test pass.
- Refreshed this note to record the currently observed archived text rendering and the fresh-context smoke coverage completed in this pass.
## Residual risks
- No additional Phase 15 residual risks were found in this manual smoke pass.
- Explicit workspace archive/completion and `hard-done` remain deferred to Phase 16 by design.
@@ -0,0 +1,57 @@
# Phase 15 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Fixed `src/core/workspace/status.ts` so a repo-local change archived under `openspec/changes/archive/` is reported as `archived` instead of silently falling back to `planned`.
- Exported the pure state-derivation helpers from `src/core/workspace/status.ts` and tightened the `soft-done` roll-up so archived targets only count once their archived task file is actually complete.
- Added Phase 15 coverage in:
- `test/core/workspace/status.test.ts`
- `test/commands/workflow/status.test.ts`
- `test/cli-e2e/workspace/workspace-status-cli.test.ts`
- Kept `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts` in the focused slice to preserve the existing planned-only workspace status contract.
- Created the missing Phase 15 notes and updated the Phase 15 checklist in `ROADMAP.md`.
## Tests or research performed
- Re-read the Phase 15 roadmap block in `ROADMAP.md`.
- Confirmed the Phase 15 notes were missing on disk before implementation.
- Re-inspected the current workspace status implementation and existing coverage:
- `src/core/workspace/status.ts`
- `src/commands/workflow/status.ts`
- `test/core/workspace/status.test.ts`
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Built the CLI:
- `pnpm run build`
- Ran the focused Phase 15 automated slice:
- `pnpm exec vitest run test/core/workspace/status.test.ts test/commands/workflow/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-status-cli.test.ts`
- Re-ran the same focused slice in a fresh process after the first pass.
- Ran `git diff --check`.
- Ran a direct built-CLI smoke on copied fixtures outside Vitest:
- happy-path workspace plus an added `ops` repo to validate `planned`, `materialized`, `archived`, and `blocked` targets in one workspace
- dirty fixture to validate interruption/resume with `app: in-progress`, `api: planned`, and `docs: blocked`
## Results
- `pnpm run build` passed.
- The focused Phase 15 slice passed twice in fresh Vitest processes: 4 files, 13/13 tests.
- `git diff --check` passed.
- The happy-path CLI smoke showed the intended mixed state matrix:
- `api: materialized`
- `app: archived`
- `docs: blocked`
- `ops: planned`
- The dirty-fixture CLI smoke showed the intended interruption/resume state:
- `app: in-progress`
- `api: planned`
- `docs: blocked`
- All `status --change <id> --json` outputs stayed parseable and free of ANSI/spinner contamination.
## Blockers and next-step notes
- No blockers remain for Phase 15.
- No new roadmap phases were required from this implementation pass.
- Phase 16 can build explicit workspace completion and `hard-done` behavior on top of the now-tested `planned/materialized/in-progress/archived/blocked/complete` target surface.
@@ -0,0 +1,66 @@
# Phase 15 Verification
Phase cycle: 1
Stage: `verification`
Date: 2026-04-17 (Australia/Sydney)
Independent verification re-run in a fresh local context for ROADMAP Phase 15.
## Checks performed
- Re-read the Phase 15 roadmap block in `ROADMAP.md`.
- Re-read the implementation summary in `notes/workspace-poc/phase-15-test-workspace-status/SUMMARY.md`.
- Re-read the current manual smoke record in `notes/workspace-poc/phase-15-test-workspace-status/MANUAL_TEST.md`.
- Re-inspected the implementation boundary for Phase 15:
- `src/core/workspace/status.ts`
- `src/commands/workflow/status.ts`
- `test/core/workspace/status.test.ts`
- `test/commands/workflow/status.test.ts`
- `test/cli-e2e/workspace/workspace-status-cli.test.ts`
- `test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts`
- Confirmed the boundary stays within Phase 15 scope:
- workspace status derivation and rendering live under the workspace status surface
- no explicit workspace completion or archive state was introduced ahead of Phase 16
- `hasExplicitWorkspaceCompletion()` remains a deliberate Phase 16 stub returning `false`
- Rebuilt the CLI:
- `pnpm run build`
- Result: passed
- Re-ran the focused Phase 15 regression slice in a fresh process:
- `pnpm exec vitest run test/core/workspace/status.test.ts test/commands/workflow/status.test.ts test/cli-e2e/workspace/workspace-targeted-change-create-cli.test.ts test/cli-e2e/workspace/workspace-status-cli.test.ts`
- Result: 4 files passed, 13/13 tests passed
- Ran `git diff --check`.
- Result: passed
- Reproduced the mixed-state scenario with the built CLI on copied fixtures outside Vitest:
- added an `ops` repo to the happy-path workspace
- created and materialized `manual-phase15`
- archived the repo-local `app` change
- removed the `docs` repo root to force a stale alias
- verified status reported `api: materialized`, `app: archived`, `docs: blocked`, and `ops: planned`
- Reproduced the interruption/resume scenario with the built CLI on copied dirty fixtures outside Vitest:
- created and materialized `manual-resume` for `app`
- marked the repo-local app tasks as 1/2 complete
- verified status reported `app: in-progress`, `api: planned`, and `docs: blocked`
- Performed a raw JSON cleanliness check outside Vitest for both scenarios:
- captured `status --change <id> --json` output directly from the built CLI
- parsed the raw output with `JSON.parse(...)`
- checked that the raw output contained no ANSI escapes, spinner glyphs, or `Loading change status...`
- Reviewed Phase 15 documentation quality:
- `SUMMARY.md`, `VERIFY.md`, and `MANUAL_TEST.md` all match the observed behavior
- the notes clearly distinguish automated coverage from direct CLI smoke coverage
- the notes do not claim Phase 16 completion semantics are already implemented
## Issues found
- No Phase 15 product correctness issues were found.
- No acceptance-test gap was found in the current Phase 15 test slice and direct CLI smoke.
- No documentation mismatch was found between the phase artifacts and the current implementation.
## Fixes applied
- No product code changes were required during this verification pass.
- Refreshed this verification note to record the fresh-context checks completed in this pass, including implementation-boundary review and raw JSON cleanliness checks.
## Residual risks
- No additional Phase 15 residual risks were found.
- Explicit workspace completion/archive semantics and `hard-done` remain intentionally deferred to Phase 16.
@@ -0,0 +1,71 @@
# Phase 16 Manual Test
Phase cycle: 1
Stage: `manual-test`
Date: 2026-04-17 (Australia/Sydney)
Fresh manual smoke run in copied local fixture contexts for ROADMAP Phase 16 using the built CLI.
## Scenarios run
- Rebuilt the CLI with `pnpm run build`.
- Scenario 1: early top-level workspace archive rejection in a fresh copied fixture:
```bash
cd <tmp-1>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-phase16-early --targets app,api
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase16-early --repo app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase16-early --workspace
```
- Scenario 2: repo-local archive first, then explicit workspace archive, in a second fresh copied fixture:
```bash
cd <tmp-2>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js new change manual-phase16 --targets app,api
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase16 --repo app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js apply --change manual-phase16 --repo api
# mark workspace coordination plus both repo-local task files as 2/2 complete
cd <tmp-2>/repos/app
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase16 --yes --skip-specs --no-validate
cd <tmp-2>/workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16 --json
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js archive manual-phase16 --workspace
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16 --json
OPEN_SPEC_TELEMETRY_DISABLED=1 node /Users/tabishbidiwale/fission/repos/openspec/dist/cli/index.js status --change manual-phase16
```
- Parsed the raw JSON status output before and after the explicit workspace archive.
- Inspected the copied workspace metadata and repo-local archive directories on disk after Scenario 2.
## Results
- `pnpm run build` passed.
- Scenario 1 behaved as required for `16.6`:
- `openspec archive manual-phase16-early --workspace` exited non-zero
- the CLI reported `Workspace change 'manual-phase16-early' is 'in-progress'. Reach 'soft-done' before running 'openspec archive manual-phase16-early --workspace'.`
- workspace hard-done was not implied or backfilled
- Scenario 2 behaved as required for `16.5`, `16.7`, and `16.8`:
- before the explicit workspace archive, JSON status parsed cleanly and overall state was `soft-done`
- before the explicit workspace archive, targets rendered as `api: complete` and `app: archived`
- before the explicit workspace archive, `workspace/changes/manual-phase16/.openspec.yaml` did not contain `workspaceArchivedAt`
- after `openspec archive manual-phase16 --workspace`, JSON status parsed cleanly and overall state became `hard-done`
- after the explicit workspace archive, target states stayed `api: complete` and `app: archived`
- after the explicit workspace archive, `workspace/changes/manual-phase16/.openspec.yaml` contained `workspaceArchivedAt`
- The filesystem boundaries stayed correct in Scenario 2:
- the workspace change still existed under `workspace/changes/manual-phase16/`
- the repo-local active `app` change no longer existed under `repos/app/openspec/changes/manual-phase16/`
- the repo-local archived copy existed under `repos/app/openspec/changes/archive/2026-04-17-manual-phase16/`
## Fixes applied
- No product code changes were required during this manual-test pass.
- Refreshed this note to capture both observed manual paths:
- early `--workspace` archive rejection
- repo-local archive first, explicit workspace archive second
## Residual risks
- No additional Phase 16 residual risks were found in this manual smoke.
- The broader command and CLI coverage expansion remains Phase 17 work.
@@ -0,0 +1,66 @@
# Phase 16 Summary
Phase cycle: 1
Stage: `implementation`
Date: 2026-04-17 (Australia/Sydney)
## Changes made
- Added the lean explicit workspace completion path on the existing archive surface: `openspec archive <id> --workspace`.
- Implemented workspace archive handling in `src/core/workspace/archive.ts` and routed `src/core/archive.ts` to it only when `--workspace` is present, leaving repo-local archive behavior unchanged by default.
- Recorded explicit workspace-level hard-done state in workspace change metadata via a new optional `workspaceArchivedAt` field on `.openspec.yaml`.
- Updated `src/core/workspace/status.ts` so `hard-done` is derived only from that explicit workspace archive marker.
- Kept repo-local archive semantics repo-local:
- repo-local archive still moves only the repo-local change under `openspec/changes/archive/`
- workspace archive does not move repo-local changes or touch canonical repo-local specs
- Added focused Phase 16 coverage in `test/core/workspace/archive.test.ts`.
- Extended `test/utils/change-metadata.test.ts` so the new workspace archive marker is parsed and persisted correctly.
- Re-ran the existing repo-local archive and workspace status regression coverage to prove the new path did not collapse the repo/local boundary.
- Created the missing Phase 16 notes and updated the Phase 16 checklist in `ROADMAP.md`.
## Tests or research performed
- Re-read the Phase 16 roadmap block in `ROADMAP.md`.
- Confirmed the Phase 16 phase artifacts were missing on disk before implementation.
- Re-read the Phase 13 decision and the Phase 15 status/archive notes to preserve the documented `soft-done` versus explicit `hard-done` boundary.
- Re-inspected the touched implementation boundary:
- `src/core/archive.ts`
- `src/core/workspace/status.ts`
- `src/utils/change-metadata.ts`
- `src/core/artifact-graph/types.ts`
- Built the CLI:
- `pnpm run build`
- Ran the focused Phase 16 automated slice:
- `pnpm exec vitest run test/core/archive.test.ts test/core/workspace/status.test.ts test/core/workspace/archive.test.ts test/utils/change-metadata.test.ts`
- Ran `git diff --check`.
- Ran a direct built-CLI smoke on copied `happy-path` fixtures outside Vitest:
- created `manual-phase16` for `app,api`
- materialized both targets
- completed coordination plus both repo-local task files
- archived the repo-local `app` change
- confirmed workspace status was still `soft-done`
- ran `openspec archive manual-phase16 --workspace`
- confirmed workspace status became `hard-done` and `.openspec.yaml` gained `workspaceArchivedAt`
## Results
- `pnpm run build` passed.
- The focused Phase 16 automated slice passed: 4 files, 57/57 tests.
- `git diff --check` passed.
- Repo-local archive no longer risks implying workspace completion:
- before the explicit workspace archive, status reported `soft-done`
- after `archive --workspace`, status reported `hard-done`
- The direct CLI smoke confirmed the intended separation of concerns:
- `app` remained archived only in `repos/app/openspec/changes/archive/...`
- the workspace change remained present at `workspace/changes/manual-phase16/`
- the workspace metadata, not repo-local archive activity, became the source of truth for `hard-done`
- Mixed repo cadences remained valid:
- `api` stayed `complete`
- `app` stayed `archived`
- the overall workspace still transitioned cleanly from `soft-done` to `hard-done`
## Blockers and next-step notes
- No blockers remain for Phase 16.
- No new roadmap phases were required from this implementation pass.
- Phase 17 can now expand the command/CLI regression matrix around this shipped `--workspace` hard-done path.
@@ -0,0 +1,65 @@
# Phase 16 Verification
Phase cycle: 1
Stage: `verification`
Date: 2026-04-17 (Australia/Sydney)
Fresh verification pass for ROADMAP Phase 16 in a clean context after the implementation landed.
## Checks performed
- Re-read the Phase 16 roadmap block in `ROADMAP.md`.
- Re-read the current Phase 16 implementation summary in `notes/workspace-poc/phase-16-workspace-archive/SUMMARY.md`.
- Re-read `notes/workspace-poc/phase-16-workspace-archive/MANUAL_TEST.md` and checked that its documented user path still matches the implementation and current observed behavior.
- Re-inspected the implementation boundary:
- `src/core/archive.ts`
- `src/core/workspace/archive.ts`
- `src/core/workspace/status.ts`
- `src/core/artifact-graph/types.ts`
- `test/core/archive.test.ts`
- `test/core/workspace/archive.test.ts`
- `test/core/workspace/status.test.ts`
- `test/utils/change-metadata.test.ts`
- Confirmed the Phase 16 boundary stays lean:
- the existing top-level `archive` surface is reused
- repo-local archive behavior still runs unless `--workspace` is passed
- workspace hard-done is represented only by workspace metadata
- repo-local canonical spec/archive ownership is untouched
- Rebuilt the CLI:
- `pnpm run build`
- Result: passed
- Re-ran the focused verification slice:
- `pnpm exec vitest run test/core/archive.test.ts test/core/workspace/status.test.ts test/core/workspace/archive.test.ts test/utils/change-metadata.test.ts`
- Result: 4 files passed, 57/57 tests passed
- Ran `git diff --check`.
- Result: passed
- Reproduced the full user-visible Phase 16 path with the built CLI on copied happy-path fixtures in a fresh temp root:
- created and materialized `manual-phase16` for `app,api`
- completed coordination and both repo-local task files
- archived only the repo-local `app` change
- confirmed `status --change manual-phase16 --json` still parsed and reported `soft-done`
- ran `archive manual-phase16 --workspace`
- confirmed `status --change manual-phase16 --json` then parsed and reported `hard-done`
- confirmed the workspace change directory remained active while the repo-local archive stayed under `repos/app/openspec/changes/archive/`
- Mapped the acceptance tests back to the implementation and checks above:
- `16.5` verified by `test/core/workspace/archive.test.ts` and the fresh CLI smoke showing repo-local archive leaves the workspace change active
- `16.6` verified by `test/core/workspace/archive.test.ts` rejecting early workspace archive and by the CLI smoke requiring explicit `--workspace`
- `16.7` verified by `test/core/archive.test.ts`, `src/core/archive.ts`, and the CLI smoke showing repo-local archive still operates inside repo-local `openspec/changes/archive/`
- `16.8` verified by `test/core/workspace/status.test.ts` and the CLI smoke showing `api: complete` plus `app: archived` still rolls up cleanly from `soft-done` to `hard-done`
## Issues found
- No Phase 16 product correctness issues were found.
- No regression was found in repo-local archive behavior.
- No acceptance-test gap was found in the focused automated slice plus the direct CLI smoke.
- No documentation drift was found between `SUMMARY.md`, `MANUAL_TEST.md`, and the verified implementation behavior.
## Fixes applied
- No additional product code changes were required during this verification pass.
- Refreshed this verification note to capture the completed fresh checks, including the direct CLI confirmation of `soft-done` before explicit workspace archive and `hard-done` after it.
## Residual risks
- No additional Phase 16 residual risks were found.
- Broader command and CLI matrix expansion remains Phase 17 work, but the shipped Phase 16 build contract is implemented and behaving as intended.

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