Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
195 KiB
@fission-ai/openspec
1.14.0
Minor Changes
-
#883
c879d13Thanks @Code-Studio-Team! - Add Code Studio as aninitandupdatetarget, with project skills and.prompt.mdcommands under.codestudio/. -
#1672
297092cThanks @DarkskyX15! - - DeepSeek Harness —openspec init --tools dsh(command-line iddsh) installs the OpenSpec workflow skills into.dsh/skills/for DeepSeek Harness. It is skills-only (no command adapter or command files): dsh discovers the generatedSKILL.mdfiles as its highest-priority project root and surfaces them through its skill catalog,skilltool, and/openspec-*user invocations. -
#1961
3c3e6e3Thanks @fresh-fx59! - Add GigaCode as a supported--toolstarget, with skills in.gigacode/skills/openspec-*/SKILL.mdand Markdown commands in.gigacode/commands/opsx-<id>.md. -
#1211
3de7c72Thanks @hu-qi! - Add AtomCode support throughopenspec init --tools atomcode, with project skills in.atomcode/skills/and/opsx-<id>commands in.atomcode/commands/. Generated commands declareargs: optionaland receive$ARGUMENTSwhen the workflow reads invocation input, andargs: nonewhen it does not, so AtomCode runs them straight from the slash menu. Follows the selected workflow profile and delivery mode. -
#1082
a7f08b8Thanks @Storm-Chaser! - ### New Features- GSD support: Install OpenSpec workflows as project skills with
openspec init --tools gsd.
- GSD support: Install OpenSpec workflows as project skills with
-
#420
070de01Thanks @jeanduplessis! - ### New Features- Amp support: select
ampduring init to install OpenSpec workflows as project skills under.agents/skills/.
- Amp support: select
-
#2001
56528eaThanks @clay-good! - ### New Features- Version reports — Run
openspec versionto inspect the installed version and install type, or add--checkand--jsonfor structured update information that tools can consume.
- Version reports — Run
-
#1352
d1642cbThanks @redknox! - Add EasyCode support to init and update, with project-local skills and TOML commands invoked as/opsx:<id>. -
#399
ded99e2Thanks @ZEDce! - Addopenspec list --archivedand--allto browse archived changes, including JSON output and sorting. Show archived changes separately in theopenspec viewdashboard. -
#848
5a360c2Thanks @Columpio! - ### New Features- Veai support: select
veaiduring init to install OpenSpec workflows as project skills under.veai/skills/.
- Veai support: select
-
#1439
f197804Thanks @jmuchovej! - Expose OpenSpec as a reusable Nix overlay throughoverlays.default. -
#1349
e232080Thanks @0x6d6e647a! - Add Grok Build as a skills-only tool. Runopenspec init --tools grokto install skills in.grok/skills, then invoke them with/openspec-proposeand other skill names. Existing Grok installations are refreshed byopenspec update. -
#1738
781c7f9Thanks @clay-good! - Add Warp support through project-local skills. Selectwarpduring init to install OpenSpec workflows in.warp/skills, invoke them with/openspec-*, and refresh them withopenspec update. Skills remain available in every delivery mode. -
#807
c21d897Thanks @Million-mo! - ### New Features- Dashboard workflow status:
openspec viewnow shows each active change's schema and which artifacts are done, ready, blocked, or skipped. Task progress remains visible if a workflow cannot be loaded. Thanks to @Million-mo for the original contribution in #807.
- Dashboard workflow status:
Patch Changes
-
#1977
7728194Thanks @clay-good! - Theopenspec-archive-changeskill no longer tells the agent to run theopenspec-sync-specsskill when that skill is not installed. It merges the delta specs into the main specs itself instead, as the/opsx:archivecommand already did (#1975). -
#1722
817cdb6Thanks @caseyg! - ### Bug Fixes- IBM Bob now appears by its full product name in the tool picker and success messages. Existing
bobselections, configuration, skills, and slash-command paths continue to work unchanged.
- IBM Bob now appears by its full product name in the tool picker and success messages. Existing
-
#1999
bda8556Thanks @clay-good! - Guide users through an AI-assisted migration from legacyproject.mdtoconfig.yaml. -
#1997
e70dcc7Thanks @clay-good! - Guide proposal authors toward durable, behavior-based capability names. -
#2018
81c2f9fThanks @clay-good! - ### Bug Fixes- Apply edits the right task —
openspec instructions apply --jsonnow gives each task itssourcePathandline. The apply workflow checks the checkbox at that location before marking the task done and rechecks progress afterward, so agents update the exact task, even when tasks span several files. - Archive stops on a failed spec sync — When the spec sync inside
/opsx:archivereports a blocking condition, such as a capability retirement it could not complete, the archive now stops and leaves the change in place instead of archiving it with the main specs unchanged. The same applies to bulk archive. - Aligned
openspec viewprogress bars — Active change names up to 48 characters now line up their progress bars instead of pushing each bar out of line.
- Apply edits the right task —
-
#1969
9557b43Thanks @flcrom! - ### Bug Fixes- Let store-only repositories run
openspec initat the repo root to install integrations without changing the external-store config or creating local planning directories.
- Let store-only repositories run
-
#2004
d4e1c77Thanks @clay-good! - Warn that files listed for legacy cleanup are deleted entirely and ask users to back up custom content first. Theopenspec/AGENTS.mdcheck detects the file by existence alone. -
#1995
baad449Thanks @clay-good! - Guide agents to keep project documentation and codebase facts out ofconfig.yamlcontext. -
#1978
1872982Thanks @clay-good! - The specs instruction now tells agents the 500-character requirement length thatopenspec validateflags as an informational hint, and how to stay under it when writing new requirements without splitting existing ones. The validator's too-long message now explains how to split a requirement too. -
#1972
d28fb49Thanks @ryandemelo! -show --jsonnow includes each requirement's and scenario'sname, matching the header names archive uses, so JSON readers can cite a requirement without parsing the markdown again (#1971). -
#2014
cf2859aThanks @clay-good! - Fixstatus --jsonfor store-backed changes:actionContext.allowedEditRootsnow lists the project on the current path that declares the store alongside the store, so apply no longer stops on a store-only edit scope. When no project on the current path declares the store, the constraint tells the agent to ask which repository to edit instead of naming the store. -
#1984
42671dfThanks @Yi-111-a! - Name the offending index when arules:list is not an array of stringsA rule item containing an unquoted
": "is valid-looking YAML but parses as a mapping, so the artifact's whole rule set is dropped with only a stderr warning naming the artifact. The warning now also names the index and the shape YAML produced there, plus the quoting fix, so the bad item can be found without bisecting the list by hand. -
#1925
88692b3Thanks @kevin9327! - ### Bug Fixes- Change metadata — Warn when
.openspec.yamlcontains unrecognized keys such asskip_design. Those keys were stripped with no signal, sostatusstill demanded the design artifact andvalidate --strictexited 0.status,validate, andarchivenow name the ignored keys;validate --strictfails.
- Change metadata — Warn when
-
#2016
cd4f9e4Thanks @huiq777! - Makeopenspec completion uninstall zshhand.zshrcback exactly ascompletion install zshfound it. Uninstall stripped every blank line at the top of the file, so a.zshrcthat started with blank lines lost them after an install/uninstall round trip, even when the OpenSpec block had been moved further down. Uninstall now drops only the separator line install added, and only when the block sits at the top of the file, matching the bash installer.
1.13.2
Patch Changes
-
#1940
0b5ce44Thanks @clay-good! - Keep fast-forward clarification guidance and onboarding task approval consistent across generated skills and commands. Fast-forward now asks only when context is critically unclear, while onboarding asks users to approve the task breakdown before saving it and separately asks whether to begin implementation. -
#1926
f2812f6Thanks @kevin9327! - ### Bug Fixes-
Archive — When Windows
EPERMblocks renaming a change directory that still has children, copy from the original source instead of requiring a staging rename that fails the same way. That lets archive finish instead of rolling back the spec write and leaving an empty capability directory git cannot see. A staging failure that is notEPERM/EXDEVstill leaves the source untouched.The source of that unstaged copy is still the live change directory, which the archive claim does not cover, so cleanup removes only the entries it copied and verified rather than whatever is present when it runs. A file written in that window is left alone and the complete destination is retained for recovery, instead of being deleted without ever reaching the archive.
An edit to a file that was already verified is covered too. Cleanup claims each entry with an atomic rename before reading it, then compares what it claimed against the copy. A rewrite that lands first is caught by that comparison and the file is put back; one that lands after creates a new file at the original path, which is never deleted. Either way the newer bytes stay on disk and archive reports the move as incomplete rather than succeeding with the older copy.
Rollback of a newly created spec now also prunes the capability directory it created — and only that one. An empty capability directory that was already there is left in place with its own permissions.
-
-
#1795
fb1b876Thanks @runsonmypc! - Archive workflows now use schema-aware task progress fromopenspec list --json, so custom task files and globs still trigger incomplete-task warnings. -
#1885
fd56e12Thanks @philo-x! - Fix artifact output resolution to recognize brace expansion and extglob patterns while preserving literal output filenames and confining brace-expanded paths to the change directory. -
#1964
7ac58dcThanks @clay-good! - Continue commands now open with an instruction to follow the active OpenSpec workflow directly, so local models no longer try to call a tool named after it (#1944). -
#1964
7ac58dcThanks @clay-good! - Generate Kilo Code commands in.kilo/command/, the directory Kilo Code reads, instead of.kilocode/workflows/(#1938).openspec initand legacy cleanup remove the workflow files OpenSpec generated there, matched by their known file names (including copies you edited), and leave files with other names in place. -
#1958
1d35e90Thanks @clay-good! - Preserve a file's existing line endings when rewriting it, so Windows users no longer get whole-file diffs. Applying a delta to a CRLF spec (the default on a Windows checkout withcore.autocrlf=true) rewrote the file to LF, turning a one-requirement change into a diff that touched every line.openspec archivenow writes the spec back with the convention it already used; a spec that does not exist yet is still written with LF.The same fix covers marker-managed files: installing or updating shell completions in a CRLF
.bashrcor.zshrcno longer leaves the file with mixed endings, whichbashreports as$'\r': command not found.Removing a managed block is fixed the same way: the blank-line collapse in
removeMarkerBlockrebuilt its separator as a bare LF, so cleaning up legacy artifacts left a lone LF inside an otherwise-CRLFCLAUDE.mdor rc file. Both write paths now read the file the same way, by dominant ending, so one stray CRLF in an otherwise-LF file no longer pulls the whole rewrite to CRLF.scripts/pack-version-check.mjsnow spawnsnpmthroughcross-spawn, so the release guard can run on Windows, wherenpmisnpm.cmdand cannot be resolved byexecFile. -
#1912
8826c0cThanks @Tyagiquamar! - Fixvalidate --strictreportingPURPOSE_IS_PLACEHOLDERfor a Purpose that opens with the ordinary word "Todo" followed by prose, as in Spanish ("Todo el…") and Portuguese ("Todo o…") specs (#1897).- Case now separates the marker from the word.
TBD/TODOin capitals is still a placeholder marker whatever follows it, soTODO write this lateris still reported. - In any other case it counts as a marker only when followed by the end of the Purpose, a line break, or marker punctuation (
todo -,tbd.), so an authored Spanish or Portuguese sentence is not reported.
- Case now separates the marker from the word.
-
#1744
5b55263Thanks @javigomez! - Clarify the Codex setup hint for CLI, IDE, and desktop app users. -
#1809
a5ceea3Thanks @ryandemelo! - Say what aMODIFIEDblock adds when the scenario-loss guard fires (#1809).openspec validateandopenspec archivealready named the scenarios a block omits. They now also print how many scenarios each side has and which ones the block introduces, capped at three names, so a rename and a truncation read differently without opening either file. The guard catches exactly what it did before, and no exit code changes. -
#1731
d6bdef6Thanks @runsonmypc! - Stop workflows from displaying schema names thatopenspec list --jsondoes not return. Update and continue no longer fabricate aspec-drivenpicker label, while bulk archive and explore describe only the change fields the list command actually provides. -
#1955
ed5d386Thanks @clay-good! - Task guidance now requires each task group to land its own tests and documentation updates instead of deferring them to a trailing group. The onboarding walkthrough teaches the same rule, and the published schema reference no longer quotes stale instruction text. -
#1939
a64303fThanks @clay-good! - Return a nonzero exit status whenopenspec update --forcecannot replace a legacy-only Codex installation. -
#1733
72fbe4cThanks @runsonmypc! - Let/opsx:updatefill a missing file under an already-satisfied glob artifact. A glob artifact is complete once one file matches it, and/opsx:continueonly picks upreadyartifacts, so the previous "point the user to/opsx:continue" handoff was unreachable and the missing file could never be created through the documented flow. -
#1962
3364146Thanks @ryandemelo! - Stop/opsx:verifyfrom reporting a correctly removed requirement as missing. Verify now reads which delta section each requirement sits under: ADDED and MODIFIED requirements are checked for an implementation as before, a REMOVED requirement passes once its behavior is gone and is flagged only while it is still present, and the old name of a RENAMED requirement is no longer reported as missing. -
#1732
072de6bThanks @runsonmypc! - Stop/opsx:verifyfrom reporting skipped checks as passing. Task completion now uses the schema-awaretasksandprogressfields returned by apply instructions, while absent spec or design inputs are mapped to every check they prevent. Apply instructions aggregate every file matched by the configured task path or glob, regardless of the tracked artifact ID. Verification stays advisory and does not require optional or intentionally omitted artifacts. The scorecard identifies each skipped check, and the final assessment does not claim archive readiness when any check did not run. -
#1769
d3d7707Thanks @kikeprzn! - Fixopenspec archiveleaving.openspec-archive.lockbehind on Windows. Node can reportdev: 0nfrom a path stat while the open file handle reports the real volume id, so the claim-ownership check never matched and the stale lock blocked every later archive. The check now treats an absent device id as unavailable while still requiring the inode and the claim's contents to match before unlinking.
1.13.1
Patch Changes
-
#1864
767d63cThanks @dwin-gharibi! - Stop archive adding a second copy of an existing requirement under a name that differs only in case or spacing. ADDED and the RENAMED target compared requirement names exactly, while REMOVED and the RENAMED source already treated a case or whitespace variant as a mistyped header, so an ADDEDlate feesbeside an existingLate Fees, or a rename toLATE FEES, archived cleanly and left two contradicting requirements in the main spec, whichvalidatethen accepted. Both now refuse with an error naming the existing requirement, in the same form REMOVED already used. The exact-duplicate error is unchanged, a case-only rename of a requirement to its own name still works, and a variant of a requirement the same delta removes or renames away is still allowed, because ADDED is checked against the spec as it stands after the earlier operations, as the exact check already was. -
#1872
72bf760Thanks @dwin-gharibi! - Makeopenspec completion uninstall bashhand.bashrcback exactly ascompletion install bashfound it. Install adds the OpenSpec block at the top of the file followed by a blank separator line; uninstall removed the block but kept that blank line at the top, then stripped every trailing blank line and wrote the file back without its final newline. The byte count happened to come out unchanged, but the next tool to append to.bashrcwith>>(the nvm, conda and rustup installers all do) merged its first line into the user's last line and broke both. Uninstall now also drops the separator line install added when the block sits at the top of the file, and leaves the rest untouched: the final newline, trailing blank lines and CRLF line endings all survive the round trip. A block the user moved elsewhere in the file is still removed, and the zsh, fish and PowerShell installers are unchanged. -
#1829
e67ac47Thanks @choi138! - Fix bulk archive nesting a change inside an existing archive target. The workflow now checks every archive target before it writes any main spec, the same orderopenspec archiveuses. A change whose target already exists, or that shares a target with another selected change, is reported as failed and is never synced or moved, while the rest of the batch continues. The check runs again just before each move. -
#1878
2ef6fbdThanks @dwin-gharibi! - Letopenspec config editrun anEDITORorVISUALthat carries arguments. The whole value was passed tospawnas the program name, so common settings such ascode --wait,subl -woremacsclient -tfailed withspawn code --wait ENOENT, and because that error was never caught the command died with a raw Node stack trace. The value is now split into a program and its arguments, honoring quoted paths with spaces, and the config path is appended as its own argument. No shell is involved, so shell metacharacters in the value are passed through literally. On Windows,.cmdshims such ascode.cmdare found. A value that is itself the absolute path of an existing file is still run as-is, so an unquoted editor path containing spaces keeps working. An editor that cannot be started, exits non-zero or is killed is now reported as a one-line error naming the editor, with an install hint when the program was not found, and the command exits 1 instead of throwing.EDITORstill takes precedence overVISUAL, and the file is still validated after the editor closes. -
#1773
11a9691Thanks @clay-good! - Stop dropping checkbox lines whose marker the task parser does not recognise. Atasks.mdwhose remaining work used a marker other than[ ]/[x]/[X], for example- [~] 1.2 Deferred, reported✓ Completeinopenspec list/statusand archived with no incomplete-task warning, because unmatched lines counted toward neither the numerator nor the denominator. An empty[]and a padded[ x]were lost the same way. Only a box holdingxorXmeans done (spacing inside the brackets is ignored, so[ x]is done), and every other marker now reads as unfinished, across progress, the apply task list, archive's gate and validate's task-numbering check. The archive, bulk-archive and verify workflows now tell agents the same rule, so a hand-counted tally cannot disagree with the CLI, and thetasksinstruction in thespec-drivenschema states it where agents author the file. Markdown link bullets stay out of the count:- [Some doc](./doc.md)and the one-character- [A](https://example.com)are not tasks. -
#1701
92fb72dThanks @clay-good! - Agent-driven archive and sync workflows now create a missing main spec fromADDEDrequirements instead of treating it as already synced. They block sync rather than inventingMODIFIEDorRENAMEDrequirements or writing an empty spec for aREMOVED-only delta, while preserving the user's explicit choice to archive without syncing. A REMOVED-only delta withretire_capabilities: trueremains already synced when its main spec is gone. Fixes #1222 and #1264. -
#1804
a5bf5c6Thanks @dwin-gharibi! - Say so when a requirement in a delta sits outside every delta section. A well-formed### Requirement:block written under## Notes, under a misspelled header such as## Add Requirements, or above the first##header was dropped with no diagnostic:openspec validatereported the change valid andopenspec archiveexited 0 without applying it.openspec validatenow reports each one as a WARNING naming the section and line, and archive prints the same warning. Nothing else changes: the block is still not applied, the verdict stays valid outside--strict, and requirements shown inside a code fence are not reported. Fixes #1803. -
#1832
4c369e0Thanks @clay-good! - Resolve the contradiction that left explore mode's capture branch without a governing rule. Explore states twice that the agent must ask a direct yes/no question and wait for confirmation in a separate user message before its first write-capable action, namingopenspec new changeas an example, while the capture branch tells the agent to transition "seamlessly" into runningopenspec new changeand creating artifacts with no confirmation step. Both readings were defensible from the text, so the same "capture this as a change" request either wrote.openspec.yamlplus several artifacts immediately or stopped and asked, depending on which passage the agent weighed, which made the #1715 guarantee unenforceable in the one explore path that writes files. An explicit capture request is now stated to be that confirmation, covering the change and the artifacts the request names and nothing else. The guardrail keeps its teeth for the case #1715 actually reported: when the agent is the one proposing the capture, or when the work would go beyond the requested scope, it still asks first, and answers to design or clarifying questions are still never consent to write. Both explore delivery surfaces and the committed skill carry the same wording. Fixes #1828. -
#1788
62106f4Thanks @clay-good! - Name the workflow where explore hands off. Explore mode refuses to implement, but every place it said what to do instead described the next step as prose ("create a change proposal") without naming the workflow that does it: the refusal itself, the "flow into a proposal" ending, the closing summary, and the do-not-implement guardrail. Its seamless capture path was worse: it scaffolded a change, wrote artifacts, and then said nothing at all about what came next. With no named exit, agents finished the discovery questions and started writing code, which is the failure reported through GitHub Copilot in #869, and which the docs already promised would not happen ("when the picture is clear, it hands off to/opsx:propose").The explore skill and command now name
/opsx:proposeat all four prose handoffs, and the capture path ends by naming/opsx:proposefor the remaining planning artifacts and/opsx:applyfor implementation, with an explicit note that capturing artifacts is not permission to implement them. The references are written in the canonical/opsx:<id>form so each tool renders the invocation it actually registers (/openspec-proposefor skills-only delivery,/opsx-propose,/opsx:propose, or@opsx-proposefor command surfaces). The handoffs follow the installed workflow set: a custom profile withoutproposeorapplygets explore's own capture path and theopenspec instructions applyCLI instead of a command it never installed. Fixes #869. -
#1787
9827762Thanks @clay-good! - ### Bug Fixes- Generated skills and commands no longer adopt a project that never ran
openspec init. Every workflow now checksrootfromopenspec list --jsonbefore its first write, and"root": nullmeans the project is not set up. What happens next depends on how the workflow was reached. A skill the agent picked on its own drops OpenSpec and answers the request normally, without asking about setup. A workflow the user asked for by name, or ran as a slash command, stops and asks whether to initialize the project, target a store, or handle the request without OpenSpec. A project whoseopenspec/config.yamlnames a store this machine cannot resolve (not registered, or a malformedstore:line) is not mistaken for an uninitialized one: the workflow stops and shows the store error. Neither path letsopenspec new changecreateopenspec/in the current directory as a side effect. Skill descriptions now name OpenSpec so hosts stop offering these workflows in unrelated repositories.openspec new changealso says when it had to create the root itself, so a directory that was never set up no longer picks up anopenspec/directory in silence (human output only;--jsonis unchanged).
- Generated skills and commands no longer adopt a project that never ran
-
#1902
eb03b9eThanks @clay-good! - Harden the CLI against repositories you have cloned but not yet read (#1835).- A
config.yamlvalue can no longer close the project context block and inject its own directives into the instructions an agent receives. - A crafted delta or skill file no longer stalls
openspec updateoropenspec archivewith catastrophic regex backtracking. - A repository's
.npmrccan no longer point the update check at a cleartext or attacker-controlled registry; a rejected registry now disables the check instead of falling back. openspec updatenow notices a generatedSKILL.mdthat was edited by hand and restores it, instead of reporting every tool as up to date.DO_NOT_TRACK=trueand other common spellings of an opt-out now turn telemetry off, and nothing is sent until the first-run notice has been shown.- Shell-completion installs quote directory paths safely, git probes run with bounded time and output, and dependencies are cleared of known advisories.
- A
-
#1874
388d344Thanks @dwin-gharibi! - Stop legacy cleanup deleting the user's own files. The six pre-skills tools that kept their commands in a<tool>/commands/openspec/folder (Claude Code, CodeBuddy, Qoder, Lingma, Crush and Gemini CLI) had that whole folder removed recursively whenever it existed, so a command the user kept there, such as a team review checklist, was deleted along with OpenSpec's files, and the summary named only the folder. Becauseopenspec initcleans up automatically when there is no TTY, an agent or CI running plainopenspec initdid this without--forceand without a prompt, andopenspec update --forcedid the same. Cleanup now deletes only the files OpenSpec wrote there:proposal,applyandarchivefiles that still carry the OpenSpec markers every legacy command was generated with, so a same-named file the user wrote is kept. It never follows a symlinked command folder, removes the folder only once nothing else is left in it, and lists each thing it kept. A folder holding nothing OpenSpec wrote is no longer reported as legacy at all. A folder holding only OpenSpec's files, or nothing, is still removed exactly as before, with the same summary line. -
#1866
8146be5Thanks @dwin-gharibi! - Stop one unresolvable file from breakingopenspec list. To sort changes by recency,liststats every file inside each change, and any entry it could not stat failed the whole command: a dangling symlink, such as the.#tasks.mdlock Emacs keeps beside every file with unsaved edits, or a symlink loop madelistexit 1 andlist --jsonreport"changes": [], so agents discovering work through it saw no changes at all. An entry that no longer resolves (removed mid-walk, a dangling symlink, or a loop) is now skipped when computing a change's last-modified time. Valid symlinks are dated as before, and any other error, such as a permission failure, still fails the listing. -
#1849
09a999bThanks @clay-good! - Report a change directory nested in a namespace folder instead of silently listing the folder around it as a change. Specs can be nested by domain (specs/mobile/tutorial-videos/spec.md), so it looks reasonable to lay changes out the same way, but a change is only ever a directory directly underchanges/:changes/mobile/refresh-token/left the real change invisible whilemobilewas reported as a task-less change everywhere.openspec archive mobilethen moved the unfinished change into the archive under the namespace's name and applied none of its deltas.openspec listnow marks the foldernot a changeand names the nested directories and a flat alternative,openspec show,openspec status --changeandopenspec status --allsay the same instead of reporting a missing proposal or a full artifact plan,openspec validatereports it instead of "must have at least one delta",openspec list --jsoncarries awarningsentry, andopenspec archiverefuses the folder outright. Detection looks up to three directory levels belowchanges/, which covers every namespace layout seen in practice; a change buried deeper than that behaves as it did before. Fixes #1846. -
#1902
eb03b9eThanks @clay-good! - Install shell completions with the Nix flake package (#1785). The package now ships bash, zsh and fish completions in their standardshare/locations, so Nix users get tab completion without runningopenspec completion installagainst their home directory. -
#1775
626269eThanks @clay-good! - Generated skills and commands no longer point at workflows the active profile does not install. On the defaultcoreprofile, the update workflow told agents to hand off to/opsx:continuefor missing artifacts and to/opsx:newfor a change of intent, neither of whichcoregenerates. Every cross-workflow handoff is now decided at generation time against the installed workflow set, and renders a concrete CLI fallback (openspec status,openspec instructions,openspec archive) when the workflow it would name is absent, rather than relying on a runtime availability check the agent had to perform. The onboarding tutorial's command tables are likewise built from the workflows you actually have.Also folds in #1735, which fixed the same issue (#1734) by removing the optional handoffs outright. The CLI's own runtime instructions no longer name the
openspec-continue-changeskill either, since those strings are chosen at run time and cannot be resolved against a profile; and the blocked-state fallback now carries the full CLI recovery (select the nextreadyartifact fromopenspec status, read its rules withopenspec instructions, keep the selected--store) rather than a one-line pointer. -
#1870
e01ed07Thanks @dwin-gharibi! - Stop archiving a change whose delta was written somewherearchivenever reads.validateandarchiveread a change's deltas only fromspecs/<capability-path>/spec.md, but the spec-driven artifact graph counts any markdown file underspecs/as the specs being written, so a delta atspecs/user-auth.md, or in a second file beside a capability'sspec.md, was reported done bystatusand ready byinstructions applywith no warning, rejected byvalidateonly as "no deltas found", and then archived with exit 0 and nothing merged intoopenspec/specs/. A markdown file that carries delta sections but is not a capability'sspec.mdis now a validation error naming the file and thespec.mdits requirements belong in;archiveruns that validation and refuses the change instead of archiving it unmerged, andinstructions applylists each such file in itswarnings.--no-validatestill archives as before, a change with no spec files still archives, and notes without delta sections underspecs/are not affected. -
#1806
6e62b1dThanks @dwin-gharibi! - Refuse a## RENAMED Requirementssection whoseFROM:andTO:lines do not pair up, instead of guessing. The reader kept one pending pair and dropped whatever did not fit: aTO:before itsFROM:, aFROM:displaced by a secondFROM:, or a trailingFROM:vanished with no diagnostic. Listing the old names and then the new ones paired the secondFROM:with the firstTO:, soopenspec archiverenamed a requirement the delta never named, under a name written for a different one, and exited 0.openspec validatenow reports each unpaired line as an ERROR with its line number, and archive refuses the change until the pairing is fixed. Well-formed renames, including several consecutive pairs, are unchanged. A change that used to archive with a malformed RENAMED section is now rejected. Fixes #1805. -
#1860
4b5c07aThanks @dwin-gharibi! - Read a requirement heading written with a CommonMark closing sequence, such as### Requirement: Late Fees ###, as the requirement it renders as. The trailing#run stayed in the name, so a REMOVED written that way looked for "Late Fees ###", missed the requirement, and archive exited 0 with a false "treating it as already removed" warning while the requirement stayed in the spec; a closed MODIFIED or RENAMED heading failed as "not found", and a closed and an open heading of one requirement were not reported as duplicates. Requirement names now drop the closing run wherever they are read, exactly as scenario names already did: only a run preceded by a space or tab counts, so a name such asC#keeps its#. Headings without a closing run are unaffected. -
#1868
7090e16Thanks @dwin-gharibi! - Reject a schema whoseapply.requiresnames an artifact that does not exist.parseSchemachecked every artifact'srequiresbut neverapply.requires, soopenspec schema validatepassed a one-character typo there, and apply then skipped the unknown id:apply.requires: [desgin]turned the apply gate off and told the agent "Proceed with implementation" with only a proposal written. That is now a schema error, raised wherever the schema is loaded, exactly like an unknown artifactrequires, and it names the bad id and the artifacts the schema declares.openspec schema validatealso warns, without failing, whenapply.tracksisn't exactly equal to some artifact'sgeneratesvalue, because OpenSpec finds the tracked artifact by comparing those two strings and can otherwise not tell which artifact's progress the file belongs to. That covers a typo such astask.mdand alsotracks: tasks/main.mdagainstgenerates: tasks/*.md, where the glob does produce the file but the strings still differ. Apply reads that path as written either way, so schemas that track a hand-written file keep loading and working. Every built-in schema parses as before. -
#1856
46ff91fThanks @dwin-gharibi! - Makeopenspec show --json --deltas-onlyreport the deltas archive applies.ChangeParser, which backsshow --json, thechange listdelta counts and archive's proposal warnings, read delta specs with its own section lookup instead ofparseDeltaSpec, the reader archive uses, and the two disagreed. A REMOVED written in the bullet form (- `### Requirement: X`) was invisible to it, so it fell back to the proposal's "What Changes" prose and reported an invented MODIFIED while archive deleted the requirement; a repeated section header was read only once; and a RENAMED line written with*or+was dropped. The inspection command OpenSpec's own error text recommends therefore misreported a deletion.ChangeParsernow derives every operation fromparseDeltaSpec, and a change whose delta spec files carry a delta section is described by them alone, so proposal prose is never reported in place of what archive applies. Requirement text and scenarios are read exactly as before, header-form deltas produce the same output, and a change with no delta spec files, or a legacy change whose spec files carry no delta section, still falls back to the "What Changes" bullets. -
#1786
8b99c07Thanks @clay-good! -openspec statusnow names the command that moves the change forward.The text output reported state and stopped there, so picking a change back up (after a lost session, or on a change you did not start) meant already knowing which command came next. The JSON surface had carried that command all along in
nextSteps; the text surface never printed it.Status now ends with a
Next:line: the next ready artifact'sopenspec instructionscommand while planning is unfinished, andopenspec instructions applyonce every planning artifact exists. It carries--store <id>when the resolved root is a store, and it is built from the same source as the JSONnextStepssentence, so the two surfaces cannot name different commands. -
#1882
208b5b5Thanks @dwin-gharibi! - Stop a store namedspecsorchangesfrom taking over root selection. Stores are placed at~/openspec/<id>, so a store with one of those ids is itself~/openspec/specsor~/openspec/changes, and that made$HOMElook like a planning root. Every command run anywhere under the home directory then resolved$HOMEas the nearest root: the globaldefaultStorewas never consulted, andnew changewrote into~/openspec/changes, outside any store. Aspecs/orchanges/directory that carries store metadata no longer counts as planning content of the directory above it, so these stores resolve like any other. A real project'sopenspec/specs/andopenspec/changes/are unaffected. -
#1880
9f8dec5Thanks @dwin-gharibi! - Stopopenspec store removedeleting a store the user did not name. Remove deletes the target's folder recursively, but it checked only the target's own metadata, so any other registered store living inside that folder was deleted with it, uncommitted planning work included, while its registry entry was left pointing at a path that no longer existed. The natural way to get there is a shared store vendored into another as a git submodule, a layoutstore registeraccepts. Remove now refuses when another registration points inside the folder, checked under the same registry lock that commits the removal, and the error names each nested store with theopenspec store unregistercommand to run first. Removing a store whose other registrations are siblings is unchanged, andstore registerstill accepts nested checkouts. -
#1884
5d22145Thanks @dwin-gharibi! - Letopenspec store setup --no-init-gitcreate a store inside an existing Git repository. Setup refuses a path inside another repository because initializing the store there would nest one repository in another, but it ran that check even with--no-init-git, which creates no repository at all. Users who keep their home directory as a dotfiles repository therefore could not set up a store at the recommended~/openspec/<id>path with any flag. With--no-init-gitthe check is now skipped, and the store never records the enclosing repository's remote. The default setup and an explicit--init-gitstill refuse a path inside another repository. -
#1862
8fc65b7Thanks @dwin-gharibi! - Count task checkboxes under every CommonMark list marker. The task counter shared bylist,status,view,instructions apply,validate --archivedand archive's incomplete-task check recognized only-and*bullets, so a task written as an ordered item (1. [ ],1) [ ]) or under a+bullet was invisible to all of them: a change with unfinished ordered tasks reported "✓ Complete", andopenspec archivearchived it without its incomplete-task warning. Task lines under+and ordered markers (.or), up to nine digits, as CommonMark allows) now count exactly like-and*ones, including nested sub-tasks, CRLF files and the existing tolerance of a missing space after the marker, and task-numbering checks now see them too. Ordered and+items without a checkbox are still ignored, and-and*tasks count as before. -
#1777
3312af4Thanks @clay-good! - Start generated proposal, spec, design, and tasks files with a top-level heading, so artifacts are complete markdown documents instead of files whose first line is a section header. Editors that run markdownlint no longer flag every OpenSpec artifact with MD041.openspec schema initscaffolds custom templates the same way.openspec show --jsonandopenspec change list --jsonkeep naming a change by its id when its proposal opens with the template's bare# Proposaltitle. -
#1778
7de2404Thanks @clay-good! - Make the vendor-neutral tool target findable when your assistant is not on the list.openspec initnow shows it as "Other / Universal (shared .agents skills)"; the picker's search box matches it onuniversal,other,generic,custom,proprietary,unlisted,unsupported,vendor-neutralandagents.md; a search that matches nothing points at it instead of ending at "No matches"; and--tools <unknown>names it in the error. The search box also accepts punctuation, so.agentsandamazon-qfilter instead of silently dropping their.and-. -
#1876
605d9e7Thanks @dwin-gharibi! - Stop OpenSpec rewriting a global config file it cannot parse. After a hand edit left a typo such as a trailing comma inconfig.json, the next command of any kind, including read-only ones likeopenspec list, read the fallback defaults as telemetry consent, minted a new anonymous ID and wrote it back, replacing the whole file: atelemetry.enabled falseopt-out, the chosen profile and the workflow list were all lost, and usage events were sent. A config file that exists but does not hold a JSON object, whether it failed to parse or its root is something else such asnull, an array or a string, is now never written implicitly, and telemetry and the update check treat it as opted out.config set,config unsetandconfig profilerefuse with an error that names the file and points toopenspec config edit, andopenspec config reset --allstill replaces it. The existing "Invalid JSON" warning is unchanged, and valid or missing config files behave exactly as before. -
#1840
fede536Thanks @clay-good! - Resolve the contradiction that left/opsx:update's only write path without a governing rule. Step 4 told the agent to "Apply the requested edit", while step 5 and the guardrails told it to write only after the user confirms each revision, so the same/opsx:update "the design now uses X"either wrote immediately or stopped and showed the proposed revision first, depending on which passage the agent weighed. Step 4 now drafts the edit in the conversation and step 5 owns every artifact write, matching the workflow's own specified behavior: propose each revision and apply it only after user confirmation. Fixes #1836. -
#1858
db560aeThanks @dwin-gharibi! - Stopvalidateaccepting a requirement whose only scenario is a bare header. The delta scenario counter counted every####header, while the spec path that archive uses to validate the rebuilt spec keeps a scenario only when its body has content, sovalidatecalled such a change valid andarchivethen refused it with a generic "Requirement must have at least one scenario" that did not name the requirement. Both paths now share one rule,hasScenarioBody, and read a scenario's body up to the same boundary, sovalidaterejects exactly what archive rejects, naming the requirement and saying that a header with no body under it does not count. A scenario whose body is only a fenced block or a deeper header still counts, a requirement with one real scenario is still accepted even when another is empty, and main-spec validation is unchanged. -
#1774
09984b8Thanks @clay-good! - ### Bug Fixes- Task lists without checkboxes are now caught: a
tasks.mdwritten as plain bullets or a numbered list counts as zero tasks, soopenspec listandopenspec statusreported "No tasks" andopenspec archivehad no unfinished work to warn about.openspec validatenow warns when a change's tracked task files contain list items but no checkbox at all, and points at the first offending line.
- Task lists without checkboxes are now caught: a
-
#1852
5f5914eThanks @clay-good! - Match the natural "openspec " phrasing to the workflow it names. Users and agents say "openspec propose" or "do an openspec apply", but no workflow skill's description contained that phrasing (and a skill's description is what an agent matches on), so the phrase read as an invitation to hand-build the artifacts with the CLI instead of running the workflow. Every workflow skill's description now names the phrasings a user actually types ("openspec propose", "opsx apply", and so on). Runopenspec updateto pick it up.openspec updateitself is deliberately left unclaimed: it is a real CLI command that refreshes generated files, unrelated to the update-change workflow, which claims "openspec update change" instead. Commands-only installs write no skills and are unchanged. Fixes #1221.
1.13.0
Minor Changes
-
#1783
8ba4ac1Thanks @clay-good! - Apply now says when a change has no delta specs. Apply gates on the schema'sapply.requiresalone, so a change whosetasks.mdwas written ahead of its specs read as ready to implement even though it had no spec deltas at all — the stateopenspec validaterejects.openspec instructions applynow reports that gap as a warning (text and--json), naming both ways out: write the specs, or declareskip_specs: true. Changes that have specs, declareskip_specs, or are still blocked on their own required artifacts are unaffected.A blocked apply also names the whole chain now, not just the first hop: a change holding only a proposal reported
Missing artifacts: taskswhile the specs thattasksdepends on were missing too, which reads as an instruction to write the tracking file straight from the proposal. The full build order is reported asmissingPrerequisitesin--json. The remedies these messages give are CLI commands (openspec instructions <artifact> --change <name>) rather than theopenspec-continue-changeskill, which thecoreprofile never installs.
Patch Changes
-
#1798
aedf4d0Thanks @dwin-gharibi! - Stop archive rewriting the inside of fenced code blocks. The final assembly inbuildUpdatedSpeccollapsed runs of blank lines across the whole rebuilt document to tidy the seams between the slices it rejoins, but the pass was not fence-aware, so a requirement documenting a sample with two or more consecutive blank lines had that sample silently edited on archive, and edited again on every later archive. That matters wherever whitespace carries meaning: YAML block scalars, Python, expected-output fixtures, Markdown inside Markdown. Blank runs are now collapsed only outside fenced blocks, using the samebuildCodeFenceMaskevery other structural pass in the module already used. Behavior outside fences is unchanged, including that only a truly empty line counts as blank, so a line of spaces is still never a collapse boundary. Fixes #1797. -
#1800
fadac3eThanks @dwin-gharibi! - Read a removal or rename written with*or+as the operation it is. CommonMark opens a bullet list with-,*or+, but the bullet form of## REMOVED Requirementsand theFROM:/TO:lines of## RENAMED Requirementsboth hardcoded-, so either other marker matched nothing at all. The operation then silently never happened:openspec validatereported the change valid,openspec archiveexited 0 with "Specs updated successfully", and the requirement that was supposed to be deleted or renamed stayed exactly as it was. The change archived as complete, leaving the spec quietly disagreeing with the delta that was meant to update it. Both forms now accept[-*+], theFROM:/TO:bullet stays optional, and the plain### Requirement:header form is unchanged. Fixes #1799. -
#1802
8251763Thanks @dwin-gharibi! - Apply every delta section, not just one copy of each. A delta file that wrote the same header twice, two## ADDED Requirementssections say, silently kept one of them: sections were collected into a record keyed by title, so a repeated title overwrote the earlier body, and the case-insensitive lookup returned only the first entry that folded to the target, so## ADDED Requirementsbeside## Added Requirementsleft the second unread. Every requirement under the discarded copy was gone before validation or the merge could see it, soopenspec validatereported zero issues andopenspec archiveexited 0 having applied less than the author wrote, then moved the change to the archive with the live spec quietly diverging from what was reviewed. Sections are now kept as a list and every body whose title matches is read, each keeping its own line numbers so diagnostics still point at the right copy. Rename pairs are read per section, so aFROM:in one copy of the header can never pair with aTO:in another. An author does not have to repeat a header on purpose to hit this: a delta documenting OpenSpec's own syntax inside a fenced example produces the duplicate on its own. Fixes #1801. -
#1657
6d2dbe6Thanks @clay-good! - Load project context before proposal planning, using the selected project or store root and honoring config precedence and validation limits. When no root exists, stop without writing files and offer initialization instead of creating an implicit root. -
#1700
3915db7Thanks @clay-good! - Teach the generated guidance how to find and read a project's specs.openspec list --specsappeared in no generated skill, command, or artifact instruction, whileopenspec list --json(the in-flight change list) appeared throughout, so an agent asked to read the existing specs first enumerated changes instead and reported the step complete against the wrong object. The explore skill and command now list the spec inventory alongside the change list and say which is which, and the spec-drivenproposalandspecsinstructions name the command where they ask for existing capabilities to be researched and for a delta's path to match an existing one. Both steps carry--store "<id>", and capabilities are read withopenspec show "<spec-id>" --type spec --json --no-scenariosso the read resolves against the same root the listing came from. Fixes #1689.The filtered read is only an overview. Agents read relevant specs in full, including scenarios, before deciding what is already covered or what should change.
-
#1779
3c6d318Thanks @clay-good! -openspec initandopenspec updatenow name the workflows your profile left out and how to add them, so a command that was never installed no longer reads as a broken setup. -
#1808
d9e1a28Thanks @dwin-gharibi! - Stopopenspec updatereporting a tool up to date while a damaged command file sits on disk. The check read thegeneratedByversion marker in a tool's skill files alone, which proves only that the skill files came from this CLI and says nothing about the command files written beside them, so a hand-edited or truncated command file left update printing "All 1 tool(s) up to date" and repairing nothing; the file could be restored only by knowing to pass--force. A deleted command file was already detected, so the claim was false only for a damaged one. Update now also compares command-file content, using the comparison that already existed and was simply never consulted once a skill file supplied a version. Scoped to tools configured for both skills and commands, so the commands-only path is unchanged, and skipped when the delivery mode generates no commands for the tool. Fixes #1807. -
#1782
c170dc7Thanks @clay-good! - Fixretire_capabilitiesrefusing any spec whose scenario bullets wrap onto a second line. The continuation line was counted as content the merge could not account for, which blocked the retirement and suppressed the hint that names the marker (#1780). A spec bulleted with+is covered too: naming only-and*as list markers reported every one of its scenario bullets as unaccounted content, so that capability could not be retired at all either.
1.12.0
Minor Changes
-
#1171
44a39ebThanks @aleksandr4842! - Add SourceCraft Code Assistant as a supported tool for project skills and commands in its VS Code extension. -
#1713
db03c6cThanks @Marzx13! - ### New Features- Add
openspec validate --report findingsfor explicit bulk scopes. It returns only items with errors, warnings, or information while keeping full-run totals and exit codes. JSON output identifies the report and its scope; human output includes each finding's path and message. The default full report is unchanged.
- Add
Patch Changes
-
#1710
a4fcdbeThanks @ryandemelo! - Report delta merge conflicts during validation as informational findings, including in successful text reports, without changing validation exit codes. Preserve filesystem read errors so unreadable main specs are not mistaken for missing specs.Keep the validation report intact when the advisory merge preflight cannot resolve its inputs.
-
#1017
b976106Thanks @DanRioDev! - Improve explore mode guidance so it asks more useful dependency-aware questions, recommends defaults, and checks the codebase before asking for facts the repo can answer. -
#1737
98bf53eThanks @clay-good! - Guide propose and fast-forward workflows to inspect relevant project code, tests, and documentation before drafting artifacts, so plans reflect the existing implementation instead of deferring basic discovery to implementation tasks. -
#786
0296401Thanks @Br1an67! - Preserve empty OpenSpec directories in Git after initialization. Re-running init restores missing directory markers without overwriting existing files or following marker symlinks. -
#1725
cd72444Thanks @aron-intframe! -openspec initandopenspec updatenow share the IDE restart hint: "Restart your IDE to refresh commands." or "Restart your IDE to refresh skills." The message also covers removing workflows, without claiming that new files were generated.
1.11.0
Minor Changes
-
#1301
a7353aeThanks @m-tanner! - Addopenspec status --all, which reports every active change in one process instead of one CLI spawn per change.--all --jsonemits a single{ "changes": [ <status>, ... ], "root" }envelope sorted by change name; a change that fails to load contributes{ "changeName", "status": [diagnostic] }in place rather than aborting the sweep. A partial failure exits 1 in both text and JSON modes while preserving the complete JSON envelope. Mutually exclusive with--change. -
#980
dd7cea3Thanks @bsmedberg-xometry! - show: add--diff, which renders each delta requirement against the requirement it replaces in the main spec instead of reprinting the whole block. A MODIFIED requirement has to carry every scenario it keeps, so reviewers could not see what a change actually altered without diffing files by hand.openspec show <change> --diffnow prints a colorized unified diff per requirement (additions green, removals red), the full text of ADDED requirements, the authored Reason/Migration text of REMOVED ones, and FROM/TO for RENAMED ones; a requirement that is renamed and modified in the same delta is diffed against its old name.--json --diffkeeps the existing payload shape and adds each applicablediffandwarningfield to MODIFIED deltas only. Main specs resolve against the same root as the change, so--store <id>diffs against that store. Without--diff,openspec show <change>prints exactly what it printed before.
Patch Changes
-
#830
109f81fThanks @alfred-openspec! - Write Antigravity skills and workflows to.agents/, arbitrate its shared skill tree with other tools, and safely migrate an existing.agent/install. -
#1712
04b37acThanks @Marzx13! - archive: preserve a requirement's original position when renaming it instead of moving the renamed block to the end of the spec. -
#1716
7010e26Thanks @aymanxdev! - explore: require explicit, scope-bound confirmation before the skill uses any command or tool that can create, edit, move, or delete a file. The explore skill's guardrails let "if the user asks" cover answers to its own clarifying questions, so an agent could treat a design discussion as a go-ahead and start creating schemas or editingopenspec/config.yamluninvited. The skill and the/opsx:explorecommand now instruct the agent to name the proposed artifacts or files, ask a direct yes/no question, and wait for confirmation in a separate message before writing. Read-only commands and tools remain available without confirmation, and expanding the confirmed scope requires another confirmation. -
#1199
ab81a4bThanks @leo-ar! - Improve Fish completions so command, subcommand, flag, and indexed positional completions no longer fall back to filesystem suggestions unless the target is a real path. -
#1010
e5e350dThanks @Dansyuqri! - Draw explore-mode diagrams with plain ASCII. The worked examples in the explore skill and/opsx:explorecommand used Unicode box-drawing, arrow, and marker glyphs, whose display width varies across terminals, fonts, and locales. Agents copied the style, causing padded boxes and aligned tables to drift. -
2fa679fThanks @ryandemelo! - Makeschema init --defaultvalidate and stage config changes before installing a schema, and roll back both files if either install fails. The staging and backup directories it creates are excluded from schema discovery, so they are never offered as real schemas. -
#1671
126c5d6Thanks @kitimark! -openspec validatenow reports a## Purposethat is still the placeholder archive writes for a new capability, instead of passing it. The placeholder is longer than the 50-character brevity floor, so until now the one check meant to catch a Purpose nobody wrote was satisfied by the exact text saying nobody wrote one — a spec whose Purpose readDoes stuff.failed--strictwhile a spec whose Purpose said nothing at all passed. A capability could carry the placeholder indefinitely while every command reported success.It is a warning, so a project that already has placeholders on disk keeps validating by default and only
--strictfails. The message says to edit the main spec directly, since a## Purposein a delta is read only when the capability is created and cannot replace an existing one.Detection is narrow. The placeholder archive generates is recognised through the same definition that writes it, wherever it appears in the Purpose. Otherwise only a
TBDorTODOopening the Purpose counts, soThe retry budget is TBD pending benchmarksis still a valid Purpose and a word likeTBDsis not a marker. Fenced code inside the Purpose is quoted material rather than the Purpose speaking, so a spec that documents the placeholder keeps passing. An empty Purpose is unchanged, and a Purpose reported as a placeholder is no longer also reported as too brief, so a bareTBDyields one finding rather than two.openspec archiveis unaffected: it validates rebuilt specs without--strict, so a spec archive writes still passes the validation it would have passed before, and the text archive writes is unchanged.
1.10.0
Minor Changes
- #1685
c747ed1Thanks @clay-good! - Addopenspec init --language <language>to configure the language used for artifacts in new projects.
Patch Changes
-
#1704
7276c6cThanks @clay-good! - Drop the npmpostinstallscript. Its only job was printing a one-line tip about opt-in shell completions, but shipping any install script madenpm install -g @fission-ai/openspecemit anallow-scriptswarning that reads as a packaging fault (andnpm approve-scriptsthen fails withENOMATCHon a global install, since it looks in the local project). The tip now prints from the CLI on its first run — to stderr, in an interactive terminal, once, and not at all if you already have completions installed — and the published package declares nopreinstall/install/postinstallscript, so a registry install runs no OpenSpec code. Suppress the tip withOPENSPEC_NO_COMPLETIONS=1. -
#1656
a72a74dThanks @clay-good! - ### Bug Fixesopenspec updatenow suggests restarting an IDE only when it updates an IDE-resident tool. CLI tools such as Claude Code, Codex, and Gemini CLI no longer show an unnecessary restart hint.
-
#1703
9643888Thanks @clay-good! - Point the spec-drivenspecsinstruction's main-spec read and edit at the store-aware root. It namedopenspec/specs/<capability-path>/spec.md, a path relative to the current directory, for both step 1 of the MODIFIED workflow ("locate the existing requirement") and the edit that fixes a leftoverTBDPurpose. When the change lives in a store — whether selected with--store, a projectstore:pointer, or a global default store — the main spec is under the store root, so that read missed it, or silently returned a different capability when a local one happened to share the name, and the MODIFIED block was then copied from the wrong requirement. Both operations now use<planningHome.root>/openspec/specs/..., the root already returned byopenspec instructions ... --jsonand the same convention the sync and archive workflows use. Fixes #1702. -
#1699
18688c8Thanks @clay-good! - archive: tell the author how to retire a capability when the emptied spec also holds content the merge cannot account for. That combination printed only "Spec must have at least one requirement" and no guidance at all; the abort now names the blocking lines and reports aretire_capabilitiesmarker that is present but cannot be honored. Authored content quoted in those messages - the blocking lines, and the marker's own reason, whichopenspec validateprints too - is stripped of control characters and bounded in length before it reaches the terminal. -
#1660
7da3f34Thanks @clay-good! - Require generated tasks to state how their completion can be verified.
1.9.0
Minor Changes
-
#1622
59c16a4Thanks @clay-good! - ### New Features- Command Code command adapter — Command Code is now a first-class, adapter-backed tool.
openspec initgenerates OpenSpec commands under.commandcode/commands/opsx-<id>.md(invoked as/opsx-<id>) alongside the skills under.commandcode/skills/, matching Command Code's documented custom-slash-command surface.
- Command Code command adapter — Command Code is now a first-class, adapter-backed tool.
-
#1613
42d7f67Thanks @Angelthebestone! - ### New Features- Command Code support —
openspec initnow supports Command Code as an adapterless skills-only tool. It installs the OpenSpec skills under.commandcode/skills/and invokes them as/openspec-*commands, matching Command Code's native skill surface.
- Command Code support —
-
#1604
83be9d1Thanks @clay-good! - Addopenspec validate --archived: an opt-in check that every change underchanges/archive/has all of itstasks.mdcheckboxes ticked, exiting non-zero if any are unchecked. This surfaces changes that were archived with unfinished work — which the normal validate flow never catches, because it only looks at active changes — and is meant for a pre-commit or CI hook (#205). It is a standalone scope: it does not alter any existingvalidateinvocation and does not re-validate already-applied spec deltas.
Patch Changes
-
#1530
bf5099eThanks @clay-good! - Apply workflow now tells agents to surface unexpected scope instead of hiding it. When a task needs work beyond what the spec describes, the/opsx:applyskill and command guidance direct the agent to pause and report the added scope rather than silently narrowing, deferring, or simplifying away specified behavior, and to mark a task complete only when its specified behavior is fully implemented. Fixes #1529. -
#1603
9ae75c8Thanks @clay-good! -openspec archiveno longer writes terminal escape codes to a redirected or captured stdout. Its confirmation prompts and the no-argument change picker drew their live UI with ANSI cursor-move sequences even when stdout was not a terminal — noise in a redirected log, and in some non-interactive hosts an unbounded render loop that could grow the captured output until the disk filled. When stdout (or stdin) is not a terminal, archive now reads the confirmations as plain text, and a no-argument run asks you to pass a change name up front instead of drawing a menu. Piped answers (printf 'y\n' | openspec archive …) and--yesbehave as before, and interactive terminals are unchanged. Fixes #1526. -
#1528
9425897Thanks @Marzx13! - Canonicalize rebuilt specs to end with exactly one final LF. Previously a spec whose## Requirementssection was last was rebuilt with a trailing blank line (\n\n), which failed Markdown whitespace checks after sync or archive. Internal spacing and content after the Requirements section are unchanged. -
#1640
610b78fThanks @clay-good! - Preserve the blank lines around a spec's## Requirementsheading when syncing a delta.openspec archiverebuiltopenspec/specs/<capability>/spec.mdby joining its slices with a bare newline, so the blank lines that surround the heading were dropped and the resulting file failed Markdown whitespace checks. The rebuild now keeps that spacing intact. Fixes #1625. Thanks @jwang513! (#1637) -
#1640
610b78fThanks @clay-good! -openspec validate --allandopenspec list --jsonno longer silently pass when run outside an OpenSpec project. From a directory with no root they used to resolve the current directory as an implicit root, exit 0, and report empty results — a false pass for CI and agents. Bulk validation (--all,--changes,--specs) andlistnow require an existing root (theopenspec/project.mdfallback for legacy projects is kept), while direct validation and other intentional implicit-root workflows are unchanged. Thanks @clay-good! (#1612) -
#1640
610b78fThanks @clay-good! - Label theupdateworkflow in theopenspec configworkflow picker. The checklist had friendly labels for 11 of the 12 workflows but was missingupdate, so that row — one of the six core workflows every user sees — fell back to its raw id with a placeholder description. The update-change template's stale "expanded-profile" wording is also reworded to "optional". Fixes #1627. Thanks @clay-good! (#1632) -
#1640
610b78fThanks @clay-good! -openspec schema forknow preserves the source schema's YAML formatting. Renaming a forkedschema.yamlround-tripped through a parse/re-serialize step that dropped comments, could rewrite block-scalar style (a literal|folded to>), and reordered keys, so the fork no longer matched its source. The rename now edits the document in place via the YAML Document API, leaving comments, scalar style, and key order untouched. Thanks @clay-good! (#1607) -
#1640
610b78fThanks @clay-good! -openspec schemasnow resolves through the canonical OpenSpec root-selection precedence instead of always reading from the current directory. It accepts--store <id>, rejects--store-pathlike the other store-aware commands, and returns the shared machine-readable diagnostics on JSON failures, while preserving the existing human output and bare JSON array on success. Thanks @Patodo! (#1616) -
#1640
610b78fThanks @clay-good! -openspec validatenow warns on ambiguous task numbering inspec-drivenchanges: a task ID duplicated at full depth (including across resolved task files), or a task whose leading number disagrees with its enclosing## N.group. Numeric-looking text outside numbered groups is ignored, and custom schemas are unchanged until they opt in. The checks run across direct, bulk, and deprecated change validation. Closes #1520. Thanks @alectimison-maker! (#1523) -
#1522
07dea6eThanks @clay-good! - ### Bug Fixes- Don't let a legacy Codex upgrade hijack the vendor-neutral
agentstarget —openspec updateno longer overwrites an existing.agentsskills tree (and its ownership marker) when Codex is detected only from leftover global~/.codex/prompts. Because Codex and the vendor-neutralagentstarget share.agents/skills, a project that used theagentstarget could have its generic skills silently rewritten with Codex-specific syntax and its target flipped to Codex on the nextupdate --force. The legacy-upgrade path now respects the established owner of a shared skills directory, matching the one-writer ruleopenspec initalready applies. When an upgrade is skipped this way, that tool's repo-local legacy files (e.g..codex/prompts/openspec-*.md) are also preserved rather than cleaned up, since no replacement was written to take their place. A genuine first-time Codex upgrade (no.agentstree yet) is unaffected.
- Don't let a legacy Codex upgrade hijack the vendor-neutral
-
#1521
c751b3dThanks @clay-good! - ### Bug Fixes- Stop silently dropping unlabeled scenarios on archive —
openspec validateandopenspec archivenow recognize every level-4 (####followed by whitespace) child of a requirement as a scenario, matching how the spec is counted elsewhere. Before, the scenario-loss guard only recognized headers written exactly as#### Scenario:, so aMODIFIEDrequirement that dropped a differently-labeled child (for example#### Edge case) passed validation and was then permanently deleted by archive with no warning. Both paths now agree, so the loss is caught at authoring time. Scenario names are normalized when comparing (an optionalScenario:prefix and a CommonMark closing#run are ignored), so simply relabeling a scenario is not mistaken for dropping one.
- Stop silently dropping unlabeled scenarios on archive —
-
#1610
17581c1Thanks @clay-good! - ### Bug Fixesopenspec initnow suggests an IDE restart only when an IDE-resident tool such as Cursor, GitHub Copilot, Continue, or Cline was configured. CLI tools like Claude Code, Codex, and Gemini CLI no longer show the hint, since their commands work as soon as the files exist.
-
#1609
804427bThanks @clay-good! - Suppress the first-run telemetry disclosure notice when--jsonis used. On a first-ever run the notice was written to stdout and could break--jsonconsumers; it is now deferred to the first later non-JSON run, keeping--jsonoutput valid while still guaranteeing the disclosure.
1.8.0
Minor Changes
-
#1303
1aa0f2aThanks @solanab! - Add the vendor-neutralagentstarget:openspec init --tools agentsinstalls the workflow skills to.agents/skills/openspec-*/SKILL.md, the shared location AGENTS.md-compatible assistants read. It is skills-only, so no slash commands are generated. Becauseagentsis now a real target,--tools allincludes it and creates.agents/skills/where it previously did not. -
#1274
7a4a745Thanks @NicoAvanzDev! - Generate GitHub Copilot coding agent setup and custom agent files duringopenspec initand keep them synchronized duringopenspec update. -
#1214
161f945Thanks @showms! - Add MiniMax Code as a global skills-only tool target. -
#1518
568e56cThanks @clay-good! - ### New Features- Atlassian Rovo Dev CLI —
openspec init --tools rovodevinstalls the OpenSpec workflow skills for Atlassian's Rovo Dev CLI. It is skills-only (no slash commands), written to.rovodev.
Bug Fixes
- Codex skills now live in the shared
.agentsdirectory —openspec initandopenspec updateinstall Codex skills under.agents/skills/(the canonical location assistants read) and migrate an existing.codexskills directory in place. Files you customized are preserved, not overwritten. openspec statusseparates planning from implementation — status now reportsisPlanningComplete(every non-skipped planning artifact exists; skipped artifacts count as satisfied without being written) distinctly from overall progress, and its messages no longer imply a change is finished before it has been implemented.isCompleteis kept as a compatibility alias, so existing scripts keep working.
- Atlassian Rovo Dev CLI —
-
#1517
73207a6Thanks @clay-good! - Make GitHub Copilot cloud coding-agent files opt-in. Selecting thegithub-copilottool no longer silently writes a GitHub Actions workflow into.github/;openspec initnow asks first (default No) and remembers the choice inopenspec/config.yaml(githubCopilot.cloudAgent). Use--copilot-cloud/--no-copilot-cloudto decide non-interactively.openspec updatenever prompts — it only refreshes cloud files for projects that opted in (or that already have generated cloud files, so existing setups keep working).- Opting out (
--no-copilot-cloudorcloudAgent: false) removes OpenSpec-managed cloud files; a user-customized file is always preserved, never overwritten or deleted. initandupdatenow report whether cloud files were written, skipped, or left untouched — and if you already have your owncopilot-setup-steps.yml, they say it was preserved and that you need to add the OpenSpec install step by hand.
-
#1484
521ee33Thanks @clay-good! - Retire a capability when a change removes its last requirement. A change that declaresretire_capabilities: truein its.openspec.yaml(alongside theschema:that file requires) may now be archived even when its REMOVED entries take a capability's last requirement:openspec archivedeletes that capability's main spec instead of aborting with "Spec must have at least one requirement". Without the marker nothing changes — the archive aborts exactly as before, except the message now names the marker as the way out. Retirement happens only when the emptied spec could not have been written at all, every one is named in the archive output, a pasteablegit checkoutis included when the spec lived in the caller's checkout, and--no-validatenever retires. Archive now also rejects a main spec with duplicate canonical requirement names instead of letting delta reconciliation collapse one of the duplicate blocks. One thing to know before retiring: a capability's spec is the base another change's MODIFIED block is checked against, so an in-flight change that modifies the capability you just retired will keep validating clean and then refuse to archive ("target spec does not exist; only ADDED requirements are allowed for new specs") — close or rework that change alongside the retirement.
Patch Changes
-
#1502
ece8660Thanks @clay-good! -openspec validatenow treats the EnglishSHALL/MUSTconvention as guidance in normal mode, so requirements written in other languages can validate. Strict mode continues to enforce the convention. -
#1483
2b3d368Thanks @clay-good! - Tell the caller which flag to pass whenopenspec archivecannot ask its confirmation questions. An AI agent (or any script) runs the CLI with stdin closed, so every prompt rejects with@inquirer'sUser force closed the prompt with 0 null— the archive aborted with an error that named neither the question nor the flag, and agents burned a turn guessing (#1479). Each confirmation now reports what it needed and a pasteable rerun that carries the flags you already passed:openspec archive <name> --skip-specs --yesstays a--skip-specsrun, so following the suggestion cannot merge specs you opted out of merging, and a change name that needs quoting gets double quotes, the one form bash, zsh, PowerShell and cmd.exe all read the same way (a name no shell reads literally even quoted — one containing$, a backtick, or the%/!that cmd.exe still expands inside quotes — is left as a<change-name>placeholder rather than a command that would target something else).openspec archivewith no change name used to swallow the same failure, printNo change selected. Aborting.and exit 0 — success for a run that archived nothing; it now exits 1 asking for a change name, matching howopenspec showandopenspec validatealready behave without a terminal. The check is reactive — it inspects a prompt that already failed — so answers piped into the command,--yes,--json, and Ctrl-C all behave exactly as before, and a run that OpenSpec already considers non-interactive (CI,OPEN_SPEC_INTERACTIVE=0,--no-interactive) gets the guidance even when the runner allocated a pty. The onboarding walkthrough, the only generated guidance that tells an agent to runopenspec archive, now shows--yes. -
#1486
427abf4Thanks @clay-good! - Task progress now counts indented sub-tasks. Atasks.mdwhose sub-tasks were unfinished reported✓ Completeinopenspec listandopenspec view, was missing those tasks from theopenspec instructions applylist, and archived with no incomplete-task warning, because both checkbox parsers only matched checkboxes at column 0.Progress counting and the apply task list now share one parser, so
list,view,archiveandapplyagree about which lines of a tasks file are tasks. A checkbox with no text after it is left out of the apply list, which has nothing to act on, but still counts toward every progress number; a file of nothing but such checkboxes now asks to be rewritten rather than reporting itself done. The shared pattern matches every line the two it replaced matched, and more, so task counts can rise but never fall: no change starts reporting less work than before, and archive's incomplete-task warning can only become stricter. Checkboxes are still counted wherever they appear, including inside a code fence, an HTML comment or an indented block, so atasks.mdthat shows a checklist as a format example can now count that example as work — remove it from the file, or pass--yesto archive. -
#1500
26bd1d4Thanks @clay-good! - Keep generated workflows on the selected store, handle optional workflow fallbacks safely, and validate synced specs before reporting success. -
#1490
45cca5dThanks @clay-good! - Say before confirmation when archiving a change will delete a note written next to a requirement. A requirement absorbs anything below it that OpenSpec doesn't recognize as a new heading — a note indented by the one to three spaces Markdown allows, for example — so removing or modifying that requirement took the note with it, silently.openspec archivenow names content the rebuilt spec would actually drop and where to move it to keep it. The merge itself is unchanged: nothing is relocated, because a#line inside a scenario looks identical to a note and moving one of those would rewrite the spec wrongly. -
#1492
690a27eThanks @mc856! -openspec initandopenspec updateno longer delete the CoStrict and Junie command files they just generated. Legacy cleanup removes artifacts older OpenSpec versions left behind, and two of its patterns named paths the current adapters still write to. CoStrict's was a whole-directory removal of.cospec/openspec/commands/, the folder the adapter writesopsx-<id>.mdinto, so every run wiped the directory — including any file the user kept there — while the banner above it readNo user content to preserve. Junie's.junie/commands/opsx-*.mdlisted its own current output. Cleanup runs before the config migration, so on a config that has noprofilekey yet the missing command files make delivery detection read the project as skills-only and persist that to the global config: the files are not regenerated, and the preference changes for every other project too.CoStrict is now a file pattern,
.cospec/openspec/commands/openspec-*.md, matching the three commands the pre-opsxCoStrict integration wrote there (openspec-proposal.md,openspec-apply.md,openspec-archive.md) and the same shape every other file-based tool already uses. Junie's entry is removed outright: Junie support arrived after the slash configurators that wroteopenspec-*files were deleted, so no OpenSpec version ever created those files there. Genuinely legacy files are still detected and removed, and no other tool's patterns change — they never overlapped their adapter's current output. -
#1501
0b20ae3Thanks @clay-good! - Keep the propose workflow focused on planning, clarify material ambiguities before creating a change, and hand implementation off to the apply workflow. -
#1503
8a3850dThanks @clay-good! - When exploration turns into a new change, generated explore guidance now instructs agents to runopenspec new changebefore writing requested artifacts. This preserves the required.openspec.yamlmetadata instead of letting an agent create an incomplete change directory by hand. After the user accepts a capture, explore also creates the requested artifacts without requiring another workflow command. -
#1513
622c509Thanks @FasterPHP! - Honortelemetry.enabledin global config.falsedisables anonymous telemetry andopenspec updateversion checks; unset keeps telemetry enabled, and env/CI opt-outs still take precedence. -
#1499
9cd845fThanks @clay-good! - Keep generated files, specs, archive moves, and local state inside their intended security boundaries without breaking linked monorepo workflows. -
#1482
84ebc57Thanks @clay-good! -openspec validate <change>now reports a MODIFIED requirement that omits a scenario the main spec still has — the same loss archive already refuses to apply — so the change fails at authoring time instead of at archive time. A change carrying a stale MODIFIED block will start failing validation; it was already unarchivable, and the message names the scenarios to copy back in.
1.7.0
Minor Changes
-
#1475
17af60cThanks @clay-good! - Add CodeArts Agent skills support:openspec init --tools codeartsagentinstalls the workflow skills. -
#1475
17af60cThanks @clay-good! - Add Hermes Agent as a supported AI tool:openspec init --tools hermesinstalls the workflow skills (Hermes is skills-only and invokes them directly). -
#1475
17af60cThanks @clay-good! - Add ZCode as a supported AI tool:openspec init --tools zcodegenerates its skills and/opsx:*commands. -
#1475
17af60cThanks @clay-good! - Codex is now skills-only: workflows install as$openspec-*skills and previously managed custom prompts are retired (existing ones are cleaned up on update). -
#1062
eac2973Thanks @showms! - Add current project context and per-operation guidance to apply and archive workflows. Projects can configureoperations.apply.guidanceandoperations.archive.guidance;openspec instructions applyreturns apply inputs, and the new read-onlyopenspec instructions archivesurface returns archive inputs for the selected root.Archive, bulk archive, and sync skills now load current archive inputs and
specsartifact rules at execution time, fail before writes or moves when required instruction lookups fail, and reuse specs-rule snapshots during inline sync. -
#1475
17af60cThanks @clay-good! - Publish the workflow skills as staticskills/<name>/SKILL.mdfiles sonpx skills add Fission-AI/OpenSpecworks. -
#1399
27b22abThanks @clay-good! - Addskip_specs: truechange metadata for work with no spec-level behavior change (pure refactors, tooling, docs).openspec validateaccepts a zero-delta change that declares the marker (honored only when the metadata parses under the shared change-metadata schema and names a schema that loads) and errors when the marker and delta specs are both present, the artifact graph no longer blockstaskson spec files for such changes,openspec statusrenders the specs stage as explicitly skipped, and the propose/specs guidance points to the marker instead of contradicting the validator. -
#1475
17af60cThanks @clay-good! - Resolve symlinked schema directories so schemas shared via symlink (e.g. from a dotfiles repo) are discovered. -
#1470
6295515Thanks @clay-good! -openspec updatenow offers to upgrade the CLI when yours is behind the published one. Instruction files are generated by the installed CLI, so a stale install reported✓ All 1 tool(s) up to date (v1.6.0)while the workflows added in newer releases were never written:A newer OpenSpec CLI is available (v1.6.0 → v1.7.0). Running from: /usr/local/lib/node_modules/@fission-ai/openspec ? Upgrade to v1.7.0 now? (Y/n)Say yes and it upgrades, confirms the new version is the one that answers, then re-runs the update so the new workflows arrive in the same command. Say no and it prints the command matching how you installed OpenSpec, and updates with what you have. Nothing happens to your machine that you did not agree to: the offer appears only in an interactive terminal and only where
npm install -gwould help, and the check is skipped in CI or whenOPENSPEC_NO_UPDATE_CHECK,DO_NOT_TRACK=1, orOPENSPEC_TELEMETRY=0is set.See CLI reference →
openspec updatefor the per-install-method behavior and every opt-out.
Patch Changes
-
#1404
a84ae70Thanks @clay-good! - Generated skills for tools without a command adapter (Kimi Code, Mistral Vibe, Hermes, ForgeCode, CodeArts) no longer reference/opsx:*commands that were never generated: skill cross-references, the init getting-started hint, and the profile-migration message now use each tool's documented skill invocation (Kimi Code:/skill:openspec-*; others:/openspec-*), and Codex — skills-invocable with no slash surface — gets a syntax-neutral hint that names the skill. Selections that mix invocation syntaxes print one labeled hint per distinct form, so every advertised instruction is usable by the tool it names. Whendelivery: commandswould generate nothing for a selected tool, init prints a configuration correction naming that tool, even when other tools did get commands or skills. The committed skills.sh distribution is regenerated with skill references (default/openspec-*form, as that channel installs skills only). -
#1363
5199f41Thanks @clay-good! - ### Features- One default store for every repo on your machine —
openspec config set defaultStore <id>sets a machine-level fallback root: any command run outside a planning root, with no--storeflag and no projectstore:pointer, resolves to that store. It sits at the bottom of the precedence list, so--store, a local root, and a project pointer all still win. The root banner and JSONrootblock report the distinct provenancesource: "global_default", so users and tooling can tell a machine-wide default from a repo's own pointer. A stale id degrades to the underlying store error with a fix that namesopenspec config unset defaultStore.
- One default store for every repo on your machine —
-
#1435
6a5171eThanks @clay-good! -openspec new changenow accepts numeric-prefixed names like100-add-featureor00001-add-auth, useful for ordering or tiering changes. Change names now use the same kebab-case grammar as store ids and change metadata (a leading digit is allowed);archivealready treated date-prefixed names as a supported convention. Uppercase, spaces, underscores, and leading/trailing or consecutive hyphens are still rejected, and every previously valid name stays valid. -
#1425
040a869Thanks @clay-good! - Compare config key guards literally instead of through a helper.setNestedValueanddeleteNestedValuerejected prototype-reaching key segments through a helper that did aSetlookup. That is correct, but static analysis could not follow it, so CodeQL kept reporting prototype-pollution on the very assignments the guard protects. The segments are now compared literally in the same function, still checked across the whole path before anything is written. Behavior is unchanged for every input, verified against the previous implementation across 400,000 generated cases. -
#1431
6a4f0d7Thanks @clay-good! - A delta spec that introduces a brand-new capability can now open with a## Purpose, andopenspec archiveuses it as the Purpose of the main spec it creates instead of writing theTBD - created by archiving change <name>. Update Purpose after archive.placeholder over it. Thespecsartifact instruction, its example, the delta template and theopenspec-sync-specsskill all tell authors and agents to write one, so the CLI and agent-driven sync paths produce the same main spec.Archive keeps the placeholder when the delta has no usable
## Purpose:- no
## Purposeheader outside a code fence or HTML comment, or a body that is only a code fence or only a comment - a body that would leave a spec its own parser cannot read — a heading or requirement header that truncates a section, an unterminated fence, or any HTML comment
- in the second case archive also says why, and still completes rather than aborting
A carried Purpose under 50 characters is kept but warned about, since
openspec validate --strictreports it as too brief. The Purpose of an existing main spec is never touched; archive warns when it ignores a delta's Purpose there. - no
-
#1437
19d4171Thanks @clay-good! -openspec archiveno longer aborts when a REMOVED delta's requirement is already gone from the main spec (the early-sync pattern the sync skill teaches): it warns, treats the removal as already applied, and reports applied-only totals. In--jsonmode those warnings are carried in a new optionalwarningsarray on the archive result. When every operation for a spec was already synced, archive skips rewriting that file instead of churning normalization differences into it. A delta that both RENAMEs and REMOVEs the same requirement is now rejected explicitly, by bothvalidateandarchive— the two spellings are compared case- and whitespace-insensitively — and a REMOVED header that differs only in case or whitespace from an existing requirement still aborts (that is a typo, not an early sync). Also fixed: the archive delta gate matches section headers case-insensitively like the parser; symlinkedspecs/<capability>/spec.mdfiles are discovered instead of silently dropped;openspec show <change>no longer prints a spurious "scenarios" flag warning; files generated for qwen and bob reference commands by their real hyphenated names (/opsx-<id>), and init's getting-started hint follows suit; apply/update/onboard guidance names the CLI fallback for profiles that don't install/opsx:continueor/opsx:new. -
#1411
c439a4eThanks @clay-good! - Fix phantom requirements parsed from delta specs, which madeopenspec archivewarn about problemsopenspec validatenever reported.A header inside a delta section that is not a
### Requirement:header — a divider such as### Documentation Requirements— was read as a requirement with no scenario.openspec archivewarned that it was missing a scenario, andopenspec show <change> --jsonandopenspec change listcounted it as an extra delta. The change parser now ignores those headers, matching the delta reader, so the phantom is gone from the warnings and from the JSON. Main spec parsing is unchanged.openspec archivealso no longer repeats requirement-level issues from the delta specs in its non-blocking "Proposal warnings in proposal.md" block. Each defect was printed twice there, and a## REMOVED Requirementsentry — names-only by design — was reported as missing a scenario on every correct removal. Delta spec validation still reports and blocks on genuine defects, and proposal-level warnings are unchanged. -
#1394
b474f81Thanks @clay-good! - ### Bug Fixes- Archive no longer races the spec sync, or reports a sync that never landed — the generated
openspec-archive-changeskill (and the matchingopsx:archivecommand) handed the spec sync to a background task and then moved the change folder immediately. The archive could move the delta specs out from under the running sync: the change ended up archived,openspec/specs/was never updated, and the summary still reportedSpecs: ✓ Synced. The sync now runs inline, and the archive only proceeds once every capability with a delta spec has been checked against it — ADDED present, MODIFIED changes applied, REMOVED gone, RENAMED under the new name and not the old. If the sync fails or a capability doesn't match, the archive stops and reports what differs instead of claiming success; nothing has moved, so you can fix it and retry.
- Archive no longer races the spec sync, or reports a sync that never landed — the generated
-
#1475
17af60cThanks @clay-good! - Apply profile changes with the installed CLI instead of shelling out tonpx, which could run a different version. -
#1475
17af60cThanks @clay-good! - Delta and main-spec parsers strip a UTF-8 BOM, so files saved by Windows editors or PowerShell redirects no longer fail with "No delta sections found". -
#1398
97d441aThanks @clay-good! - ### Bug Fixes- Bulk archive now stops when you pick "Cancel" — the generated
openspec-bulk-archive-changeskill (and the matchingopsx:bulk-archivecommand) offered a "Cancel" option at the confirmation prompt but never told the agent what to do with it, so the next step archived every selected change anyway. The prompt now routes each answer by intent: "Cancel" stops without archiving anything, the archive options proceed (the ready-only option archives just the changes the status table marksReadyorReady*), and any other answer re-asks instead of archiving. The single-change archive skill already routes Cancel this way; this brings the bulk variant in line.
- Bulk archive now stops when you pick "Cancel" — the generated
-
#1375
52a8bceThanks @clay-good! ---changenow accepts any change name that exists on disk (e.g. date-prefixed names like2026-07-04-voice-copilot-v1), matching whatlist,validate, andarchivealready resolve. Lookup still rejects unsafe names (path separators,.., hidden entries); the kebab-case naming rule still applies when creating a change. -
#1475
17af60cThanks @clay-good! -openspec new changerejects names over 200 characters with a validation message instead of surfacing a raw ENAMETOOLONG filesystem error. -
#1447
fb19699Thanks @hsusul! - Generated tool command files now carry valid YAML frontmatter for every supported tool. Command names ship asOPSX: Explore, and the unquotedname: OPSX: Explorethat adapters emitted is not parseable YAML — strict parsers rejected the whole file, so the command failed to load. Several adapters also re-implemented their own escaping, and a few interpolated descriptions in raw.Escaping now lives in one place (
escapeYamlValue/formatTagsArray) and every adapter uses it. String frontmatter values are always double-quoted, which also keeps values liketrue,nulland123from round-tripping as booleans, nulls and numbers. Non-string fields such asallowed-toolsandinvokableare unchanged. Expect the firstopenspec updateafter upgrading to rewrite the frontmatter lines of your generated command files.Archive workflow guidance also gets two corrections: bulk archive now carries its per-delta include/exclude decisions into execution, so a delta whose implementation was not found is reported as
sync skippedinstead of being synced anyway, and both archive workflows verify the main specs before moving the change directory. -
#1471
9a937cbThanks @clay-good! - Reference slash commands by the name each tool actually registers. Command bodies, generatedSKILL.mdcross-references, and theinit/update/migration hints all advertised/opsx:<id>, but only 7 of the 28 tools with a command adapter register that name — the ones whose files sit in anopsx/directory. The other 21 write.../opsx-<id>.md, where the filename is the command, so tools such as Cursor, GitHub Copilot, Windsurf and Kilo Code were told to type a command their palette never had; a single generated Cursor file named itself/opsx-applyin frontmatter and then told the reader to run/opsx:apply. The command name is now derived from the command file each adapter writes rather than a hand-maintained tool list, so a newly added adapter cannot drift, and the wrapper around it is adapter metadata: Amazon Q loads its files into a prompt library invoked with@, so it now gets@opsx-<id>in command bodies, skills, and the onboarding hint instead of a slash command it never registers. Codex, which generates no command files at all, now gets$openspec-<skill>— the syntax its CLI actually accepts — everywhere it previously advertised/opsx:*, superseding the syntax-neutral hint described in the pendingadapterless-skill-referencesnote. Command filenames and paths are unchanged, and Claude Code output is byte-identical. -
#1364
f58b445Thanks @clay-good! - Fixopenspec completion installdetecting the wrong shell for fish (and other) users whose interactive shell differs from their login shell. Detection now consults the parent process before falling back to$SHELL, so running the command from fish installs fish completions instead of defaulting to bash. -
#1377
285dfd7Thanks @clay-good! - ### Bug Fixes- Config
rules:keys are no longer reported asUnknown artifact IDwhen they belong to a different schema. The global rules map is now validated against the union of artifact IDs across every available schema, so multi-schema projects stop seeing spurious warnings on every command (#1322).
- Config
-
#1401
b33b15dThanks @clay-good! - Stopdesign.mdfrom restating the proposal. In the defaultspec-drivenschema, the design instruction asked for "Background, current state, constraints, stakeholders" and "What this design achieves and excludes" without saying that motivation and scope already live inproposal.md, so agents restated the proposal's Why and What Changes instead of adding the design's own value - approach, alternatives, and trade-offs. The instruction and the design template now state the boundary explicitly (the proposal covers why and what, design covers how) and tell the agent to reference those documents rather than repeat them (#1382). -
#1167
1637856Thanks @mehdishahdoost! - Windsurf is now Devin Desktop. Windsurf was rebranded on June 2, 2026 and its config directory moved:.devin/is the preferred read + write location,.windsurf/a legacy read-only fallback that the Devin Local agent does not read at all. OpenSpec follows the rename rather than carrying two ids for one product — the tool id isdevin, writing.devin/workflows/opsx-<id>.mdand.devin/skills/openspec-*/SKILL.md, and it is detected from either directory.--tools windsurfstill resolves, so existing setup scripts keep working; it now configures.devin/.- If your OpenSpec files are still in
.windsurf/,openspec updateexplains the rebrand and offers to move them.--forceand non-interactive runs take the move; declining leaves every file exactly where it is. Only the files OpenSpec generates move — each skill'sSKILL.mdand commands namedopsx-*. A hand-written Cascade workflow, a reference file you keep beside aSKILL.md, a command file you edited, and.devin/rules/all stay exactly where they are. - Devin skills and the getting-started hint reference
/openspec-*skills rather than/opsx-*workflows, because only Devin Desktop reads workflows; the/openspec-*form works on both agents. Workflow bodies still use/opsx-<id>, the name Devin registers for a workflow file.
-
#1475
17af60cThanks @clay-good! -openspec doctornow notes when a store checkout is behind its upstream ref. -
#1475
17af60cThanks @clay-good! - Make the archive scenario-drift check multiplicity-aware: a MODIFIED block that keeps only one of two same-named scenarios no longer silently drops the other. -
#1408
378d468Thanks @clay-good! - Explore now reads the project's context and rules fromopenspec/config.yaml(orconfig.yml) at the start of a session, so it reasons with the same tech stack and conventions the artifact-creating workflows already receive. -
#1475
17af60cThanks @clay-good! -openspec feedbackshows the formatted text and a pre-filled submission URL on any gh failure (issues disabled, network, rate limit), not only when gh is missing or unauthenticated. -
#1396
60f720cThanks @clay-good! - Fixopenspec feedbackfailing when the repository does not define thefeedbacklabel. The command now retries without the label and notes that it was not applied, instead of exiting with an error and discarding the feedback. -
#1151
18cbf5dThanks @javigomez! - ### Fixed- Ignore Markdown structure (requirement headers, delta sections, scenarios, REMOVED/RENAMED entries) that appears inside fenced code blocks when parsing delta specs. Previously a fenced
### Requirement:example was parsed as a real (phantom) requirement, producing spuriousvalidateerrors and risking incorrectarchiveoutput. Fenced-code detection is now shared across the Markdown parsers sovalidateandarchivebehave consistently.
- Ignore Markdown structure (requirement headers, delta sections, scenarios, REMOVED/RENAMED entries) that appears inside fenced code blocks when parsing delta specs. Previously a fenced
-
#1475
17af60cThanks @clay-good! - The archive scenario-drift check now ignores#### Scenario:lines inside fenced code blocks, matching validate: a fenced example no longer false-aborts an archive, and a fenced name no longer masks a genuinely dropped scenario. -
#1316
9b70481Thanks @mc856! - ### Bug Fixesarchiveno longer stacks a second date prefix — archiving a change whose name already starts with aYYYY-MM-DD-prefix (a common authoring convention) keeps the name as-is instead of prepending today's date. Previouslyopenspec archive 2026-07-04-voice-copilot-v1 --yesproduced2026-07-06-2026-07-04-voice-copilot-v1, and when run on a later day the folder sorted under a day on which the change did not happen. Names without a full date prefix (including partial dates like2026-07-feature) are dated as before, and the naming is now idempotent.
-
#1374
da3907bThanks @clay-good! - fix(completion): make the PowerShell completion script parse and load againThe generated
OpenSpecCompletion.ps1contained 18 emptyswitch ($positionalIndex) { }blocks — emitted for commands whose positionals are allpath-typed (PowerShell completes paths natively, so those cases produce no clauses). A switch with no clauses is a PowerShell parse error ("Missing condition in switch statement clause"), and PowerShell parses the whole file before running it, so the script never loaded and completions never registered. The generator now skips the positional-index block entirely when no positional produces completions, so the script parses clean (18 → 0 errors) and tab completion works. -
#1388
9b5d2cdThanks @mc856! - ### Bug Fixes- Archive workflow templates no longer teach agents to stack a second date prefix — the
openspec-archive-changeandopenspec-bulk-archive-changeskill/command templates (and the onboarding walkthrough's archived-path example) now mirror theopenspec archiverule: a change whose name already starts with aYYYY-MM-DD-prefix is archived under its own name, while other names get the current date prepended as before. Previously an agent following the workflow instructions on a change named2026-07-04-voice-copilot-v1producedarchive/2026-07-07-2026-07-04-voice-copilot-v1, whatever the CLI did.
- Archive workflow templates no longer teach agents to stack a second date prefix — the
-
#1475
17af60cThanks @clay-good! - Gemini command files escape TOML-active characters (quotes, backslashes, control characters) in the description and prompt, so a template value containing them can no longer produce an invalid.tomlfile. -
#1464
5bcf057Thanks @clay-good! - Workflow skills and commands no longer tell agents to use the Claude Code-only AskUserQuestion tool. The same templates are generated for every supported tool, and agents without that tool (OpenCode, Factory Droid, Codex, and others) errored or stalled on the instruction. The guidance is now runtime-neutral: agents are simply told to ask the user. -
#1403
2d6c447Thanks @clay-good! - ### Bug Fixes- Propose and fast-forward skills no longer name the Claude-only TodoWrite tool — the generated
openspec-proposeandopenspec-ff-changeskills (and their/opsx:propose//opsx:ffcommands) told every agent to "Use the TodoWrite tool", which only exists in Claude Code. Codex, Cursor, Gemini, Copilot, and the other supported tools have no such tool, so agents either errored or stalled looking for it. The instruction is now runtime-neutral ("Use a todo list to track progress"), which works everywhere — including Claude Code.
- Propose and fast-forward skills no longer name the Claude-only TodoWrite tool — the generated
-
#1415
e2f748cThanks @clay-good! - Reject config key paths that reach the prototype chain, and update the bundledyamldependency.openspec config set --allow-unknown __proto__.polluted <value>reported success and assigned ontoObject.prototypefor the rest of the process.--allow-unknownwas meant to relax the known-key check only, but it skipped every key check, so__proto__,constructor, andprototypesegments reached the nested-write helper. Those segments are now rejected inconfig setwhether or not--allow-unknownis passed, andsetNestedValue/deleteNestedValuerefuse them regardless of caller. Ordinary keys such asfeatureFlags.myFlagbehave exactly as before.The
yamlruntime dependency moves from 2.8.2 to 2.9.0, picking up the fix for a stack overflow on deeply nested input (GHSA / advisory patched in 2.8.3). -
#1376
7958924Thanks @clay-good! - ### Bug Fixes- Archive after early sync —
openspec archiveno longer fails withADDED failed … already existswhen a change's specs were already synced to the main specs before archiving (the early-sync pattern from thesyncworkflow). If an ADDED requirement already exists in the target spec with identical content, applying it is treated as a no-op; a same-named requirement with different content still aborts the archive as a genuine conflict (#1332).
- Archive after early sync —
-
#1386
b419e96Thanks @mc856! - ### Bug Fixes- Archive after early sync (RENAMED) —
openspec archiveno longer fails withRENAMED failed … source not foundwhen a change's renames were already synced to the main specs before archiving (the early-sync pattern from thesyncworkflow). If a RENAMED requirement's source header is gone but the target header exists in the spec, applying the rename is treated as a no-op; a rename whose source and target are both missing still aborts the archive as a genuine error, and reported counts reflect only renames actually applied.
- Archive after early sync (RENAMED) —
-
#1462
ebf66c7Thanks @clay-good! - Respect reduced-motion preferences inopenspec init: the welcome animation is skipped when the OS reduced-motion setting is on (macOS Reduce Motion, GNOME animations disabled), whenOPENSPEC_NO_ANIMATIONis set, or when the new--no-animationflag is passed. The static welcome screen is shown instead. -
#1405
5dfef4bThanks @clay-good! - ### Bug Fixes- Custom schema instructions are no longer overridden by hard-coded spec-driven patterns — the
openspec-continue-changeskill/command embedded one-line "common artifact patterns" for proposal.md, specs, design.md, and tasks.md, so agents followed those shortcuts instead of the schema'sinstructionfield whenever a custom schema reused familiar artifact names. The templates now state that theinstructionfield is the authoritative guidance, and thepropose,continue, andffworkflows direct the agent — both in the artifact-creation step and in the guidelines — to invoke a skill when the instruction delegates artifact creation to one, verifying the artifact exists afterward (fixes #777).
- Custom schema instructions are no longer overridden by hard-coded spec-driven patterns — the
-
#1475
17af60cThanks @clay-good! - Follow the Kimi CLI rename to Kimi Code: new install paths with automatic migration of existing.kimisetups. -
#1415
e2f748cThanks @clay-good! - Parse spec headings in linear time when the title is padded with whitespace.Building the reference index read the first Purpose line with a regex that backtracked quadratically on a heading full of spaces: 10,000 characters of padding took 60ms, and 100,000 would have taken roughly six seconds. The heading scan is now hand-rolled and linear. Behavior is unchanged — the replacement was checked against the old implementation across 303,000 generated inputs, including CommonMark closing sequences (
## Purpose ##), seven-hash lines, and headings with no space after the hashes. -
#1475
17af60cThanks @clay-good! - Use local dates for CLI date-only values (archive names, timestamps) instead of UTC, so late-evening archives no longer get tomorrow's date. -
#1475
17af60cThanks @clay-good! -openspec updatewarns when a custom profile is missing core workflows instead of silently generating a partial install. -
#1428
81d5109Thanks @taltas! - Update current Roo Code product references to its community successor, Zoo Code. -
#1475
17af60cThanks @clay-good! - Archive treats a MODIFIED delta whose content already matches the main spec as a no-op: a fully early-synced change now reports "Specs already in sync" instead of rewriting the file and claiming modifications. -
#1475
17af60cThanks @clay-good! - Render multi-select prompts with[x]/[ ]checkbox markers instead of radio-button icons. -
#1475
17af60cThanks @clay-good! - Discover nested spec paths likespecs/<area>/<capability>/spec.mdrecursively and consistently across parse, apply, and archive. -
#1410
b3b05e1Thanks @clay-good! - Only advertise onboarding commands that will actually exist. Theopenspec initwelcome screen and theopenspec update"Getting started" summary listed/opsx:newand/opsx:continue, which the defaultcoreprofile never generates, so users were told to run commands that did not exist. Both surfaces now list the commands for the installed workflows. Theinitandupdatecompletion hints also name the skill (/openspec-propose) instead of a command for tools that receive no command files — Codex, and any tool under skills-only delivery. -
#1412
1dc670dThanks @clay-good! - ### Fixed/opsx:proposeand/opsx:ffno longer finish a change with no spec written. The workflows listed onlyproposal/design/tasksand treated the apply phase'stasksartifact as the stop condition — butstatusmarks an artifactdoneas soon as a matching file exists, so writingtasks.mdearly satisfied the loop whilespecs/<capability>/spec.mdwas never created (a spec-less change in a spec-driven tool). The loop now derives the full required set — every apply dependency plus everything it transitivelyrequires— from a singlestatuscall, creates each missing artifact, and only skips one when its owninstructionfield marks it conditional. (#1260, #788)
Changed
openspec status --jsonnow reports each artifact'srequiresedges. Every entry in theartifactsarray carries arequiresarray of the ids it directly depends on, present for every status (includingdone) so agents can compute the transitive required set fromstatusalone. Additive and backward-compatible — existing fields are unchanged.
-
#1191
7704702Thanks @mc856! - Generate Markdown commands for Qwen Code instead of deprecated TOML format. Qwen Code now recommends Markdown custom commands with YAML frontmatter; the old.qwen/commands/opsx-*.tomlfiles are cleaned up as legacy artifacts on update. -
#1475
17af60cThanks @clay-good! - An already-synced RENAMED delta aborts when a case/whitespace variant of the source requirement still exists — the same typo guard REMOVED deltas have. -
#1368
de78c31Thanks @clay-good! - ### Fixes- Regenerated artifacts now pick up your manual edits — the continue, propose, and fast-forward workflows (and the
openspec instructionsdependency block) now tell the agent to re-read dependency artifacts from disk before creating the next one, instead of trusting whatever version it saw earlier in the conversation. Previously, editingspec.mdand deletingdesign.md/tasks.mdto regenerate them could silently produce artifacts based on the stale, pre-edit content.
- Regenerated artifacts now pick up your manual edits — the continue, propose, and fast-forward workflows (and the
-
#1475
17af60cThanks @clay-good! - Proposal guidance now resolves blocking open questions with the user instead of deferring them to design.md. -
#1392
a13abeaThanks @clay-good! - ### Fixed- Stop a delta spec written directly at a change's
specs/root from being silently dropped.validateacceptedspecs/spec.mdand counted its deltas, but the apply/archive merge only reads capability folders (specs/<capability>/spec.md), so the change could pass validation and be archived while its requirements never reachedopenspec/specs/.validatenow uses the same discovery rules as the merge path and reports the misplaced file with a fix hint, andarchiveblocks instead of completing.
- Stop a delta spec written directly at a change's
-
#1465
f917b8bThanks @clay-good! - Order artifacts by the schema's declaration order instead of alphabetically.specsanddesignboth require onlyproposal, so both become ready at once - and the tie used to be broken alphabetically, which putdesignfirst.openspec statuslisted design above specs andnextStepsrecommended writingdesign.mdbefore any spec existed, contradicting the spec-driven schema's own documentedproposal → specs → design → taskssequence.Ties now follow the order the schema declares its artifacts, so
openspec status,status --json,nextSteps,blocked by:lists, and an artifact'sunlocksall agree. No dependency edges changed, so nothing newly blocks anddesign.mdstays optional - only the order of equally-ready artifacts moved. Custom schemas get the same guarantee: dependency order still comes first, but wherever your schema leaves two artifacts equally ready, the order of itsartifacts:list now decides which one the CLI recommends - so reorder that list if it was never deliberate. -
#1446
5348da9Thanks @showms! - ### Bug Fixes- Preserve an existing project-local schema when
openspec schema init --forcerejects an unknown artifact ID. Forced replacement now begins only after artifact validation succeeds.
- Preserve an existing project-local schema when
-
#1433
26f009dThanks @clay-good! - Change lookup no longer requiresproposal.md.openspec show,openspec change list/show/validate, and shell completion now resolve a change by its directory, matchingopenspec list,status,instructions, andvalidate.Previously a change created by
openspec new change— which scaffolds only.openspec.yaml— was reported asUnknown itembyopenspec showand was missing from completions andopenspec change listuntil a proposal was written, and a change from a schema with no proposal artifact was never resolvable.openspec change listnow reports the same set asopenspec list, keeps task counts for a change that has no proposal yet, and labels it(no proposal.md yet)rather than(unable to read). Showing such a change explains that the proposal is not written yet and points atopenspec status --change <name>. -
#1468
fc886afThanks @clay-good! - The continue, update, verify, sync, and archive workflow skills now select a change the same way apply does: use the provided name, infer it from conversation context, auto-select when exactly one active change exists, and only prompt when the choice is genuinely ambiguous. Previously these workflows were told to always prompt ("Do NOT guess or auto-select"), so invoking them with a single active change stalled on a question with only one possible answer. The selection is always announced ("Using change: ") with how to override, and bulk archive still always prompts. -
#1194
b7c85c7Thanks @mc856! - Fix skills-only delivery emitting/opsx:*command references. SKILL.md files generated by init, update, and workspace skill setup now reference the corresponding skills (e.g./openspec-apply-change) whendelivery: 'skills'is configured, instead of commands that were never generated. -
#1475
17af60cThanks @clay-good! - Specs instructions include the spec content guidance from the concepts docs, so generated specs follow the requirement/scenario format. -
#1475
17af60cThanks @clay-good! - The static welcome screen (reduced motion,--no-animation, narrow terminals) now waits for the Enter it asks for instead of letting the keystroke submit the tool picker unseen. -
#1475
17af60cThanks @clay-good! - Sync and archive workflows resolve main specs through the store-aware root instead of assumingopenspec/specsin the repo. -
#1402
0da5f98Thanks @clay-good! - Show the main spec format in the sync-specs skill so agents stop leaving delta operation headers (## ADDED/MODIFIED Requirements) inopenspec/specs/— merged main specs with those headers parse as 0 requirements inopenspec view(#1120). -
#1476
8731290Thanks @clay-good! - Telemetry no longer depends onposthog-node: the single usage event is sent with a plain fetch to the same endpoint. Installing OpenSpec no longer pulls the fast-publishingposthog-node/@posthog/core/@posthog/typestree, which broke downstream installs under supply-chain age policies like pnpm'sminimumReleaseAge(#1390). -
#1475
17af60cThanks @clay-good! - The stale-CLI check hardens its install detection: a directory merely namedvoltano longer changes the upgrade hint, the Windows npm-ownership check corroborates against theopenspec.cmdshim npm actually writes, and a registry redirect from https to plain http is no longer followed. -
#1475
17af60cThanks @clay-good! - The stale-CLI check tears down a redirected registry connection when its time budget expires instead of leaving the socket open. -
#1442
10fa39bThanks @hsusul! -openspec updatenow refreshes tools that are configured with command files but no skills (deliverycommands). Previously it read the generating version only from skill files, so such a tool was reported as "up to date" forever and its command files were never regenerated after a CLI upgrade. Command files carry no version stamp, so OpenSpec compares their contents against what it would generate now — including removing a command file left behind by a workflow you have since deselected. CRLF line endings and a UTF-8 BOM are treated as checkout artifacts rather than drift, so a Windows clone does not report a spurious update. -
#1475
17af60cThanks @clay-good! -openspec updatewithdelivery: commandsprints the same configuration correction as init when it removes the skills of a tool that supports only skills, instead of deleting them silently. -
#1475
17af60cThanks @clay-good! -openspec validatereports an unreadable specs/ directory as the error it is instead of misdiagnosing it as "no deltas found". -
#1455
6b3623aThanks @c4patino! -openspec viewnow resolves the configured OpenSpec root instead of always reading the current directory, and accepts--store <id>like its sibling commands. Projects whoseopenspec/config.yamlpoints at an external store saw an empty dashboard — 0 specs, 0 requirements — whileopenspec listread the same store correctly. -
#1475
17af60cThanks @clay-good! - Preserve keyboard input on Windows after the welcome screen instead of dropping the first keystrokes. -
#1475
17af60cThanks @clay-good! - zsh completion install honors$ZSHand$ZSH_CUSTOM, so Oh My Zsh setups at custom locations get the completion where their shell actually loads it.
1.6.0
Minor Changes
-
#1090
3f0ca3fThanks @jjxyxsjr! - ### New Features- TRAE command adapter — Added command adapter for Trae IDE, enabling generation of
.trae/commands/opsx-<id>.mdfiles for custom slash commands
- TRAE command adapter — Added command adapter for Trae IDE, enabling generation of
-
#1340
1552731Thanks @TabishB! - ### New Features- Oh My Pi support — Generate native OPSX commands and skills for Oh My Pi projects, including tool detection and the expected
.ompdirectory layout. - Update planning artifacts in place — Use
/opsx:updateto revise an existing change's planning artifacts, reconcile related artifacts, and keep implementation work delegated to/opsx:apply.
Bug Fixes
- Fresh store registration — Register and use newly created stores before their empty changes, specs, or archive directories have been committed.
- Safer requirement archiving — Stop stale
MODIFIEDrequirements from silently deleting scenarios that were added by an earlier archive.
- Oh My Pi support — Generate native OPSX commands and skills for Oh My Pi projects, including tool detection and the expected
Patch Changes
-
#1300
a5bfedaThanks @clay-good! - ### Features- Auto-approve the OpenSpec CLI in generated skills and commands — every generated
SKILL.md(all tools) and every Claude Code/opsx:*slash command now carriesallowed-tools: Bash(openspec:*)in its frontmatter, so agents that honor the Agent Skills standard runopenspeccommands without prompting for approval on each call; tools that don't recognize the field ignore it. Scope is limited to theopenspecCLI; becauseallowed-toolspre-approves rather than restricts, every other tool a skill or command uses stays available under your normal permission settings.
- Auto-approve the OpenSpec CLI in generated skills and commands — every generated
-
#1311
5956a8eThanks @danilopopeye! - ### Bug Fixesarchiveexits non-zero when blocked in human mode —openspec archive <change> -y(and any non---jsoninvocation) no longer returns exit code 0 when validation fails and nothing is archived. The three blocking paths in human mode — delta-spec validation failure, spec rebuild failure, and rebuilt-spec validation failure — now setprocess.exitCode = 1, matching the existing--jsonbehavior. Previously the command printed "Validation failed" (or "Aborted. No files were changed.") and exited 0, letting scripts and CI believe the archive succeeded. Alignsarchivewith the same exit-code guarantee already approved forapplyinstructions (#1250).
-
#1280
a325305Thanks @clay-good! - ### Bug Fixesvalidateresolves changes likestatus—openspec validate <change>(and--all/--changesand the interactive selector) now resolves a change by directory existence, matchingstatus/instructions, instead of requiringproposal.md. A scaffolded or still-authoring change is validated rather than reported asUnknown item, and a resolved-but-invalid change now exits non-zero. Delta discovery also recurses the nestedspecs/<area>/<capability>/spec.mdlayout. (#1182)- Task progress reads nested/glob
tasks.md—openspec view,list, and thearchiveincomplete-task gate now resolve task progress through the tracked-tasks artifact'sgeneratesglob (the same file-resolutionstatususes), so a change whose tasks live in nestedtasks.mdfiles is classified correctly and can no longer archive while unfinished. (#1202) - SHALL/MUST body-keyword hint applies to main specs — A main-spec requirement whose normative keyword sits only in the
### Requirement:header now receives the same targeted "move it to the body line" remediation as a change delta, emitted exactly once. (#1156)
-
#1281
9a0dfb5Thanks @clay-good! - ### Bug Fixes-
Requirement reading fidelity — The requirement reader used by
validate <change>,validate <spec>, andarchiveis now unified into one fence-, metadata-, and multi-line-aware extraction, closing the known divergences between the change-delta path and the main-spec path (the remaining ones are documented in the change's design doc):- A
SHALL/MUSTkeyword that wraps onto a later body line is detected instead of dropped (#361). - Metadata lines (
**ID**:,**Priority**:) before the description are skipped on the spec path, matching the change path (#418). A requirement written entirely as metadata (e.g.**Constraint**: The system MUST ...) keeps that line as its text instead of being emptied. - A fenced code block before the prose line no longer becomes the requirement text (#312).
- A
#### Scenario:inside a fenced example no longer counts as a real scenario invalidate <change>, matchingvalidate <spec>. SHALL/MUSTdetection uses one whole-word predicate across all readers, and a requirement with no body text falls back to its header title on both paths.
Displayed requirement text (e.g. in JSON output and delta descriptions) now reflects the full requirement body rather than only its first line. Archived spec content is unchanged — the archive rebuild reads raw
### Requirement:blocks, not the parsed text. - A
-
Surface non-canonical delta headers —
validate <change>now emits an INFO note when an## ADDED/## MODIFIED Requirementssection contains a level-3 header that is not a canonical### Requirement:header (one the delta reader silently skips, such as a stray### Documentation Requirementsdivider). The note never changes thevalidresult, including under--strict(#498).
-
1.5.0
Minor Changes
-
#1267
96f6cacThanks @TabishB! - ### New Features- Stores (very early beta) — Introduces stores as a simpler way to organize specs and changes, replacing the workspace and initiative model. This feature is in very early beta — expect rough edges and breaking changes in upcoming releases.
Bug Fixes
- Config parsing — Configuration values wrapped in JSON containers are now parsed correctly.
Patch Changes
-
#1240
cbf386bThanks @zied-jlassi! - fix(adapters): escape carriage returns in generated YAML frontmatterescapeYamlValueflagged\ras a character requiring quoting but never escaped it, leaving a literal carriage return inside the double-quoted scalar where YAML line folding/normalization could silently corrupt the value (realistic with CRLF-authored command descriptions). Carriage returns are now escaped as\r. The helper — previously duplicated verbatim across five adapters (bob, claude, cursor, pi, windsurf) — is extracted into a sharedcommand-generation/yaml.tsmodule so the behavior stays consistent and is fixed in one place.
1.4.1
Patch Changes
- #1165
0a01146Thanks @TabishB! - Move beta workspace view state to.openspec-workspace/view.yaml, stop top-levelopenspec updatefrom routing into workspace updates, and ignore foreign rootworkspace.yamlfiles so Dagster projects keep updating normally.
1.4.0
Minor Changes
-
#1003
342ed43Thanks @Miss-you! - ### New Features- Kimi CLI support — OpenSpec can now initialize Kimi CLI as a supported skills-only tool using
.kimi/skills/
Other
- Added Kimi-specific docs and init coverage aligned with skill-based
/skill:openspec-*usage
- Kimi CLI support — OpenSpec can now initialize Kimi CLI as a supported skills-only tool using
-
#1154
aa16080Thanks @TabishB! - ### New Features- Mistral Vibe support — OpenSpec can now initialize Mistral Vibe as a supported skills-only tool using
.vibe/skills/
Bug Fixes
- Case-insensitive requirement headers — Requirement headers are now parsed regardless of capitalization, so specs no longer fail to parse over header casing
- Zsh completions on oh-my-zsh — Fixed shell completion setup so tab completion installs correctly under oh-my-zsh's
compinit
Other
- Clearer validation hints — When a requirement has SHALL/MUST only in its header,
openspec validatenow points you to move the keyword onto the requirement body line instead of showing the generic error
- Mistral Vibe support — OpenSpec can now initialize Mistral Vibe as a supported skills-only tool using
-
#1030
485c97eThanks @TabishB! - ### New Features- Include the sync workflow in the default core profile so new installs generate
/opsx:syncskills and commands by default.
- Include the sync workflow in the default core profile so new installs generate
Patch Changes
-
#1111
7fdb177Thanks @TabishB! - ### Fixed- Preserve workspace planning detection when Windows short paths or symlink aliases resolve to a canonical workspace root.
1.3.1
Patch Changes
-
#995
d1f3861Thanks @TabishB! - ### Bug Fixes- Canonical artifact paths — Workflow artifact paths are now resolved via the native
realpath, so symlinks and case-insensitive filesystems no longer cause path mismatches during apply and archive. - Glob apply instructions — Apply instructions with glob artifact outputs now resolve correctly, and literal artifact outputs are enforced to be file paths.
- Hidden main spec requirements — Requirements nested inside fenced code blocks or otherwise hidden in main specs are now detected during validation.
- Clean
--jsonoutput — Spinner progress text no longer leaks into stderr when--jsonis passed, so AI agents that combine stdout and stderr can parse the JSON reliably. - Silent telemetry in firewalled environments — PostHog network errors are now swallowed with a 1s timeout and retries/remote config disabled, so OpenSpec no longer surfaces
PostHogFetchNetworkErrorin locked-down networks. Telemetry opt-out is documented earlier in the README, installation guide, and CLI reference.
- Canonical artifact paths — Workflow artifact paths are now resolved via the native
1.3.0
Minor Changes
-
#952
cce787eThanks @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
61eb999Thanks @fsilvaortiz! - fix: OpenCode adapter now uses.opencode/commands/(plural) to match OpenCode's official directory convention. Fixes #748. -
#759
afdca0dThanks @fsilvaortiz! - fix:openspec statusnow exits gracefully when no changes exist instead of throwing a fatal error. Fixes #714.
1.2.0
Minor Changes
-
#747
1e94443Thanks @TabishB! - ### New Features- Profile system — Choose between
core(4 essential workflows) andcustom(pick any subset) profiles to control which skills get installed. Manage profiles with the newopenspec config profilecommand - Propose workflow — New one-step workflow creates a complete change proposal with design, specs, and tasks from a single request — no need to run
newthenffseparately - AI tool auto-detection —
openspec initnow 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 updatenow removes command files and skill directories for workflows you've deselected, keeping your project clean - Config drift warning —
openspec config listwarns 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
- Profile system — Choose between
1.1.1
Patch Changes
-
#627
afb73cfThanks @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
- OpenCode command references — Command references in generated files now use the correct
1.1.0
Minor Changes
-
#625
53081fbThanks @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
workflowsdirectory instead of the legacycommandspath (#610)
Patch Changes
-
#550
86d2e04Thanks @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
e91568dThanks @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
- Clarified spec naming convention — Specs should be named after capabilities (
1.0.1
Patch Changes
-
#587
943e0d4Thanks @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 incorrectopenspec/archive/YYYY-MM-DD--<name>/
- Fixed incorrect archive path in onboarding documentation — the template now shows the correct path
1.0.0
Major Changes
-
#578
0cc9d90Thanks @TabishB! - ## OpenSpec 1.0 — The OPSX ReleaseThe 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:archiveno longer exist - Config files removed — Tool-specific instruction files (
CLAUDE.md,.cursorrules,AGENTS.md,project.md) are no longer generated - Migration — Run
openspec initto 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:
- Context — Project background from
config.yaml(tech stack, conventions) - Rules — Artifact-specific constraints (e.g., "propose spike tasks for unknowns")
- 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:exploreThink through ideas before committing to a change /opsx:newStart a new change /opsx:continueCreate one artifact at a time (step-through) /opsx:ffCreate all planning artifacts at once (fast-forward) /opsx:applyImplement tasks /opsx:verifyValidate implementation matches artifacts /opsx:syncSync delta specs to main specs /opsx:archiveArchive completed change /opsx:bulk-archiveArchive multiple changes with conflict detection /opsx:onboardGuided 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:onboardwalks 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 initshows 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
- Old commands removed —
0.23.0
Minor Changes
-
#540
c4cfdc7Thanks @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
- Bulk archive skill — Archive multiple completed changes in a single operation with
0.22.0
Minor Changes
-
#530
33466b1Thanks @TabishB! - Add project-level configuration, project-local schemas, and schema management commandsNew 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 schemacommands (list,show,export,validate) for inspecting and managing artifact schemas (experimental)
Bug Fixes
- Fixed config loading to handle null
rulesfield in project configuration
- Project-level configuration — Configure OpenSpec behavior per-project via
0.21.0
Minor Changes
-
#516
b5a8847Thanks @TabishB! - Add feedback command and Nix flake supportNew 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
- Feedback command — Submit feedback directly from the CLI with
0.20.0
Minor Changes
-
#502
9db74aaThanks @TabishB! - Add/opsx:verifycommand and fix vitest process stormsNew Features
/opsx:verifycommand — 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:explorecommandNew Features
- Continue IDE support – OpenSpec now generates slash commands for Continue, expanding editor integration options alongside Cursor, Windsurf, Claude Code, and others
- Shell completions for Bash, Fish, and PowerShell – Run
openspec completion installto set up tab completion in your preferred shell /opsx:explorecommand – 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=0orDO_NOT_TRACK=1to 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 systemNew 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.yamlfiles - 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-interactiveflag 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/promptsThe 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 resetcommand is actually used interactively.Also adds ESLint with a rule to prevent static @inquirer imports, avoiding future regressions.
0.17.0
Minor Changes
-
2e71835: Addopenspec configcommand and Oh-my-zsh completionsNew Features
- Add
openspec configcommand 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
- Add
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 initcan generate.continue/prompts/openspec-*.promptfiles with MARKDOWN frontmatter and$ARGUMENTSplaceholder, and refresh them onopenspec update. -
Add Antigravity slash command support so
openspec initcan generate.agent/workflows/openspec-*.mdfiles with description-only frontmatter andopenspec updaterefreshes 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
- Gemini CLI: Add native TOML-based slash command support for Gemini CLI with
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 validationThis 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 optionsThis 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-toolsCLI flags toopenspec initfor 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.mdwith YAML frontmatter and$ARGUMENTSplaceholder, and refreshes them onopenspec 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 viaopenspec --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/promptsor$CODEX_HOME/prompts) and refreshes them onopenspec update.
0.7.0
Minor Changes
- Add native Kilo Code workflow integration so
openspec initandopenspec updatemanage.kilocode/workflows/openspec-*.mdfiles. - Always scaffold the managed root
AGENTS.mdhand-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 initwith extend mode, multi-tool selection, and an interactiveAGENTS.mdconfigurator.
0.2.0
Minor Changes
ce5cead: - Add anopenspec viewdashboard that rolls up spec counts and change progress at a glance- Generate and update AI slash commands alongside the renamed
openspec/AGENTS.mdinstructions file - Remove the deprecated
openspec diffcommand and direct users toopenspec show
- Generate and update AI slash commands alongside the renamed
0.1.0
Minor Changes
24b4866: Initial release