Files
shiro-neko/docs/extensions.md
T

4.0 KiB

Extensions: auto-loaded skills, tools, and plugins

External extensions load automatically from two directories on every start, the project shadowing the user by name:

Origin Directories
user ~/.shiro-neko/skills ~/.shiro-neko/tools ~/.shiro-neko/plugins
project .shiro/skills .shiro/tools .shiro/plugins

Drop a file in and it is live on the next start. No registry, no install command, no restart of anything but the CLI itself.

Everything here is data, never code. That is the same rule the registry enforces, and it is the whole security model. An external extension can add instructions, a bounded tool, or a refusal rule — it cannot run arbitrary code, so it cannot read every file the agent can read or lie about what it blocks. A malformed file is reported on the welcome dashboard and skipped, never fatal.

Skills

A skill is a Markdown file with frontmatter, exactly like a bundled one:

---
name: deploy
description: Ship a release. Use when asked to deploy or cut a release.
---

# Deploy

1. Confirm the tests pass. Do not deploy on a red suite.
2. Tag with the version from src/version.ts, not by hand.

Skills merge by name with the precedence builtin < registry < user < project, so your own debug.md overrides the bundled debug. See skills for the full format.

Tools

A tool is a JSON manifest describing one bounded operation. Three kinds, each with a ceiling on what it can do:

{
  "name": "recent-changes",
  "description": "List the ten most recently changed files",
  "kind": "shell",
  "command": "git diff --name-only HEAD~10",
  "autoApprove": true
}
Field Meaning
name The tool name the model calls. Letters, digits, dashes, underscores.
description What the model reads to decide when to use it.
kind shell, http, or read.
command For shell: the template to run, with an optional {arg} placeholder.
url For http: the URL to fetch, with an optional {arg} placeholder. HTTPS only.
path For read: the workspace file to return, with an optional {arg} placeholder.
autoApprove false to require approval before running. Default true.

The model passes a single optional arg string, substituted into {arg}.

The limits are the point. A shell tool runs a fixed template through the guard and the platform shell — the same chain a built-in bash call goes through, so an installed tool cannot do what the agent itself may not. An http tool fetches one HTTPS URL. A read tool returns one workspace file, jailed to the workspace. None of them executes code from the manifest.

Plugins

A plugin is a refusal manifest — the same shape the registry installs — a name, an optional prompt appendix, and deny rules matched against tool input:

{
  "name": "no-prod-config",
  "description": "refuses to edit production config",
  "appendix": "Production config is changed by hand, never by the agent.",
  "deny": [
    { "tools": ["write_file", "edit_file"], "pathPattern": "config/production", "reason": "production config is hand-edited" },
    { "tools": ["bash"], "commandPattern": "kubectl\\s+apply", "reason": "deploys to the cluster" }
  ]
}

A rule names the tools it covers and either a pathPattern (matched against the path a file tool carries) or a commandPattern (matched against a bash command), both as case-insensitive regexes, plus the reason handed to the model when it blocks. Patterns are validated on load; an invalid regex is a reported error, not a crash.

Refusal plugins compose with the built-in plugins — the first block wins.

Relationship to the registry

The registry fetches the same kinds of files over HTTPS with a confirmation step. Auto-load is for your own and your project's files, which need no confirmation because you wrote them. The two mechanisms share the loaders and the safety model; they differ only in where the file comes from.