Skills System & Multi-Agent Context
Skills are reusable instruction templates that extend the agent without touching source code. They live as SKILL.md files and are invoked in the TUI with a /skill-name [args] slash command.
Directory layout
Section titled “Directory layout”~/.umbra/skills/ ← global skills (available in every project) deploy/ SKILL.md summarise/ SKILL.md
<project>/.umbra/skills/ ← project-local skills (override global on name collision) test-watch/ SKILL.mdEach skill lives in its own named subdirectory. The subdirectory name becomes the skill name if the frontmatter omits name:. Project-local skills take precedence over global ones with the same name.
SKILL.md format
Section titled “SKILL.md format”---name: deploydescription: Deploy the project to the staging environmentargument-hint: <environment>disable-model-invocation: false---
Deploy $1 environment.
Current git status:!`git status --short`
Run the deploy script and confirm the service is healthy.Frontmatter fields:
| Field | Required | Description |
|---|---|---|
name | No (falls back to dir name) | Lowercase a–z, 0–9, hyphens; max 64 chars; no leading/trailing/consecutive hyphens |
description | Yes | One-line summary; shown in TUI autocomplete and injected into the system prompt |
argument-hint | No | Placeholder shown in autocomplete, e.g. <branch-name> |
disable-model-invocation | No | true → skill is user-invocable only; not listed in the LLM system prompt |
Argument substitution
Section titled “Argument substitution”| Pattern | Expands to |
|---|---|
$1, $2, $3 | First, second, third space-separated word |
$ARGUMENTS or $@ | All arguments joined as a single string |
${@:2} | All args from position 2 onward |
${@:2:3} | Args 2 through 4 (bash-style slice) |
Choosing between $1 and $ARGUMENTS: use $1/$2 only when the skill has clearly distinct positional flags (e.g. branch name + environment). For natural-language input (“find the bug in the auth module”), always use $ARGUMENTS — splitting a sentence into $1 $2 produces garbage.
Shell injection
Section titled “Shell injection”Commands embedded in the skill body are executed at invocation time, before the content is sent to the model. The output replaces the injection marker.
Inline: !`command` — single-line output
Block:
```!git log --oneline -10```Both forms run with the agent’s current cwd (10-second timeout). Errors produce [shell error: ...] inline instead of aborting.
How invocation works
Section titled “How invocation works”User types: /deploy staging
1. Parse args: ["staging"]2. substituteArgs(content, ["staging"]) → $1 → "staging"3. expandShellInjections(content, cwd) → !`git status` → actual output4. Prepend: "The user ran: /deploy staging\nExecute the following skill instructions now:\n\n..."5. Send as the user message to the agent loopSystem prompt integration
Section titled “System prompt integration”At the start of each run, formatSkillsForPrompt() injects an <available_skills> XML block into the system prompt listing every skill where disable-model-invocation is not true. This lets the model know which skills exist and suggest them autonomously when relevant:
<available_skills> <skill> <name>deploy</name> <description>Deploy the project to the staging environment</description> <location>/home/user/.umbra/skills/deploy/SKILL.md</location> </skill></available_skills>Skills with disable-model-invocation: true are excluded from this block — they are user-only shortcuts and the model cannot suggest them.
TUI autocomplete
Section titled “TUI autocomplete”Typing / in the TUI input field opens the skill picker. The argument-hint value is shown as a placeholder after the skill name. Skills are listed alphabetically with their description. The picker is fuzzy-searchable.