Skip to content

Handbook

Custom commands

Create reusable Markdown slash commands, substitute arguments and deliberately constrain shell execution.

Reviewed CLI source version: 2.4.0 · Editorial update:

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

FieldExampleEffect
descriptionReview requested codeDescription 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.
modelA selection from /modelChanges the running parent model. No automatic restoration after the command and no global settings write at this point.
disableModelInvocationtrueDisplays 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.
  • $1 through $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.md becomes /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.

ProblemCheck
Command missingIs the .md file under the current project CWD? Restarted? Using the path-derived key rather than the description?
Built-in runs insteadAvoid reserved names such as review; collisions are skipped.
Global text does not appearA project file with the same key replaces the global source.
Arguments split incorrectlyAccount for whitespace splitting; use $ARGUMENTS for free text.
Agent can use more than allowedToolsThis field does not restrict tools. Use modes, permissions or a custom-agent role.
Model remains changedThe model field is not temporary; check /model afterwards.

Next: agents, skills, complete reference.

A deliberate choice

Before your first prompt.

Interactive demo
Lurus Codeprivacy-demo · illustrative workspace

Demo session ready. Your model choice and data route are separate decisions.

Illustrative scenario. No real sign-in, security test or code transmission takes place.

Image preview