Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e0d01c1
proposal: add devin desktop support
mehdishahdoost Jun 4, 2026
a0a3fb6
feat(adapters): add devin desktop command adapter
mehdishahdoost Jun 4, 2026
514699e
fix(config): add devin desktop to AI_TOOLS
mehdishahdoost Jun 4, 2026
fd974e1
fix(devin-adapter): escape implicit YAML scalars in frontmatter
mehdishahdoost Jun 4, 2026
9a8befa
test(devin-adapter): add comprehensive tests for Devin Desktop adapter
mehdishahdoost Jun 6, 2026
cbb8301
Add cross-platform testcase.
mehdishahdoost Jun 6, 2026
c83bdd4
Merge branch 'main' into feat/add-devin-desktop-support
mehdishahdoost Jul 2, 2026
48e6b28
Merge branch 'main' into feat/add-devin-desktop-support
mehdishahdoost Jul 9, 2026
254fec2
Merge origin/main into feat/add-devin-desktop-support (resolve confli…
mehdishahdoost Jul 25, 2026
3563114
Merge branch 'main' into feat/add-devin-desktop-support
clay-good Jul 28, 2026
e310b41
fix(devin): refresh deltas against canonical specs and point skills a…
clay-good Jul 28, 2026
872e34c
fix(devin): correct commands-only hint, fill doc gaps, cover both sur…
clay-good Jul 28, 2026
44258ce
fix(devin): name the right command in the profile migration notice
clay-good Jul 28, 2026
306e8e6
Merge branch 'main' into feat/add-devin-desktop-support
clay-good Jul 28, 2026
ad43431
Merge remote-tracking branch 'origin/main' into pr-1167-local
clay-good Jul 28, 2026
343ae0a
fix(devin): keep the cli-update delta in step with the canonical spec
clay-good Jul 28, 2026
9005be2
feat(adapters): follow the Windsurf rename to Devin Desktop, with mig…
clay-good Jul 28, 2026
8012bc3
fix(devin): stop the migration from deleting anything it does not own
clay-good Jul 28, 2026
d94af8b
docs(devin): add a changeset for the Windsurf rename and migration
clay-good Jul 28, 2026
2a9c0e9
fix(devin): move only SKILL.md, never the skill directory around it
clay-good Jul 28, 2026
90eaee1
fix(devin): treat an edited skill the way an edited command is alread…
clay-good Jul 28, 2026
37bff11
fix(devin): report divergent legacy files even when nothing is movable
clay-good Jul 28, 2026
c164701
test(devin): stop matching the unrelated profile-migration line
clay-good Jul 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/devin-desktop-rename.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@fission-ai/openspec': patch
---

**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 is `devin`, writing `.devin/workflows/opsx-<id>.md` and `.devin/skills/openspec-*/SKILL.md`, and it is detected from either directory.

- `--tools windsurf` still resolves, so existing setup scripts keep working; it now configures `.devin/`.
- If your OpenSpec files are still in `.windsurf/`, `openspec update` explains the rebrand and offers to move them. `--force` and non-interactive runs take the move; declining leaves every file exactly where it is. Only the files OpenSpec generates move — each skill's `SKILL.md` and commands named `opsx-*`. A hand-written Cascade workflow, a reference file you keep beside a `SKILL.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.
2 changes: 1 addition & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ openspec init [path] [options]

The welcome animation is also skipped when the `OPENSPEC_NO_ANIMATION` environment variable is set (any value, including empty), when `NO_COLOR` is set to a non-empty value, or when the OS reduced-motion preference is enabled (macOS Reduce Motion, GNOME animations disabled).

**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codeartsagent`, `codex`, `forgecode`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `hermes`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `lingma`, `vibe`, `oh-my-pi`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`, `zcode`
**Supported tool IDs (`--tools`)** — `windsurf` is also accepted, as an alias for `devin`: `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codeartsagent`, `codex`, `devin`, `forgecode`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `hermes`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `lingma`, `vibe`, `oh-my-pi`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `zcode`

> This list mirrors `AI_TOOLS` in `src/core/config.ts`. See [Supported Tools](supported-tools.md) for each tool's skill and command paths.

Expand Down
9 changes: 7 additions & 2 deletions docs/commands.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Commands

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

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

Expand Down Expand Up @@ -672,11 +672,16 @@ Different AI tools use slightly different command syntax. Use the format that ma
| Your tool's command file | Syntax example | Example tools |
|--------------------------|----------------|---------------|
| `.../commands/opsx/<id>.*` | `/opsx:propose`, `/opsx:apply` | Claude Code, Gemini CLI, Crush |
| `.../opsx-<id>.*` | `/opsx-propose`, `/opsx-apply` | Cursor, Windsurf, Copilot (IDE), Trae, Oh My Pi |
| `.../opsx-<id>.*` | `/opsx-propose`, `/opsx-apply` | Cursor, Devin Desktop, Copilot (IDE), Trae, Oh My Pi |
| none — skills only | `/openspec-propose`, `/openspec-apply-change` | CodeArts, ForgeCode, Hermes, Mistral Vibe |
| none — Kimi Code | `/skill:openspec-propose` | Kimi Code |
| none — Codex CLI | `$openspec-propose` | Codex |

> **Devin Desktop vs Devin Local:** the `.devin/workflows/opsx-*.md` files give
> Devin Desktop `/opsx-propose`. Devin Local has no workflows — use the skills
> OpenSpec writes to `.devin/skills/`, e.g. `/openspec-propose`, which work on
> both agents.

The intent is the same across tools, but how commands are surfaced can differ by integration. [How To Invoke](supported-tools.md#how-to-invoke) lists every supported tool; this table shows only examples of each shape.

> **Note:** GitHub Copilot commands (`.github/prompts/*.prompt.md`) are only available in IDE extensions (VS Code, JetBrains, Visual Studio). GitHub Copilot CLI does not currently support custom prompt files — see [Supported Tools](supported-tools.md) for details and workarounds.
Expand Down
2 changes: 1 addition & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Existing codebases are the main event. OpenSpec is brownfield-first: you do not

### Is it tied to one AI tool?

No. OpenSpec works with 30+ assistants, including Claude Code, Cursor, Windsurf, GitHub Copilot, Gemini CLI, Codex, and more. The full list and per-tool details are in [Supported Tools](supported-tools.md).
No. OpenSpec works with 30+ assistants, including Claude Code, Cursor, Devin Desktop, GitHub Copilot, Gemini CLI, Codex, and more. The full list and per-tool details are in [Supported Tools](supported-tools.md).

## Running commands

Expand Down
15 changes: 11 additions & 4 deletions docs/how-commands-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ openspec list # see active changes
openspec view # open the interactive dashboard
```

**The slash commands (chat half).** Short commands like `/opsx:propose` and `/opsx:apply` that you type into your AI assistant. These tell the AI to follow the OpenSpec workflow: draft a proposal, write specs, build from the task list, archive when done. You type these into Claude Code, Cursor, Windsurf, Copilot, or whichever assistant you use.
**The slash commands (chat half).** Short commands like `/opsx:propose` and `/opsx:apply` that you type into your AI assistant. These tell the AI to follow the OpenSpec workflow: draft a proposal, write specs, build from the task list, archive when done. You type these into Claude Code, Cursor, Devin Desktop, Copilot, or whichever assistant you use.

```text
/opsx:propose add-dark-mode (typed in your AI chat)
Expand Down Expand Up @@ -51,7 +51,7 @@ You don't enter a special OpenSpec mode. You just open your AI coding assistant

So the real instructions are:

1. Open your AI coding assistant (Claude Code, Cursor, Windsurf, and so on) in your project.
1. Open your AI coding assistant (Claude Code, Cursor, Devin Desktop, and so on) in your project.
2. Type `/opsx:propose` in its chat, the same place you type any other request.
3. Watch the autocomplete: if OpenSpec is installed, you'll see `/opsx:propose`, `/opsx:apply`, and friends appear as you type the slash.

Expand All @@ -65,7 +65,7 @@ It's worth understanding, because it explains why OpenSpec works with 30+ differ

The CLI is the **engine**. It knows the rules: what a change folder looks like, which artifacts depend on which, how to merge a delta spec into your source of truth. It's the same everywhere.

The slash commands are the **steering wheel**, and every AI tool has a slightly different one. Claude Code calls them commands. Cursor and Windsurf have their own formats. Some tools call them skills. When you run `openspec init`, OpenSpec generates the right kind of file for each tool you selected, so the same `/opsx:propose` intent works no matter which assistant you prefer.
The slash commands are the **steering wheel**, and every AI tool has a slightly different one. Claude Code calls them commands. Cursor and Devin Desktop have their own formats. Some tools call them skills. When you run `openspec init`, OpenSpec generates the right kind of file for each tool you selected, so the same `/opsx:propose` intent works no matter which assistant you prefer.

The strength of this design: you learn the workflow once and carry it across tools. The tradeoff: the exact syntax of a command can differ slightly between tools, which is the next section.

Expand All @@ -76,12 +76,19 @@ The intent is identical everywhere. The spelling follows the file your tool load
| Your tool's command file | How you type it | Example tools |
|--------------------------|-----------------|---------------|
| `.../commands/opsx/<id>.*` | `/opsx:propose` | Claude Code, Gemini CLI, Crush |
| `.../opsx-<id>.*` | `/opsx-propose` | Cursor, GitHub Copilot (IDE), Windsurf, Trae, Oh My Pi |
| `.../opsx-<id>.*` | `/opsx-propose` | Cursor, GitHub Copilot (IDE), Devin Desktop, Trae, Oh My Pi |
| `.amazonq/prompts/opsx-<id>.md` | `@opsx-propose` | Amazon Q Developer |
| none — skills only | `/openspec-propose` | CodeArts, ForgeCode, Hermes, Mistral Vibe |
| none — Kimi Code | `/skill:openspec-propose` | Kimi Code |
| none — Codex CLI | `$openspec-propose` | Codex |

Devin is the one tool that spans two rows. Devin Desktop reads
`.devin/workflows/`, so `/opsx-propose` works there; [Devin Local does
not](https://docs.devin.ai/desktop/devin-local), so on that agent use the
`/openspec-propose` skill instead. The skills OpenSpec writes to
`.devin/skills/` work on both, which is why they reference each other by skill
name.

Every tool is listed in [How To Invoke](supported-tools.md#how-to-invoke) — that
table is the authoritative one. Two rows are not slash commands at all: Amazon Q
loads its files into a prompt library invoked with `@`, and the last three rows
Expand Down
2 changes: 1 addition & 1 deletion docs/migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Only OpenSpec-managed files that are being replaced:

- Claude Code: `.claude/commands/openspec/`
- Cursor: `.cursor/commands/openspec-*.md`
- Windsurf: `.windsurf/workflows/openspec-*.md`
- Devin Desktop, formerly Windsurf: `.windsurf/workflows/openspec-*.md`
- Cline: `.clinerules/workflows/openspec-*.md`
- Roo: `.roo/commands/openspec-*.md`
- GitHub Copilot: `.github/prompts/openspec-*.prompt.md` (IDE extensions only; not supported in Copilot CLI)
Expand Down
2 changes: 1 addition & 1 deletion docs/opsx.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ Examples in this section use the expanded command set (`new`, `continue`, etc.);
│ ▼ │
│ Skill Files (.claude/skills/openspec-*/SKILL.md) │
│ │
│ • Cross-editor compatible (Claude Code, Cursor, Windsurf)
│ • Cross-editor compatible (Claude Code, Cursor, Devin)
│ • Skills query CLI for structured data │
│ • Fully customizable via schema files │
│ │
Expand Down
9 changes: 6 additions & 3 deletions docs/supported-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ way it loads the file OpenSpec wrote. Find your tool's command path in the
| Command file OpenSpec writes | You type | Tools |
|------------------------------|----------|-------|
| `.../commands/opsx/<id>.*` — an `opsx/` folder namespaces it | `/opsx:<id>` | Claude Code, CodeBuddy, Crush, Gemini CLI, Lingma, Qoder, ZCode |
| `.../opsx-<id>.*` — the filename is the command | `/opsx-<id>` | Every other tool with generated command files, except Amazon Q |
| `.../opsx-<id>.*` — the filename is the command | `/opsx-<id>` | Every other tool with generated command files, except Amazon Q and Devin |
| `.devin/workflows/opsx-<id>.md` — read by only one of Devin's two agents | `/opsx-<id>` on Devin Desktop, `/openspec-<skill>` on Devin Local | Devin Desktop\*\*\*\* |
| `.amazonq/prompts/opsx-<id>.md` — a prompt, not a command | `@opsx-<id>` | Amazon Q Developer |
| none — skills only | `/openspec-<skill>` | CodeArts, ForgeCode, Hermes, Mistral Vibe |
| none — Kimi Code | `/skill:openspec-<skill>` | Kimi Code |
Expand Down Expand Up @@ -72,6 +73,7 @@ to read the hint.
| CodeArts (`codeartsagent`) | `.codeartsdoer/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
| CodeBuddy (`codebuddy`) | `.codebuddy/skills/openspec-*/SKILL.md` | `.codebuddy/commands/opsx/<id>.md` |
| Codex (`codex`) | `.codex/skills/openspec-*/SKILL.md` | Not generated (skills-only; use `.codex/skills/openspec-*`) |
| Devin Desktop, formerly Windsurf (`devin`) | `.devin/skills/openspec-*/SKILL.md` | `.devin/workflows/opsx-<id>.md`\*\*\*\* |
| ForgeCode (`forgecode`) | `.forge/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/openspec-*` invocations) |
| Continue (`continue`) | `.continue/skills/openspec-*/SKILL.md` | `.continue/prompts/opsx-<id>.prompt` |
| CoStrict (`costrict`) | `.cospec/skills/openspec-*/SKILL.md` | `.cospec/openspec/commands/opsx-<id>.md` |
Expand All @@ -95,13 +97,14 @@ to read the hint.
| Qwen Code (`qwen`) | `.qwen/skills/openspec-*/SKILL.md` | `.qwen/commands/opsx-<id>.md` |
| [Zoo Code](https://github.com/Zoo-Code-Org/Zoo-Code) (`roocode`) | `.roo/skills/openspec-*/SKILL.md` | `.roo/commands/opsx-<id>.md` |
| Trae (`trae`) | `.trae/skills/openspec-*/SKILL.md` | `.trae/commands/opsx-<id>.md` |
| Windsurf (`windsurf`) | `.windsurf/skills/openspec-*/SKILL.md` | `.windsurf/workflows/opsx-<id>.md` |
| ZCode (`zcode`) | `.zcode/skills/openspec-*/SKILL.md` | `.zcode/commands/opsx/<id>.md` |

\*\* GitHub Copilot prompt files are recognized as custom slash commands in IDE extensions (VS Code, JetBrains, Visual Studio). Copilot CLI does not currently consume `.github/prompts/*.prompt.md` directly.

\*\*\* Hermes loads skills from `~/.hermes/skills/` by default. To use project-local OpenSpec skills, add the project `.hermes/skills/` directory to `skills.external_dirs` in `~/.hermes/config.yaml`; Hermes then exposes skills with user-facing slash invocations such as `/openspec-propose`.

\*\*\*\* Windsurf was [rebranded to Devin Desktop](https://docs.devin.ai/desktop/devin-desktop-faq) on June 2, 2026, and its config directory moved: `.devin/` is the preferred read + write location, `.windsurf/` a legacy read-only fallback. OpenSpec follows the rename — the tool id is `devin`, and `--tools windsurf` still resolves to it so existing setup scripts keep working. A project still holding OpenSpec files in `.windsurf/` is offered the move on the next `openspec update`; declining leaves them in place, and files you wrote yourself are never touched. Workflows are invoked by filename, so `.devin/workflows/opsx-apply.md` is `/opsx-apply`. The [Devin Local agent does not support workflows](https://docs.devin.ai/desktop/devin-local) — only skills, and it does not read `.windsurf/` at all — so whenever OpenSpec writes Devin skills it keeps their bodies, and the getting-started hint, on `/openspec-*` skill invocations, which work on both agents. Under commands-only delivery no skills are written and both fall back to `/opsx-*`.

## Non-Interactive Setup

For CI/CD or scripted setup, use `--tools` (and optionally `--profile`):
Expand All @@ -120,7 +123,7 @@ openspec init --tools none
openspec init --profile core
```

**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codeartsagent`, `codex`, `forgecode`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `hermes`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `lingma`, `vibe`, `oh-my-pi`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`, `zcode`
**Available tool IDs (`--tools`)** — `windsurf` is also accepted, as an alias for `devin`: `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codeartsagent`, `codex`, `devin`, `forgecode`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `hermes`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `lingma`, `vibe`, `oh-my-pi`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `zcode`

## Workflow-Dependent Installation

Expand Down
2 changes: 2 additions & 0 deletions openspec/changes/add-devin-desktop-support/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-06-04
32 changes: 32 additions & 0 deletions openspec/changes/add-devin-desktop-support/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Why

- Windsurf has been [rebranded to **Devin Desktop**](https://docs.devin.ai/desktop/devin-desktop-faq) as of June 2, 2026. Same IDE, same editor, new brand.
- The rebrand moved the config directory: `.devin/` is now the preferred read + write location and `.windsurf/` the legacy read-only fallback, for `rules/`, `workflows/`, `skills/`, and `plans/`. OpenSpec writes only `.windsurf/`, so every Devin install lands in the deprecated path.
- Devin ships two agents. Devin Desktop (Cascade) reads workflows; the [Devin Local agent does not](https://docs.devin.ai/desktop/devin-local) — its docs say to migrate workflows to skills, and it does not read `.windsurf/` at all. An existing Windsurf user's OpenSpec files are therefore invisible to Devin Local entirely.
- Adding `devin` as a *second* tool id alongside `windsurf` would list one product twice in the picker and leave existing users with two parallel installs. This follows the rename instead, matching what OpenSpec already did for Kimi CLI → Kimi Code.

## What Changes

- **Rename the tool, don't duplicate it.** `windsurf` is retired as a tool id; `devin` (Devin Desktop) takes its place with `skillsDir: '.devin'` and `detectionPaths: ['.devin', '.windsurf']`. The Windsurf adapter is replaced by a Devin adapter writing `.devin/workflows/opsx-<id>.md`.
- **Keep `--tools windsurf` working.** A `TOOL_ID_ALIASES` map resolves retired ids, so existing setup scripts and CI keep running; they now configure `.devin/`.
- **Migrate existing installs, with consent.** OpenSpec-managed skills (`openspec-*`) and command files (`opsx-*`) under `.windsurf/` move to `.devin/`. `openspec update` explains the rebrand and asks first; `--force` and non-interactive runs take the move. Selecting the tool during `openspec init` is itself consent. Files the user wrote are never touched.
- Route Devin's **skill** bodies and the getting-started hint through the skill-reference transformer so they say `/openspec-*`, the one invocation both Devin agents accept.
- Update the tool reference, invocation, and command-syntax tables in `docs/`, plus the website tool list.

## Impact

- **Specs:** `ai-tool-paths`, `cli-init`, `cli-update`, `command-generation`
- **Code:**
- `src/core/command-generation/adapters/devin.ts` (new; `windsurf.ts` deleted)
- `src/core/command-generation/registry.ts`, `adapters/index.ts`, `index.ts`
- `src/core/config.ts` (`AI_TOOLS` row, `TOOL_ID_ALIASES`, `resolveToolIdAlias`)
- `src/core/migration.ts` (`LEGACY_TOOL_ROOTS`, consent-aware migration of skills *and* command files)
- `src/core/init.ts`, `src/core/update.ts` (alias resolution, migration prompt)
- `src/core/legacy-cleanup.ts` (pre-opsx `.windsurf/` files now key to `devin`)
- `src/utils/command-references.ts` (Devin's skill-reference transformer)
- **Docs:** `supported-tools.md`, `cli.md`, `commands.md`, `how-commands-work.md`, `faq.md`, `migration-guide.md`, `opsx.md`, website home page

## Notes

- **Who could be affected:** a user still on a pre-rebrand Windsurf build reads only `.windsurf/`. That is why the move is offered rather than taken — declining leaves every file where it is. Declining does mean `.windsurf/` stops being refreshed, which the prompt says plainly.
- The `.devin/` directory also covers `rules/` and `plans/`. OpenSpec writes neither, so they are out of scope and untouched.
Loading
Loading