Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,6 @@ opencode.json

# Trae
.trae/

# Cursor
.cursor/
1 change: 1 addition & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ Different AI tools use slightly different command syntax. Use the format that ma
| Windsurf | `/opsx-propose`, `/opsx-apply` |
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
| CodeArts | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |
| Codex | Skill-based invocations from `.codex/skills/openspec-*` (no generated `opsx-*` prompt files) |
| Oh My Pi | `/opsx-propose`, `/opsx-apply` |
| Kimi Code | Skill-based invocations such as `/skill:openspec-propose`, `/skill:openspec-apply-change` (no generated `opsx-*` command files) |
| Trae | `/opsx-propose`, `/opsx-apply` |
Expand Down
3 changes: 2 additions & 1 deletion docs/how-commands-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ The intent is identical everywhere. The punctuation differs. Use the form that m
| Windsurf | `/opsx-propose`, `/opsx-apply` |
| GitHub Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
| CodeArts | skill-style, e.g. `/openspec-propose` |
| Codex | skill-style via `.codex/skills/openspec-*` |
| Oh My Pi | `/opsx-propose`, `/opsx-apply` |
| Kimi CLI | skill-style, e.g. `/skill:openspec-propose` |
| Trae | `/opsx-propose`, `/opsx-apply` |
Expand All @@ -93,7 +94,7 @@ When in doubt, type a slash in your AI chat and look at the autocomplete. Your t
When you run `openspec init` (or `openspec update`), OpenSpec writes small files into your project so your AI tool can find the workflow. Depending on your tool and settings, these are **skills**, **commands**, or both.

- **Skills** live in places like `.claude/skills/openspec-*/SKILL.md`. They're the emerging cross-tool standard: a folder of instructions your assistant auto-detects.
- **Commands** live in places like `.claude/commands/opsx/<id>.md`. They're the older per-tool slash command files.
- **Commands** live in places like `.claude/commands/opsx/<id>.md`. They're the older per-tool slash command files. Codex does not get generated command files; use `.codex/skills/openspec-*`.

You don't have to care which one your tool uses. You just type the slash command and it works. But knowing these files exist helps when something goes wrong: if your commands vanish, it usually means these files are missing or stale, and `openspec update` regenerates them.

Expand Down
5 changes: 5 additions & 0 deletions docs/migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Only OpenSpec-managed files that are being replaced:
- 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)
- Codex: OpenSpec now uses `.codex/skills/openspec-*`; legacy cleanup only targets OpenSpec's allowlisted prompt filenames in `$CODEX_HOME/prompts` or `~/.codex/prompts`, and only removes them after replacement skills exist.
- And others (Augment, Continue, Amazon Q, etc.)

The migration detects whichever tools you have configured and cleans up their legacy files.
Expand Down Expand Up @@ -156,6 +157,8 @@ openspec init --force --tools claude

The `--force` flag skips prompts and auto-accepts cleanup.

This includes cleanup of OpenSpec-managed Codex prompt files in the global Codex prompt directory. Cleanup only targets OpenSpec's allowlisted legacy Codex prompt filenames, removes them only after replacement `.codex/skills/openspec-*` skills exist, and preserves all other files.

---

## Migrating project.md to config.yaml
Expand Down Expand Up @@ -407,6 +410,8 @@ OPSX uses the emerging **skills** standard:

Skills are recognized across multiple AI coding tools and provide richer metadata.

Codex is skills-only in OPSX. OpenSpec no longer generates Codex custom prompt files; use the generated `.codex/skills/openspec-*` directories instead.

---

## Continuing Existing Changes
Expand Down
6 changes: 3 additions & 3 deletions docs/supported-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ For each selected tool, OpenSpec can install:
1. **Skills** (if delivery includes skills): `.../skills/openspec-*/SKILL.md`
2. **Commands** (if delivery includes commands): tool-specific `opsx-*` command files

Codex is skills-only: OpenSpec installs `.codex/skills/openspec-*/SKILL.md` for Codex even when delivery is set to `commands`, and it does not generate Codex custom prompt files.

