Contents
Overview
robotter composes GenAI "dotfiles" (the instruction/configuration files read by AI coding agents) from a single source template.
Different agents read their configuration from different locations under different filenames. robotter renders one Jinja2 template and writes the result to the appropriate location(s) for a target agent, at either global (user-level) or project scope:
| Agent | Value | Project Configuration | Global Configuration |
|---|---|---|---|
| Claude Code | claude-code |
AGENTS.md |
~/.claude/AGENTS.md |
| Cline | cline |
.clinerules/main.md |
~/Documents/Cline/Rules/main.md |
| Cursor | cursor |
.cursor/rules/main.mdc |
~/.cursor/rules/main.mdc |
| Gemini CLI | gemini-cli |
GEMINI.md |
~/.gemini/GEMINI.md |
| GitHub Copilot | github-copilot |
.github/copilot-instructions.md |
<VS Code user>/prompts |
| Grok | grok |
AGENTS.md |
~/.grok/AGENTS.md |
| OpenAI Codex | openai-codex |
AGENTS.md |
~/.codex/AGENTS.md |
| OpenCode | opencode |
AGENTS.md |
~/.config/opencode/AGENTS.md |
Some agents also support "skills" — reusable instruction sets stored under a per-skill location, keyed by a skill name. robotter writes rendered skills to the appropriate location(s) for those agents:
| Agent | Value | Project Skill | Global Skill |
|---|---|---|---|
| Claude Code | claude-code |
.claude/skills/<name>/SKILL.md |
~/.claude/skills/<name>/SKILL.md |
| Cline | cline |
.cline/skills/<name>/SKILL.md |
~/.cline/skills/<name>/SKILL.md |
| Cursor | cursor |
.cursor/skills/<name>/SKILL.md |
~/.cursor/skills/<name>/SKILL.md |
| Gemini CLI | gemini-cli |
.gemini/skills/<name>/SKILL.md |
~/.gemini/skills/<name>/SKILL.md |
| GitHub Copilot | github-copilot |
.github/skills/<name>/SKILL.md |
~/.copilot/skills/<name>/SKILL.md |
| Grok | grok |
.grok/skills/<name>/SKILL.md |
~/.grok/skills/<name>/SKILL.md |
| OpenAI Codex | openai-codex |
.agents/skills/<name>/SKILL.md |
~/.agents/skills/<name>/SKILL.md |
| OpenCode | opencode |
.opencode/skills/<name>/SKILL.md |
~/.config/opencode/skills/<name>/SKILL.md |
Templates may include optional YAML frontmatter (preserved in the rendered output) and may compose other templates via the include_configuration("<relative path>") function, letting you maintain shared content once and assemble agent-specific files from it (see Example Configuration and Example Skill below).
Only files whose names include a .jinja or .jinja2 extension are rendered as Jinja2 templates. The extension does not have to be the last one, so instructions.jinja.md is a template. Every other file is written verbatim, which means content such as {{ ... }} is preserved as-is.
When rendering globally, a file that is not a template is installed as a symbolic link to its source, so edits to the source take effect without rendering again. Templates are always written as files, and project-level rendering always copies. Pass --copy to copy non-template files instead of linking them. If a symbolic link cannot be created (for example, on Windows without Developer Mode or administrator rights), rendering fails; pass --copy to render anyway.
How to use robotter
Render a template to an agent's configuration location(s):
uvx robotter render <template> <agent> [<dir>] [--copy] [--verbose] [--debug]
| Argument / Option | Description |
|---|---|
<template> |
Path to the template file to render. |
<agent> |
Target agent: claude-code, cline, cursor, gemini-cli, github-copilot, grok, openai-codex, or opencode. |
<dir> |
Render project-level configuration under this directory. When omitted, global (user-level) configuration is rendered. |
--copy |
Copy a non-template file instead of creating a symbolic link to it when rendering globally. Project-level rendering always copies. |
--verbose |
Write verbose information to the terminal. |
--debug |
Write debug information to the terminal. |
Examples
Render instructions.jinja.md to the current user's global Claude Code configuration:
uvx robotter render instructions.jinja.md claude-code
Render instructions.jinja.md to the project-level OpenCode configuration under ./my-project:
uvx robotter render instructions.jinja.md opencode ./my-project
Example Configuration
A configuration file is a Jinja2 template with optional YAML frontmatter. Use the include_configuration("<relative path>") function to compose shared content from another configuration file, letting you maintain that content once and reuse it across multiple templates.
The following instructions.jinja.md template includes a shared shared/coding-standards.md file:
---
description: Instructions for AI coding agents
---
# Project Instructions
## Overview
This project composes GenAI dotfiles from a single source template.
## Coding Standards
{{ include_configuration("shared/coding-standards.md") }}
The included shared/coding-standards.md file is not a template, so its content is included verbatim (its frontmatter, if any, is ignored when included):
- Prefer clarity over cleverness.
- Write tests for all new functionality.
- Document public interfaces.
The path passed to include_configuration is resolved relative to the file that contains the call, so a template in one directory can include a file located in a subdirectory ("shared/coding-standards.md") or a parent directory ("../coding-standards.md"). Included files may themselves call include_configuration, allowing configuration to be composed from arbitrarily nested fragments.
Rendering the instructions.jinja.md template above produces the following output (the frontmatter is preserved; the include_configuration call is replaced with the rendered content of the included file):
---
description: Instructions for AI coding agents
---
# Project Instructions
## Overview
This project composes GenAI dotfiles from a single source template.
## Coding Standards
- Prefer clarity over cleverness.
- Write tests for all new functionality.
- Document public interfaces.
Rendering a skill
Some agents support "skills" — reusable instruction sets stored under a per-skill location. Render a skill template to an agent's skill location(s):
uvx robotter render_skill <template> <agent> [<dir>] [--copy] [--verbose] [--debug]
| Argument / Option | Description |
|---|---|
<template> |
Path to the skill template file to render, or to a skill template directory whose files are each rendered into a skill named after the directory. |
<agent> |
Target agent: claude-code, cline, cursor, gemini-cli, github-copilot, grok, openai-codex, or opencode. |
<dir> |
Render the project-level skill under this directory. When omitted, the global (user-level) skill is rendered. |
--copy |
Copy non-template files instead of creating symbolic links to them when rendering globally. Project-level rendering always copies. |
--verbose |
Write verbose information to the terminal. |
--debug |
Write debug information to the terminal. |
When <template> is a file, the skill name is taken from its frontmatter name attribute (required); the rendered output is written to the per-skill location derived from that name (see the table in the Overview above). When <template> is a directory, the directory name is the skill name and frontmatter is not consulted for it — see Skill template directories below. Not every agent supports skills; render_skill fails for an agent that does not.
Example Skill
A single-file skill template is a Jinja2 template with YAML frontmatter that must include a name attribute; that name determines the per-skill location the rendered output is written to. Like a configuration template, a skill template may compose shared content via include_configuration("<relative path>").
The following review_skill.jinja.md skill template declares its name in frontmatter and reuses the shared shared/coding-standards.md file from the Example Configuration above. Note that the template filename (review_skill.jinja.md) and the name attribute (review) are independent — for a single-file template the rendered output location is derived from name, not the filename:
---
name: review
description: Review changes before committing
---
# Review
Review the pending changes before committing, confirming they satisfy the project's coding standards:
{{ include_configuration("shared/coding-standards.md") }}
Rendering the template preserves the frontmatter and replaces the include_configuration call with the rendered content of the included file, producing the following SKILL.md:
---
name: review
description: Review changes before committing
---
# Review
Review the pending changes before committing, confirming they satisfy the project's coding standards:
- Prefer clarity over cleverness.
- Write tests for all new functionality.
- Document public interfaces.
Examples
Render review_skill.jinja.md to the current user's global Claude Code skill location (~/.claude/skills/review/SKILL.md):
uvx robotter render_skill review_skill.jinja.md claude-code
Render review_skill.jinja.md to the project-level Claude Code skill under ./my-project (./my-project/.claude/skills/review/SKILL.md):
uvx robotter render_skill review_skill.jinja.md claude-code ./my-project
Skill Template Directories
A skill that needs supporting files — additional instructions, scripts, data — can be authored as a directory instead of a single file. Pass the directory as <template> and every file beneath it is written into one skill named after the directory:
review/
├── SKILL.jinja.md
├── reference.md
└── scripts/
└── check.py
Rendering that directory for Claude Code produces ~/.claude/skills/review/SKILL.md, ~/.claude/skills/review/reference.md, and ~/.claude/skills/review/scripts/check.py. The nested structure is preserved, and the .jinja/.jinja2 extension is removed from each template's output filename (SKILL.jinja.md is written as SKILL.md).
Directory templates differ from single-file templates in the following ways:
| Single file | Directory | |
|---|---|---|
| Skill name | The frontmatter name attribute (required) |
The directory name; frontmatter is not consulted for the name |
| Files written | One | Every file beneath the directory, recursively |
| Required content | — | Must produce SKILL.md at its top level (SKILL.md or, for example, SKILL.jinja.md) |
Template files (those with a .jinja or .jinja2 extension) are rendered with frontmatter preserved exactly as it is for a single-file template. Every other file is reproduced byte for byte (linked when rendering globally, copied otherwise), so images, scripts, and data files are never corrupted by having a leading --- consumed as frontmatter. Symbolic links are created before any template is written, so a host that cannot create them fails without writing any files.
All files are rendered before any file is written, so a malformed template fails without leaving a partially installed skill behind. A failure during the writes themselves (a permission error, a full disk) can still leave the skill incomplete.
render_skill fails, writing nothing, when the directory is empty, when it does not produce a top-level SKILL.md, when multiple files produce the same output filename (for example, SKILL.md and SKILL.jinja.md), when a file's output name matches a directory (for example, scripts.jinja and scripts/run.py), or when the directory name is not a valid skill name.
Examples
Render the review/ directory to the current user's global Claude Code skill location (~/.claude/skills/review/):
uvx robotter render_skill review claude-code
Render the review/ directory to the project-level Claude Code skill under ./my-project (./my-project/.claude/skills/review/):
uvx robotter render_skill review claude-code ./my-project
Editing an agent's configuration
Open an agent's rendered configuration file in an editor:
uvx robotter edit <agent> [<dir>] [--verbose] [--debug]
| Argument / Option | Description |
|---|---|
<agent> |
Target agent: claude-code, cline, cursor, gemini-cli, github-copilot, grok, openai-codex, or opencode. |
<dir> |
Edit project-level configuration under this directory. When omitted, global (user-level) configuration is edited. |
--verbose |
Write verbose information to the terminal. |
--debug |
Write debug information to the terminal. |
The configuration file must already exist (for example, produced by a prior render); edit fails if it does not. The editor is selected from the VISUAL or EDITOR environment variable when set, otherwise the operating system's default handler for the file is used.
Examples
Edit the current user's global Claude Code configuration:
uvx robotter edit claude-code
Edit the project-level OpenCode configuration under ./my-project:
uvx robotter edit opencode ./my-project
Editing a skill
Open an agent's rendered skill file in an editor:
uvx robotter edit_skill <name> <agent> [<dir>] [--verbose] [--debug]
| Argument / Option | Description |
|---|---|
<name> |
Name of the skill to edit (for a single-file template, the name declared in its frontmatter; for a skill template directory, the directory name). |
<agent> |
Target agent: claude-code, cline, cursor, gemini-cli, github-copilot, grok, openai-codex, or opencode. |
<dir> |
Edit the project-level skill under this directory. When omitted, the global (user-level) skill is edited. |
--verbose |
Write verbose information to the terminal. |
--debug |
Write debug information to the terminal. |
The skill file must already exist (for example, produced by a prior render_skill); edit_skill fails if it does not. The editor is selected from the VISUAL or EDITOR environment variable when set, otherwise the operating system's default handler for the file is used. Not every agent supports skills; edit_skill fails for an agent that does not.
Examples
Edit the current user's global Claude Code review skill (~/.claude/skills/review/SKILL.md):
uvx robotter edit_skill review claude-code
Edit the project-level Claude Code review skill under ./my-project (./my-project/.claude/skills/review/SKILL.md):
uvx robotter edit_skill review claude-code ./my-project
Browsing an agent's global configuration
Open an agent's global (user-level) configuration directory in a file browser:
uvx robotter browse <agent> [--verbose] [--debug]
| Argument / Option | Description |
|---|---|
<agent> |
Target agent: claude-code, cline, cursor, gemini-cli, github-copilot, grok, openai-codex, or opencode. |
--verbose |
Write verbose information to the terminal. |
--debug |
Write debug information to the terminal. |
The directory is opened using the operating system's default file browser. The directory must already exist (for example, produced by a prior render); browse fails if it does not.
Example
Browse the current user's global Claude Code configuration directory:
uvx robotter browse claude-code
Browsing an agent's skills
Open an agent's skills directory in a file browser:
uvx robotter browse_skills <agent> [<dir>] [--verbose] [--debug]
| Argument / Option | Description |
|---|---|
<agent> |
Target agent: claude-code, cline, cursor, gemini-cli, github-copilot, grok, openai-codex, or opencode. |
<dir> |
Browse the project-level skills directory under this directory. When omitted, the global (user-level) skills directory is browsed. |
--verbose |
Write verbose information to the terminal. |
--debug |
Write debug information to the terminal. |
The directory is opened using the operating system's default file browser. The directory must already exist (for example, produced by a prior render_skill); browse_skills fails if it does not. Not every agent supports skills; browse_skills fails for an agent that does not.
Examples
Browse the current user's global Claude Code skills directory (~/.claude/skills):
uvx robotter browse_skills claude-code
Browse the project-level Claude Code skills directory under ./my-project (./my-project/.claude/skills):
uvx robotter browse_skills claude-code ./my-project
Installation
Note that it isn't necessary to install robotter when running via uvx.
| Installation Method | Command |
|---|---|
| Via uv | uv add robotter |
| Via pip | pip install robotter |
Verifying Signed Artifacts
Artifacts are signed and verified using py-minisign and the public key in the file ./minisign_key.pub.
To verify that an artifact is valid, visit the latest release and download the .minisign signature file that corresponds to the artifact, then run the following command, replacing <filename> with the name of the artifact to be verified:
uv run --with py-minisign python -c "import minisign; minisign.PublicKey.from_file('minisign_key.pub').verify_file('<filename>'); print('The file has been verified.')"
Development
Please visit Contributing and Development for information on contributing to this project.
Additional Information
Additional information can be found at these locations.
| Title | Document | Description |
|---|---|---|
| Code of Conduct | CODE_OF_CONDUCT.md | Information about the norms, rules, and responsibilities we adhere to when participating in this open source community. |
| Contributing | CONTRIBUTING.md | Information about contributing to this project. |
| Development | DEVELOPMENT.md | Information about development activities involved in making changes to this project. |
| Governance | GOVERNANCE.md | Information about how this project is governed. |
| Maintainers | MAINTAINERS.md | Information about individuals who maintain this project. |
| Security | SECURITY.md | Information about how to privately report security issues associated with this project. |
License
robotter is licensed under the MIT license.
Release files for robotter 0.21.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| robotter-0.21.0.tar.gz | 17.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| robotter-0.21.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.4 kB
Release files / robotter-0.21.0.tar.gz
| Download URL | robotter-0.21.0.tar.gz |
|---|---|
| Size | 17.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3f7070c543f3f878c935fe673df40a13452382cdb84903a37a102b4913da9282
|
|
BLAKE2b-256 checksum How to use checksums |
9626d53106b2cbe836faac39caa97ccc6e1ae20291365023d9850c5f49fb2b4f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / robotter-0.21.0-py3-none-any.whl
| Download URL | robotter-0.21.0-py3-none-any.whl |
|---|---|
| Size | 23.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1e06043286c4a9cb8f4eadcff38a4f7a5954e943f8d176c0ce091b00cd4cfa60
|
|
BLAKE2b-256 checksum How to use checksums |
9d141b34078f78857466055074054b7782c3432bb8b16fafdd932667c430f99e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|