You can create your own commands to automate workflows and combine multiple built-in or user-defined commands into a single, reusable command. ## How it works User-defined commands are YAML blocks in markdown files inside the `Steward/Commands` folder. Each command can specify a sequence of steps to execute. These commands are available with autocomplete and work just like built-in commands. For why Steward uses YAML fences in notes (instead of separate config files or frontmatter only), see [YAML blocks in markdown](YAML-blocks-in-markdown). ## Basic structure Create a note in `Steward/Commands` and add your command YAML in a code block: ```yaml command_name: clean-up description: Example — one-line summary for Help. query_required: false model: gpt-4o # Optional: Specify a default model for all steps steps: - name: search query: 'Notes name starts with Untitled or with tag #delete' - name: vault query: 'Delete them' model: gpt-3.5-turbo # Optional: Override the model for this specific step ``` For commands that require user input: ```yaml command_name: ask description: General Q&A using instructions linked below. query_required: true tools: - switch_agent_capacity system_prompt: - '[[#Instructions]]' steps: - query: '$from_user' ``` ## Key fields ### Command-level fields | Field | Required | Description | | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `command_name` | Yes | The name to invoke your command (e.g., `/clean-up`) | | `description` | No | Short text shown next to the command in `/ Help` (and similar listings) | | `query_required` | No | If `true`, the command requires user input after the prefix | | `model` | No | The model to use for all steps in this command | | `system_prompt` | No | Additional system prompts that apply to all steps (see [Adding system prompts](#adding-system-prompts)) | | `tools` | No | Super Agent tool names allowed for this command; omit for full set. Example: `[switch_agent_capacity]` for chat-only until the user enables full tools. If more than five tools are listed, `activate_tools` is added when missing. | | `hidden` | No | If `true`, the command will not appear in the command menu | | `triggers` | No | Automatically execute commands when files match specified criteria (see [Automated triggers](#automated-triggers)) | | `cli` | No | Shell settings for commands that use the shell tool (see [CLI settings](#cli-settings)) | | `steps` | Yes | The sequence of built-in or user-defined commands to execute | ### Step-level fields | Field | Required | Description | | --------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | No | The step name (e.g., `read`, `edit`, `search`, `vault`, `generate`). Activates the corresponding tools for this step. Use `generate` for direct AI responses without tools. | | `system_prompt` | No | Additional system prompts for this step (see [Adding system prompts](#adding-system-prompts)) | | `query` | Conditional | The query to send to Steward. Use `$from_user` as a placeholder for user input. Required if `query_required` is `true`. | | `model` | No | The model to use for this step (overrides command-level model) | | `no_confirm` | No | If `true`, skips confirmation prompts for this step | ## Adding system prompts Steward uses a single agent (SuperAgent) whose core system prompt is not editable. However, you can **add** system prompts using the `system_prompt` field. These are appended to the core system prompt, allowing you to provide extra context or instructions. You can limit tools to **direct response** mode by setting `tools: [switch_agent_capacity]` so the user can confirm switching to the full agent when needed. ### Root-level system prompt Applies to **all steps** in the command: ```yaml command_name: my_command system_prompt: - '[[#Guidelines]]' # Link to a heading in the current note - 'Always use formal language' steps: - query: | Read the content above and help me with: $from_user ``` ### Step-level system prompt Applies only to a **specific step** (root-level prompts are applied first, then step-level): ```yaml steps: - name: generate system_prompt: - '[[My Context Note]]' # Link to a note (content will be included) - 'Focus on technical details' - 'Provide examples' query: $from_user ``` ### Using links in system prompts Reference the content of other notes in your vault using Obsidian links: | Syntax | Behavior | | ----------------------- | ------------------------------------------------------------------------------ | | `[[Note Name]]` | Full content of the linked note | | `[[Note Name#Heading]]` | Content under a specific heading in the linked note | | `[[#Heading]]` | Content under a heading in the **current note** (where the command is defined) | You can update the linked notes independently of your command definition. ## CLI settings Commands that use the **shell** tool can define a root-level `cli` block to customize the local shell and to auto-approve specific model shell lines without a confirmation prompt. ```yaml command_name: explain-video cli: shell: /bin/zsh # optional whitelist: - 'yt-dlp*' - 'Get-Content*' - 'rm *_temp_transcript*' tools: - shell steps: - query: '$from_user' ``` ### `cli.shell` Optional shell executable used when Steward starts a new session for this command. If omitted, Steward uses your global CLI shell setting. ### `cli.whitelist` Optional list of patterns (up to 50). When the agent sends a shell command in **transcript mode**, a matching pattern skips the “run this command?” confirmation. Patterns are matched against the **trimmed** command line: | Pattern | Matches | | -------- | ----------------------------------------------------- | | No `*` | Exact string only (`pwd` matches `pwd`, not `pwd -L`) | | With `*` | Glob-style: each `*` matches any run of characters | Examples: - `Get-Content*` — prefix match (`Get-Content foo`, `Get-Content "a.txt"`) - `rm *_temp_transcript.en.srt` — `rm` with optional flags before that file - `rm *_temp_transcript*` — `rm` commands that reference `_temp_transcript` anywhere - `*_temp_transcript.en.srt` — any command that includes that filename Restrictions: - Each entry must include at least one literal (non-`*`) character. - Empty shell lines never match. - Commands that run in **interactive terminal mode** always require confirmation, even if whitelisted. ## Automated triggers Commands can automatically execute when file events occur: ```yaml command_name: generate_flashcards query_required: false triggers: - events: [modify] patterns: tags: '#flashcard-gen' steps: - name: read query: 'Read the content of $file_name' - name: edit query: | Generate flashcards from this note content. Format each flashcard as: Q: [question] A: [answer] --- Append the flashcards at the end of the note under a "## Flashcards" heading. ``` ### Trigger fields | Field | Required | Description | | ---------- | -------- | -------------------------------------------------------- | | `events` | Yes | List of events to watch: `create`, `modify`, `delete` | | `folders` | No | Folder paths to watch (e.g., `["Inbox", "Daily Notes"]`) | | `patterns` | No | Pattern matching criteria (all must match) | **Pattern fields:** | Field | Description | | ---------------- | --------------------------------------------------------------------------------------- | | `tags` | Tags to match (e.g., `["#todo", "#review"]` or `"#todo"`) | | `content` | Regex pattern to match file content | | _(any property)_ | Any frontmatter property name (e.g., `status: "draft"`, `priority: ["high", "urgent"]`) | ### How triggers work 1. When a file event occurs (create/modify/delete), the system checks all trigger conditions. 2. For `modify` events, the system waits for the metadata cache to update, then checks if patterns are **newly added**. 3. If all patterns match and are new (for modify events), a conversation note is created automatically. 4. The triggered command executes in this conversation note. ## Placeholders These placeholders are replaced with actual values when the command executes: | Placeholder | Description | | -------------- | -------------------------------------- | | `$file_name` | The file name that triggered a command | | `$from_user` | User input | | `$steward` | Steward folder path | | `$active_file` | Current active file path | ## Community commands The plugin ships a catalog of ready-to-use commands maintained in the [obsidian-steward](https://github.com/googlicius/obsidian-steward) repository (`community-UDCs`). You can **browse the catalog, install new commands, and update ones you already have** from the Steward chat. ### Browse and install from chat 1. Run **`/ Help`** or **`/ ?`**. 2. Click **Browse community commands** under the User-defined commands section. 3. The table lists each published bundle (one row can include several slash commands if they share the same markdown note). Columns include: - **Your version** — read from the `version` field in the installed note’s frontmatter (or shown as not installed). - **Latest version** — the version bundled with your plugin build for that catalog entry. - **Actions** — status (**Not installed**, **Installed**, or **Update available**), plus: - **Install** / **Update** / **Reinstall** — runs the built-in **`/update-command`** user-defined command with a JSON payload so the agent can download the correct files from GitHub and move them into `Steward/Commands` (including optional subfolders such as `Video/` when the catalog specifies them). - **View** — opens the raw source file on GitHub for reading or verification. Installing or upgrading runs **`/update-command`** with full agent tools (including shell) so the model can download files from GitHub into a temporary folder and move them into `Commands`. Approve those tool steps if prompted. ### Manual setup You can still copy command markdown into `Steward/Commands` yourself. The in-chat catalog is optional convenience on top of that workflow. ## Tips - From **`/ Help`**, use **Browse community commands** to install or refresh catalog commands without copying files from the repo manually. - Ask the AI to use the `todo_list` tool for complex tasks to get more deterministic results. - Link system prompts to a heading in the current note (e.g., `[[#Instructions]]`) to keep your prompts alongside the command definition. This makes editing easier and lets you use full markdown formatting. - Test your commands thoroughly by fine-tuning system prompts, providing constructed outputs, one or few-shot examples, and iterating until they work as expected. - Use the User-defined-commands skill at `@skills/user-defined-command/SKILL.md` to build commands with partial AI round trips.