By default, OpenSpec uses the `core` profile, which includes:
- `propose`
- `explore`
Expand All @@ -30,7 +32,7 @@ You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `bulk-arch
| Cline (`cline`) | `.cline/skills/openspec-*/SKILL.md` | `.clinerules/workflows/opsx-<id>.md` |
| 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` | `$CODEX_HOME/prompts/opsx-<id>.md`\* |
| Codex (`codex`) | `.codex/skills/openspec-*/SKILL.md` | Not generated (skills-only; use `.codex/skills/openspec-*`) |
| 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 @@ -57,8 +59,6 @@ You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `bulk-arch
| Windsurf (`windsurf`) | `.windsurf/skills/openspec-*/SKILL.md` | `.windsurf/workflows/opsx-<id>.md` |
| ZCode (`zcode`) | `.zcode/skills/openspec-*/SKILL.md` | `.zcode/commands/opsx/<id>.md` |

\* Codex commands are installed in the global Codex home (`$CODEX_HOME/prompts/` if set, otherwise `~/.codex/prompts/`), not your project directory.

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

\*\*\* 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`.
Expand Down
4 changes: 3 additions & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ If `/opsx:propose` (or your tool's equivalent) doesn't appear or doesn't do anyt

5. **Check you initialized this project.** Skills are written per project. If you cloned a repo or switched folders, run `openspec init` (or `openspec update`) there.

6. **Confirm your tool supports command files.** A few tools (CodeArts, Kimi CLI, ForgeCode, Mistral Vibe) don't get generated `opsx-*` command files; they use skill-based invocations instead. The forms differ per tool: see [Supported Tools](supported-tools.md) and [How Commands Work](how-commands-work.md#slash-command-syntax-by-tool).
6. **Confirm your tool supports command files.** Codex and a few other tools (CodeArts, Kimi CLI, ForgeCode, Mistral Vibe) don't get generated `opsx-*` command files; they use skill-based invocations instead. For Codex, check `.codex/skills/openspec-*`. The forms differ per tool: see [Supported Tools](supported-tools.md) and [How Commands Work](how-commands-work.md#slash-command-syntax-by-tool).

## Working with changes

Expand Down Expand Up @@ -149,6 +149,8 @@ You're in CI or a non-interactive shell, and OpenSpec found old files to clean u
openspec init --force
```

For Codex, OpenSpec may detect old managed prompt files in `$CODEX_HOME/prompts` or `~/.codex/prompts`. That cleanup is limited to OpenSpec's allowlisted legacy Codex prompt filenames, and non-interactive `openspec init` removes only the files whose replacement `.codex/skills/openspec-*` skills exist. Non-interactive `openspec update` leaves all legacy cleanup untouched unless you pass `--force`.

### Commands didn't appear after migrating

Restart your IDE. Skills are detected at startup. If they still don't appear, run `openspec update` and check the file locations in [Supported Tools](supported-tools.md).
Expand Down
2 changes: 2 additions & 0 deletions openspec/changes/make-codex-skills-only/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-06-30
86 changes: 86 additions & 0 deletions openspec/changes/make-codex-skills-only/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## Context

Codex is currently represented as both a skill-capable tool and a command-file target. Its command adapter writes `opsx-<workflow>.md` files to the global Codex prompt directory resolved from `CODEX_HOME` or the user's default `.codex` home. That means `openspec init` and `openspec update` can mutate files outside the project, and users can believe a project-local setup succeeded while the observable Codex surface depends on stale global prompt files.

Codex custom prompts are now deprecated in favor of skills, while OpenSpec already generates `.codex/skills/openspec-*/SKILL.md` as the supported workflow surface. This change removes Codex from the generated command adapter surface and treats Codex as a `skills-invocable` tool even when the user's global delivery mode includes commands.

## Goals / Non-Goals

**Goals:**

- Stop generating or refreshing Codex custom prompt files during `openspec init` and `openspec update`.
- Keep Codex usable through `.codex/skills/openspec-*/SKILL.md` for `both`, `skills`, and `commands` delivery settings.
- Remove stale OpenSpec-managed global Codex prompt files from the global Codex prompt directory only after replacement Codex skills exist, while keeping repo-local `.codex/prompts/openspec-*.md` compatibility cleanup.
- Update user-facing documentation and tests so Codex is documented as skills-only.

**Non-Goals:**

- Do not remove Codex as a supported AI tool.
- Do not remove command generation for other tools that still support prompt or command files.
- Do not delete arbitrary user-authored Codex prompt files; cleanup is limited to the final OpenSpec-managed prompt patterns in each scope.
- Do not change Codex workspace opener behavior.

## Decisions

### Decision: Remove Codex from the command adapter registry

Codex should no longer have a registered command adapter. This makes the command-generation layer reflect supported behavior: `CommandAdapterRegistry.get('codex')` returns undefined, and command generation callers skip command-file output for Codex.

Alternative considered: keep the adapter but gate writes in `init` and `update`. That leaves stale API surface and tests that imply Codex custom prompts are supported. Removing the adapter is clearer and matches adapterless skills-only tools.

### Decision: Treat Codex as skills-invocable regardless of delivery mode

Global delivery expresses the preferred output surfaces for tools that support both surfaces. For Codex, the only supported command surface is invocable skills. When a selected or configured Codex tool is processed under `commands` delivery, OpenSpec should still generate and preserve Codex skills while skipping Codex command files.

Alternative considered: let `commands` delivery remove Codex skills because there is no adapter. That would make selecting Codex produce no usable output, which contradicts the proposal and creates a poor migration path.

This should reuse the shared command-surface capability model from `add-tool-command-surface-capabilities` if that change lands first. If this change lands first, it should introduce only a shared minimal resolver that can later become the broader capability model; it should not add a Codex-only predicate that `init` and `update` special-case forever.

This follows the adapterless integration boundary for skills-only tools: do not add a fake command adapter or generated command path when the tool's real invocation surface is discovered skills. Codex also has existing managed global prompt files to retire; those global files are handled as legacy cleanup artifacts, not as ordinary delivery-reconciliation command files.

### Decision: Split global and repo-local Codex cleanup by trust level

Cleanup resolves the Codex prompt directory with the same `CODEX_HOME` fallback semantics that command generation used, but the global and repo-local legacy surfaces are not trusted equally.

Repo-local compatibility cleanup continues matching `.codex/prompts/openspec-*.md` inside the project tree. Those files are repository-scoped compatibility artifacts and can stay in the ordinary legacy cleanup model.

Global Codex prompts live in a user-owned directory outside the repository, so even a broad match on the historical `opsx-*.md` prompt filenames is too risky. Global cleanup therefore requires both the exact resolved Codex prompt directory and an explicit allowlist of the historical OpenSpec-owned Codex filenames. Workflow IDs are inferred from those allowlisted filenames. User-authored files such as `opsx-review.md` or `opsx-my-flow.md` remain unmanaged because they are not in the allowlist.

Alternative considered: compare file contents with the current prompt templates. That would miss prompts generated by older OpenSpec releases after templates changed. Exact directory and filename matching provides a stable migration boundary because the allowlisted names were generated and owned by OpenSpec, while avoiding broad matches against custom `opsx-*` files.

### Decision: Global Codex prompt deletion is replacement-gated migration cleanup

Managed global Codex prompt files are still detected through legacy artifact detection, but they are not deleted as ordinary "detect then delete" cleanup items. They are migration artifacts:

- detect the managed global prompt files
- infer the workflow IDs represented by those legacy filenames
- create or confirm replacement `.codex/skills/...` skills for those workflows
- delete only the prompt files whose replacement skills now exist

This avoids deleting the user's only Codex entry point before OpenSpec has established the replacement skill surface. The adapterless command-skip path must not by itself delete files from `$CODEX_HOME/prompts`, and ordinary delivery reconciliation must not touch them.

`openspec init` may still auto-clean other OpenSpec-managed legacy artifacts in non-interactive mode, but global Codex prompt deletion is deferred until replacement skills exist. `openspec update --force` or accepted interactive cleanup follows the same replacement-gated rule. For configured tools, update refreshes the selected Codex skills before performing the deferred global cleanup so a newly installed replacement skill can retire its prompt in the same run.

To keep cleanup previews auditable without falsely implying immediate deletion, CLI messaging should separate immediate repo-local cleanup from deferred global prompts cleanup. The deferred section should list the concrete global prompt paths and their tool IDs, while clearly stating that those prompts are removed only after matching replacement skills exist.

Implementation note: model project-local and global legacy prompt surfaces separately. Keep project-root slash-command paths in `LEGACY_SLASH_COMMAND_PATHS`, including `.codex/prompts/openspec-*.md` compatibility cleanup, and represent Codex's external prompt home in a separate `LEGACY_GLOBAL_SLASH_COMMAND_PATHS` table that resolves `$CODEX_HOME/prompts` (or `~/.codex/prompts` when unset) for the exact allowlisted historical OpenSpec prompt filenames. The allowlist includes `opsx-update.md`, introduced with the `update` workflow in v1.6.0. `detectLegacyArtifacts()` keeps these managed global prompt files separate from repo-local slash command files via `globalSlashCommandFiles`.

### Decision: Legacy Codex workflow replacement prefers the legacy filenames over the current profile

When OpenSpec migrates legacy global Codex prompts into skills for an unconfigured Codex tool, the replacement skill set is inferred from the detected prompt filenames where possible. For example, a legacy `opsx-explore.md` maps to `openspec-explore` rather than the full current core profile.

Alternative considered: reuse the current profile's `desiredWorkflows` for every legacy Codex upgrade. That can silently expand a narrow historical setup into a broader skill set and makes cleanup unsafe because OpenSpec would delete a legacy prompt even when it did not recreate the equivalent workflow.

### Decision: Keep legacy project-local `.codex/prompts` cleanup as compatibility cleanup

Existing cleanup already detects `.codex/prompts/openspec-*.md` in the project tree. That should remain for older or manually migrated projects, but it is insufficient for this change because recent Codex prompt generation used the global Codex home.

Alternative considered: replace project-local detection with global-only detection. Keeping both avoids regressions for users with older project-local artifacts.

## Risks / Trade-offs

- [Risk] Users with custom workflows that rely on Codex custom prompts will lose refreshed prompt files. -> Mitigation: document the breaking change and point Codex users to `.codex/skills/openspec-*`.
- [Risk] `delivery=commands` semantics become per-tool rather than purely global. -> Mitigation: document Codex as a `skills-invocable` command-surface tool and test commands-only Codex init/update.
- [Risk] Cleanup touches a global directory. -> Mitigation: remove only exact allowlisted OpenSpec-owned filenames directly under the resolved Codex prompt home, keep repo-local `.codex/prompts/openspec-*.md` cleanup scoped to the project tree, require replacement skills before deletion, and honor `CODEX_HOME` in tests.
- [Risk] Registry tests or docs may still assume Codex has a command adapter. -> Mitigation: update adapter, registry, supported-tools, troubleshooting, and migration docs in the same change.
- [Risk] This overlaps with `add-tool-command-surface-capabilities`. -> Mitigation: represent Codex with the same `skills-invocable` concept and rebase whichever change lands second.
Loading
Loading