Skills
Spec: skills.
Skills are SKILL.md files in ~/.blitz/skills and the project’s ./skills and .agents/skills; a project’s skill runs its scripts only once you trust the project’s settings (Sharing settings with your team). Their frontmatter takes the Agent Skills fields (name, description, license, compatibility, allowed-tools, metadata) and the fields of Castor’s skill definition (castor.skills.v1.SkillDefinition), under their proto names:
---
name: gh-issues
description: Triage GitHub issues
tool_requirements:
- {name: Bash, scopes: ["gh:*"], description: read issues}
execution_hints:
hitl_tier: TIER_2_AUDITED_WRITE # a tier name, never a number
environment_variables: [GITHUB_TOKEN]
custom_hints: {network: "true"} # the scripts need the network
scripts:
- name: list
language: python
relative_path: scripts/list.py
dependencies: ["requests>=2.31"]
timeout_seconds: 60
---
A skill is one of four kinds, from what its folder holds:
| Kind | What it has |
|---|---|
| Simple | SKILL.md alone |
| With references | A references/ folder: the agent reads its files when the skill calls for them (read_skill_file) |
| With scripts | Python (.py), TypeScript (.ts), JavaScript (.js, .mjs), shell (.sh, macOS and Linux), cmd (.cmd, .bat, Windows) or PowerShell (.ps1, where pwsh is installed) files in scripts/, or scripts declared in the front matter, run sandboxed under the skills policy. A requirements.txt or pyproject.toml (Python) or package.json (JavaScript, TypeScript) gives them an isolated environment with those packages, installed once you approve: in Studio, the Scripts tab’s Packages section adds and edits them |
| Combines skills | skills: [a, b] in the front matter: activating it activates them too |
agents: [reviewer] in the front matter offers a skill only to those agents.
Desktop: Studio › Skills lists the workspace’s skills (.agents/skills). + makes one; click one to edit it: General (what it’s for, its name, instructions with Redraft, the skills it combines, the agents it’s offered to, its tools), References (add, upload, edit or delete files; PDFs, images and Markdown preview) and Scripts (a new script from a template, Redraft to have the model write it, and Test run with arguments). Opening a file gives it the whole tab; the back arrow returns to the list. Add from… copies any skill you can see into the workspace to change it, or references it in the skill you’re editing.
In a prompt: type \ and a skill’s name (the composer completes it) to use that skill for the request: its instructions go with your prompt, as /skill-name does.
A skill’s scripts run without asking only once you’ve reviewed them: Blitz remembers the content you trusted, so a new or changed script (or a registry update) is asked about again. Until then the agent asks you before each run, and a worker’s run is refused.
- Desktop: installing a registry skill with scripts opens the review; Studio › Skills marks a skill Scripts to review, with Review scripts in its view. The review lists each script, its file and the packages it installs; Trust these scripts remembers them.
- Trusting a workspace’s project settings trusts its skills’ scripts as they are, so you aren’t asked twice.
A registry, such as your organization’s Castor registry, offers skills to install by name. Each skill is a .zip whose SHA-256 the registry gives, and Blitz refuses one that doesn’t match.
blitz skills registry add https://castor.example.com/skills/index.json --token-stdin # the token is kept in the keychain
blitz skills search literature
blitz skills install castor/lit-review # for you, in every workspace
blitz skills install castor/lit-review --project # in this project's .agents/skills, for everyone
blitz skills update # every skill whose registry has a new version
blitz skills uninstall lit-review
In a session, /skills search also lists what your registries offer, and /skills install <registry>/<name> installs one. In the desktop app it’s Settings › Skills (with the advanced settings shown): add a registry, find skills, install them for you or the open workspace, update and uninstall. Open conversations can use a new skill at once, with no restart.
| Command | Does |
|---|---|
blitz skills registry add <url> |
Adds a registry, after reading its index; --name names it, --token-stdin reads an access token |
blitz skills registry list, remove <name> |
Lists them, or forgets one and its token (its skills stay) |
blitz skills search [words] |
Skills whose name or description has every word |
blitz skills install <registry>/<name> |
Installs one (--project: in this folder’s .agents/skills) |
blitz skills update [name…], uninstall <name>, list |
Keeps them up to date, removes one, lists them |
A registry is https:// (or http://localhost, or a local file), and the token is only ever sent to the registry’s own host. An installed skill is an ordinary skill folder: the skills policy below applies to it as to any other, and Blitz never replaces a folder it didn’t install.
Serving a registry. An index is a JSON file:
{
"version": 1,
"name": "Castor",
"skills": [
{"name": "lit-review", "description": "Reviews the literature on a question", "version": "1.2.0",
"archive_url": "lit-review-1.2.0.zip", "sha256": "9f2c…", "castor_id": "sk_lit"}
]
}
archive_url is absolute or relative to the index. The archive holds SKILL.md (naming the skill) at its root or in one folder, and the skill’s other files.
[skills.policy] caps what skills may ask for: the approval tier, script languages, network, which environment variables pass through, timeouts, trusted content hashes, denied tools and scopes, and packages (the index, wheels only, allow and deny lists, pinning). The stricter of the skill’s request and the policy always applies:
- A missing tier gets
min_hitl_tier(default 2). TIER_0_BYPASS_ALLneeds both the skill’sallow_hitl_bypassand the policy’s; otherwise it becomes tier 3.- Dependencies must be plain package requirements: URLs, paths and pip options are refused.
/skills update revisits the project’s skills against its specification (.agents/specs/) and offers what to add, change or retire (spec, then setup). /skills show <name> lists every decision and the skill’s content hash, for trusted_hashes. blitz doctor reports skills that don’t parse and scripts the policy blocks.
| Tier | Approval | Can write |
|---|---|---|
| 1 | None (audited) | Nothing but its private /tmp |
| 2 (default) | None (audited) | Its output directory |
| 3 | Asked every time; can’t be remembered | Its output directory |
| 0 (bypass; both sides must allow it) | None | Its output directory |
skills.policy.sandbox chooses the sandbox, and blitz doctor shows which is in use:
gvisor(Linux). Each script gets its own gVisor sandbox, whose user-space kernel keeps a kernel exploit in a script or package away from the host. Only the host’s binaries and libraries,/etc, and the script’s own paths are mounted; home directories don’t exist inside,/tmpis private, and the network is off unless allowed. Install gVisor’s release (runsc) on yourPATH, in~/.blitz/bin, or atRUNSC_PATH.os. Seatbelt or bubblewrap, as for shell commands.auto(the default) uses gVisor when a test run works, otherwise the OS sandbox.
A script sees only the variables the policy passes, and it’s stopped at its timeout or when you press Ctrl+C. Without a sandbox (on Windows, for example) scripts don’t run.
activate_skill lists a skill’s scripts and whether the policy lets each run; the agent runs them with run_skill_script. Scripts are Python (the system python3) or TypeScript (the system node, 22.6 or later, which runs TypeScript by stripping its types).
- Dependencies go into an isolated environment in
~/.blitz/envs, one per distinct set of requirements. It’s built inside the sandbox, with the network on and writes allowed only to the environment and the package cache, usinguvif it’s installed (elsevenvandpip). You approve each install once, with the package list shown. The system Python is never touched./envslists environments;/envs pruneremoves the unused. A Python script can say which Python it needs, withrequires_pythonin its definition orrequires-pythonin its PEP 723 metadata. When the system’spython3doesn’t fit and uv is installed, a uv-managed Python runs it (uv installs one after you approve); without uv the script is refused, saying why.
A skill whose scripts change your files declares execution_hints.writes_workspace: true: its scripts then work in a copy of the workspace, and when one succeeds you see what it changed as a diff and decide, every time, whether to keep it. Kept changes are part of the turn, so /undo reverts them.
TypeScript’s npm packages go into ~/.blitz/node-envs the same way, installed with npm install --ignore-scripts so no package’s code runs at install; [skills.policy.packages.npm] sets the registry, allow and deny lists, and require_exact versions.
- Scripts read the workspace but never write it. At tier 2 or above a script writes to its own
.blitz/skill-output/<skill>/<run>/($SKILL_OUTPUT). The agent reads the results there and makes any changes with the file tools, so diffs, approvals, checkpoints and/undowork as usual.