Skip to content

Writing agent types, skills and commands

Four kinds of plain files shape how malac works, without any code of its own:

File What it is Where
Agent type A reusable subagent role: instructions, tools, model ~/.malac/agents/*.md, <project>/.malac/agents/*.md
Skill Instructions for one kind of task, with any scripts it needs, loaded when it applies …/skills/<name>/SKILL.md
Slash command A prompt you run by name, /release-notes 2.0 …/commands/*.md, …/commands/*.toml
Instructions Standing rules for every session AGENTS.md; see Project context

The formats are the ones Claude Code, Gemini CLI and the Agent Skills specification use, so files you already have work as they are, and the ones you write work in those tools too. Plugins bundle all of them.

malac reads them when a tab loads. After changing them, open a new tab for the folder (Ctrl+T in the terminal UI) or run malac daemon restart. /context lists what was loaded.

An agent type is a role the agent can hand work to with agent_spawn. Here is a reviewer:

---
name: reviewer
description: Reviews uncommitted changes for bugs, missing tests and unclear code
tools: read, grep, glob, bash
---
You review the uncommitted changes in this repository. Start with `git diff` and
`git status`, then read enough of the surrounding code to judge each change in context.
Report only real problems, most severe first. For each one give the file and line,
what goes wrong and in which situation, and a concrete fix. Skip style preferences the
codebase does not already follow. If the change looks correct, say so in one sentence.
Do not modify any files.

Save it as .malac/agents/reviewer.md in a project, or ~/.malac/agents/reviewer.md for all projects. Plugins add agent types named <plugin>:<agent>.

Key Required Meaning
name no The type’s name. Defaults to the file name without .md.
description yes, in practice One line. The agent sees it and uses it to decide when to delegate.
model no Model for this role, as provider/model, for example lora/smart. Any other value, such as Claude Code’s sonnet, is ignored.
tools no Tool names, comma-separated or as a list. A name ending in * matches by prefix, such as browser_*. Claude Code’s names (Read, Grep, Bash, Edit, Write, WebFetch, TodoWrite, Task) map to malac’s tools. Without it, the role gets every tool.

The body becomes a Role section of the subagent’s system prompt, after malac’s own instructions.

Agent types are listed (name and description) in the system prompt of every agent that may still delegate. The agent picks one by passing agent: "reviewer" to agent_spawn, usually when the task matches the description, or when you ask: “have the reviewer look at my changes”.

  • The subagent’s model is the model argument of the call, else the type’s model, else the main model.
  • tools limits what the role can use. Permission checks still apply on top: a reviewer with bash still asks before running commands in ask mode.
  • A project type with the same name as a user type wins.
  • tester: runs the test suite, reports failures with the failing assertion and a likely cause. tools: read, grep, glob, bash.
  • researcher: answers questions about the codebase without changing anything. tools: read, grep, glob, web_fetch.
  • browser: drives a web app through the control service. tools: browser_*, read.

A skill is a folder with a SKILL.md: a name and a description, then instructions for one kind of task. It may ship scripts/, references/ and assets/ next to it.

.malac/skills/changelog/
├── SKILL.md
├── scripts/commits.sh
└── references/format.md
---
name: changelog
description: Write a changelog entry from the commits since the last tag
---
1. Run `sh "$SKILL_DIR/scripts/commits.sh"` to list the commits since the last tag.
2. Group them under Added, Changed and Fixed, following `references/format.md`.
Drop merge commits and chores.
3. Add the entry to `CHANGELOG.md` under a new heading with today's date.

The system prompt lists each skill’s name and description. When a task fits, the agent loads the skill with the skill tool, which returns its instructions and the list of its files. From then on its bash commands have SKILL_DIR set to the skill’s folder, so scripts run as sh "$SKILL_DIR/scripts/x.sh", through the usual permission checks. References are read with read when the instructions call for them, so a long skill costs nothing until it is used.

Every skill is also a slash command: /changelog loads it and runs it now, with anything after the name as $ARGUMENTS.

malac reads skills from these folders, in this order; when two have the same name, the later one wins:

  1. ~/.malac/skills/
  2. ~/.claude/skills/
  3. ~/.agents/skills/
  4. <project>/.agents/skills/
  5. <project>/.claude/skills/
  6. <project>/.malac/skills/

Skills from plugins are named <plugin>:<skill>. name defaults to the folder name.

Key Meaning
name The skill’s name: lowercase letters, digits and single hyphens
description When to use it. The agent decides from this line alone, so make it specific.
argument-hint What the slash command takes, shown in completion, for example <version>
disable-model-invocation: true Keep it out of the prompt, so only /<name> runs it
user-invocable: false Keep it from being a slash command

$SKILL_DIR, ${CLAUDE_SKILL_DIR} and ${CLAUDE_PLUGIN_ROOT} in the instructions are written in as paths. allowed-tools is not used: approvals work as for any tool call.

Besides the built-in commands, /name arguments runs a command of your own. The command’s text goes to the agent after what you typed.

Markdown commands, in Claude Code’s format, from ~/.malac/commands/, ~/.claude/commands/, <project>/.claude/commands/, <project>/.malac/commands/ and plugins:

---
description: Draft release notes for a version
argument-hint: <version>
---
Draft release notes for version $ARGUMENTS from the commits since the previous tag.
Group them by user-visible change, and leave out refactors and chores.

Saved as .malac/commands/release-notes.md, it runs as /release-notes 2.0. $ARGUMENTS is everything after the name, and $1 to $9 are its words.

TOML commands, in Gemini CLI’s format, from ~/.gemini/commands/, <project>/.gemini/commands/ and plugins:

.gemini/commands/git/commit.toml
description = "Write a commit message for the staged changes"
prompt = "Write a commit message for the staged changes. Context: {{args}}"

Folders become namespaces: git/commit.toml runs as /git:commit. Plugin commands are named <plugin>:<command>, and the part after : works alone when no other command has it.

!`command` lines and @file references inside commands are not expanded. Typing / in the terminal UI lists your commands with the built-in ones.

Use When
AGENTS.md A rule that applies to every task in a project
A skill A procedure for one kind of task that the agent should follow when it fits, with scripts if it needs them
A slash command A prompt you run often, by name, with arguments
An agent type Work you want done in a separate context, often in parallel, with its own tools or model
Memory A fact the agent learned and should remember, saved by the agent itself

The tutorial Customizing malac builds an agent type and a skill step by step. To share them, put them in a plugin.

malac is created by lobirus and released under the MIT license. About malac