Create a command
A command is a prompt template, not a separate agent or a permission role. You need an open project and a CLI session. Create .lurus/commands/review-code.md:
---
description: Review the requested code without changing files
argumentHint: <file or module>
---
Review $ARGUMENTS for correctness and test coverage. Explain concrete findings with file references. Do not change files.
Restart the CLI after creating the file, then check:
/commands
/review-code src/example.ts
/commands lists the key, description, argument hint and source. The second invocation expands the template and submits a review request to the parent agent. “Do not change files” is an instruction, not an enforced write restriction. For an enforced boundary, use Ask mode or a custom agent.
The same file at ~/.lurus/commands/review-code.md is global. Global commands load first; a project command with the same key replaces the global one. review is already a built-in, so this example deliberately uses review-code.
Complete frontmatter reference
| Field | Example | Effect |
|---|---|---|
description | Review requested code | Description in the command list. |
argumentHint | <file or module> | Usage hint, not argument validation. |
allowedTools | [Read, Grep] | Does not restrict tools available in chat. Do not treat this field as a sandbox. |
model | A selection from /model | Changes the running parent model. No automatic restoration after the command and no global settings write at this point. |
disableModelInvocation | true | Displays the expanded template instead of the final model invocation. Embedded shell execution and a model change can already have happened. |
The parser normalizes camelCase, kebab-case and snake_case forms of these fields. mode and isolation are not supported command fields. Keep frontmatter small; allowedTools does not replace the permission system.
Arguments and namespaces
$ARGUMENTS: the entire argument string following the command.$1through$9: positional values; missing positions become empty strings.- Positional values are split again on whitespace, not with shell-aware quoting. Quoting a string does not reliably make it a single positional argument.
.lurus/commands/quality/review-code.mdbecomes/quality:review-code. The path and filename determine the lowercase key, not a display name.
Advanced example .lurus/commands/quality/compare.md:
---
description: Compare two modules
argumentHint: <first-path> <second-path>
---
Compare $1 and $2. Explain differences in behavior and tests.
Full request: $ARGUMENTS
/quality:compare src/old.ts src/new.ts
Expected result: both paths appear in the expanded prompt. This is text substitution, not a guaranteed file import or shell argument binding.
Embed shell output
Warning: Embedded shell commands execute before the model response and may have real side effects. disableModelInvocation: true is not a dry run for them. Use only trusted fixed commands and never interpolate user input.
Example .lurus/commands/status-review.md:
---
description: Review the current working-tree status
---
Current status:
!`git status --short`
Explain which areas need review. Do not modify files.
For a project source, the CLI asks before execution. “Once” applies to that invocation; “Always” is an in-memory, name-bound grant here, not a persistent hash-bound trust record. Global command sources skip this project-specific prompt. Only use deliberately trusted global shell templates.
Never interpolate user input into shell expressions. Use $ARGUMENTS in ordinary prompt text, not as shell code. disableModelInvocation: true is not a dry run for embedded shell execution. Shell execution is a real process action with possible side effects.
Loading, collisions and troubleshooting
/commands has no create, reload or remove subcommands. Extra arguments do not perform management operations. Edit files manually and start a new CLI session to reload reliably.
| Problem | Check |
|---|---|
| Command missing | Is the .md file under the current project CWD? Restarted? Using the path-derived key rather than the description? |
| Built-in runs instead | Avoid reserved names such as review; collisions are skipped. |
| Global text does not appear | A project file with the same key replaces the global source. |
| Arguments split incorrectly | Account for whitespace splitting; use $ARGUMENTS for free text. |
Agent can use more than allowedTools | This field does not restrict tools. Use modes, permissions or a custom-agent role. |
| Model remains changed | The model field is not temporary; check /model afterwards. |
Next: agents, skills, complete reference.