Skip to content

Cursor slash commands: colon vs hyphen mismatch in docs and generated content #1307

Description

@Nanowingz

Summary

OpenSpec documents slash commands with colon syntax (/opsx:propose, /opsx:apply, …), but openspec init --tools cursor generates Cursor command files that register hyphen syntax (/opsx-propose, /opsx-apply, …) in the command palette. Users who follow OpenSpec docs cannot invoke the commands they expect.

Related: #680 (same class of mismatch for Qwen CLI).

Environment

  • OpenSpec CLI: 1.5.0
  • Cursor IDE (slash commands from .cursor/commands/)
  • Configured via openspec init --tools cursor

Expected behavior

After openspec init or openspec update for Cursor:

  1. The command palette should list /opsx:propose, /opsx:apply, /opsx:explore, /opsx:archive, /opsx:sync.
  2. The post-init "Getting started" message, generated command bodies, and skills should all use the same colon syntax.
  3. In-file cross-references (e.g. "run /opsx:apply") should match what the palette registers.

Actual behavior

Command palette shows hyphens, not colons

Typing /opsx in Cursor shows:

opsx-propose
opsx-apply
opsx-explore
opsx-archive
opsx-sync

The user cannot invoke /opsx:propose — only /opsx-propose.

Init message uses colons (correct per OpenSpec docs)

displaySuccessMessage() in src/core/init.ts prints colon syntax:

Start your first change: /opsx:propose "your idea"

So docs and palette disagree.

Cursor adapter hardcodes hyphen syntax

The Cursor adapter (src/core/command-generation/adapters/cursor.ts) writes:

// File path
return path.join('.cursor', 'commands', `opsx-${commandId}.md`);

// Frontmatter
name: /opsx-${content.id}
id: opsx-${content.id}

By contrast, the Claude adapter uses content.name, which is the canonical colon form (/opsx:propose).

Generated command bodies also mix conventions depending on version/update path — sometimes colon references inside files whose frontmatter registers hyphens.

transformToHyphenCommands makes things worse for Cursor

transformToHyphenCommands() (src/utils/command-references.ts) converts /opsx:/opsx-. It is applied for opencode and pi in src/core/init.ts and src/core/update.ts, but the Cursor adapter already emits hyphens in frontmatter regardless. The real fix is not to hyphenate Cursor content — it is to emit colon syntax for Cursor, consistent with OpenSpec docs and the Claude adapter.

Steps to reproduce

  1. openspec init --tools cursor in a fresh project (or openspec update --force).
  2. Restart Cursor.
  3. Type /opsx in the command palette → commands appear as opsx-propose, not opsx:propose.
  4. Compare with openspec init success output which says /opsx:propose.

Suggested fix

  1. Cursor adapter: use content.name (colon form) in frontmatter, same as Claude:
    name: ${escapeYamlValue(content.name)}  // /opsx:propose
  2. Investigate Cursor command registration: confirm whether colon syntax in name is sufficient, or whether file naming (opsx-<id>.md) forces hyphen display — if so, consider a nested layout (e.g. .cursor/commands/opsx/<id>.md) similar to Claude.
  3. Do not apply transformToHyphenCommands to Cursor.
  4. Keep colon syntax in displaySuccessMessage() / welcome text when that is the canonical form.

Related issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions