# Custom Slash Commands

Extend the CLI with reusable Markdown prompts or executable scripts that run from the chat input.

Custom slash commands turn repeatable prompts or scripts into `/shortcuts` that you can run from chat. Droid scans `.factory/commands` folders and turns each registered file into a command.

<Note>
For new reusable workflows, prefer [Skills](/harness/skills); existing `.factory/commands` files keep working.
</Note>

## Discovery and naming

| Scope | Location | Purpose |
| ----- | -------- | ------- |
| **Workspace** | `<repo>/.factory/commands` | Project-specific commands shared with teammates. Overrides a personal command with the same slug. |
| **Personal** | `~/.factory/commands` | Private or cross-project shortcuts available across sessions. |

A file is registered only when it matches one of these rules:

- It ends with `.md`.
- Its first line starts with a `#!` shebang.

Filenames are slugged: lowercase, spaces and non-URL characters become `-`, and the extension is dropped. `Code Review.md` becomes `/code-review`.

Command files may be nested in subdirectories; Droid discovers them recursively. Invoke a command with `/command-name optional arguments`. Run `/commands` to open the Custom Commands manager for browsing, reloading, or importing.

## Markdown commands

Markdown files render as a system notification that seeds Droid's next turn. Optional YAML frontmatter sets autocomplete metadata.

| Frontmatter key | Purpose |
| --------------- | ------- |
| `description` | Overrides the generated summary shown in slash suggestions. |
| `argument-hint` | Appends inline usage hints, such as `/code-review <branch-name>`. |

Tool scoping is not available for custom commands. Use [Skills](/harness/skills) or [Custom Droids](/harness/subagents) for tool policy.

`$ARGUMENTS` expands to everything typed after the command name. If you do not reference it, the body is sent unchanged.

<Note>
Positional placeholders like `$1` or `$2` are not supported in Markdown commands. Use `$ARGUMENTS` and parse the input inside the prompt.
</Note>

<Tip>
Markdown output is wrapped in a system notification so the next agent turn immediately sees the prompt.
</Tip>

## Executable commands

Executable files must start with a valid shebang so the CLI can call the interpreter.

```bash
#!/usr/bin/env bash
set -euo pipefail

echo "Preparing $1"
npm install
npm run lint
echo "Ready to deploy $1"
```

- The executable receives positional arguments (`/deploy feature/login` sets `$1=feature/login`).
- The script runs from the current working directory and inherits your environment.
- Stdout and stderr (up to 64 KB) plus the script contents are posted back to the chat transcript for transparency. Failures still surface their logs.

## Managing commands

{/* sweep-allow: term-bullets */}

- **Edit or add** files directly in `.factory/commands`. In `/commands`, press `R` to reload, `I` to import, or `Esc` to close.
- **Import** existing `.agents` or `.claude` commands: open `/commands`, press `I`, then use `Space` to select, `A` to toggle all, `Enter` to import, and `B` or `Esc` to return. Import scans `.agents/commands` and `.claude/commands` at the repo root and in `~`. It copies only `.md` files and skips files that already exist in `.factory/commands`.
- **Remove** a command by deleting its file. Workspace commands take precedence, so deleting the repo version reveals the personal fallback if one exists.

## Examples

### Review checklist

```markdown
---
description: Send a structured code review checklist
argument-hint: <branch-or-PR>
---

Review `$ARGUMENTS` and respond with:

1. Summary of what changed and why it matters.
2. Correctness checks: tests, edge cases, and regressions.
3. Risks: security, performance, or migration concerns.
4. Follow-up TODOs with file paths and owners.
```

Run `/review feature/login-flow` to seed Droid with a consistent checklist.

### Deploy helper

```bash
#!/usr/bin/env bash
set -euo pipefail

target=${1:-"src"}

echo "Running lint and tests for $target"
npm run lint -- "$target"
npm test -- --runTestsByPath "$target"

git status --short
echo "Done"
```

Saved as `deploy.sh`, this shows up as `/deploy`. Pass a path (`/deploy src/widgets`) to constrain the checks and share the aggregated output in the thread.
