Guide for authoring an IDE slash command - one Markdown file the user runs as /name in Cursor, Claude Code or OpenCode. Use when users want to create or update such a command. Not for model-discovered skills.
68
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
This skill guides writing a slash command: ONE Markdown file in an IDE's commands directory that the user runs by typing /<name>. The file is the prompt the agent receives when the command runs.
When asking the user a choice (IDE, scope, examples to cover):
1., 2., …), not a heading, a bold-only line, or a paragraph.**Essence:** line under it says what would be done, to what, and what the reader gets. A short reply option with no analysis of its own (Apply / Skip / Edit) has no Essence line, and its title says it alone. Inside an option, name things in words, never by a report's ids. Every line of the option — title, Essence, Pros, Cons, Risks, Best for — is read without the report, and ids slip in most often in Pros, Cons and Risks. Write what the thing is instead of its label: "the checkout errand on the shop site", not E4; "the search box ignoring the first keystroke", not N3. A label in parentheses after a general phrase — "the two most expensive errands (E4, E3)" — is still a bare label: name each item. A number taken from a report keeps what it measures in the same sentence: a percentage names the whole it is a share of ("page text takes about 40% of the cost", not "a 40% share"), and a sum says whose cost it is. Any phrase that stands for a group is a pointer: a count ("the four slow pages", "the same three errands"), a category ("the anomalies", "the issues found"), a rank or superlative ("the costliest runs"), "these", "as above", "the current round" — and so is a partial list, a count followed by a few examples or a "such as". Replace it with every member of the group, named in words, in that option — even when the list is long, even when the report above already lists them; if the whole set does not fit, drop the group from the option. Test: with the report deleted, could the reader name every member from this option alone? A word coined in this session gets a short explanation in the option. An explanation elsewhere in the reply does not count — not in the report above the question, not in another option. Before sending, read each option alone, line by line, and list every label (letters plus digits such as E4 or N3), number, group phrase (a count, a category, a superlative, "the same", "these") and coined term in it; replace each with words or remove it.AskUserQuestion and the like) already offers a free-text answer of its own, so such an option adds a line and no choice. An option that names a concrete alternative is a real option, even when its title starts with "Other".agent's choice — on a multi-select where the user delegates with agent's choice (or its language equivalent), pick the subset yourself, justify the pick in one line, and proceed without re-asking for confirmation.**Essence:** line, then **Pros:**, **Cons:**, **Risks:** and **Best for:**, each on its own labelled line.<commands-dir>/<name>.md. The user starts it by name; the model does not pick it up on its own.SKILL.md directory. When the user wants a capability the model loads by itself from its description, or one that needs bundled scripts, references or assets, that is a skill: hand over to engineer-skill and say why.| IDE | Project command | User command | Format |
|---|---|---|---|
| Cursor | .cursor/commands/<name>.md | ~/.cursor/commands/<name>.md | Plain Markdown, no frontmatter. The text typed after /<name> is passed along with the file. |
| Claude Code | .claude/commands/<name>.md (or .claude/commands/<namespace>/<name>.md) | ~/.claude/commands/<name>.md | YAML frontmatter (description, argument-hint, allowed-tools, model, disable-model-invocation) + Markdown body. $ARGUMENTS, $1…$N |
| OpenCode | .opencode/commands/<name>.md | ~/.config/opencode/commands/<name>.md | YAML frontmatter (description, agent, model, subtask) + Markdown body. $ARGUMENTS, $1…$N, @filepath, bang-backtick shell output |
Claude Code also runs a bang-backtick pair (!shell command) that is preceded by whitespace while it expands a command, and a code span does not escape it. Use it only on purpose and with allowed-tools; otherwise keep the bang glued to the preceding character.
.cursor/ → Cursor, .opencode/ or opencode.json → OpenCode, .claude/commands/ or CLAUDE.md → Claude Code. A .claude/skills/ directory alone is NOT evidence of Claude Code: Cursor and OpenCode projects keep their skills there too.Skip this step only when real invocations are already on record — the exact words someone would type after /<name>. A feature list is not that: "starting/stopping services, viewing logs, rebuilding containers, checking health" is a spec, while /docker-compose rebuild api, "show me the logs for the db service" and "is everything up?" are invocations. Given a spec, draft the invocations yourself and have the user confirm, add or drop them before writing anything.
Invocations decide what the command must accept and what it must do with each input. Ask a few questions at a time; start with the most important ones.
For each confirmed invocation, decide:
$ARGUMENTS / $1 in Claude Code and OpenCode, the trailing text in Cursor;If an invocation needs a reusable script, reference material or a template, stop and propose a skill instead (see "What a Command Is").
Write <commands-dir>/<name>.md, where <name> is hyphen-case and is what the user types after /.
Claude Code:
---
description: <what the command does, as shown in the / menu>
argument-hint: '[action] [service]'
---
<Imperative instructions. Read the request from $ARGUMENTS.>OpenCode:
---
description: <what the command does>
---
<Imperative instructions. Read the request from $ARGUMENTS.>Cursor:
# <Command title>
<Imperative instructions. The request is the text typed after the command name.>Writing rules:
[, {, * or contain : — an unquoted argument-hint: [action] parses as a list.references/workflows.md and references/output-patterns.md.deno run -A scripts/validate_command.ts <path/to/name.md> --ide <claude|cursor|opencode>The script checks the file name, the frontmatter rules of the IDE (none for Cursor, a description and known keys for Claude Code and OpenCode), a non-empty body, and unintended Claude Code shell expansion. Fix every error it reports and run it again. Then tell the user how to run the command (/<name> …) and that the IDE may need a reload to list it.
After the user runs the command on real tasks, note where the agent went wrong or asked something the file should have answered, and change the body.
korchasa/flowai-plugins
240d92b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.