forked from WHC/Hermit
- Skills (SKILL.md discovery, skill tool, /skills /skill) - plugin.json exec tools with permission prompts, timeouts and workspace trust (/plugins) - MCP stdio client: JSON-RPC initialize/tools/list/tools/call, mcp__server__tool, /mcp and sidebar status - task tool with general/explore/plan and .agent/agents/*.md roles, parallel read-only runs, cancel propagation, /agents - Keymap with Ctrl+X leader, keybinds.json overrides and /keys panel - Collapsed thinking, throttled streaming Markdown, leaner tool output, parallel read-only tools - Spawn: close-on-exec pipes and a process-wide fork lock - Tests for keymap, skills, plugins, MCP, sub-agents, shell compaction; docs/plugins.md
187 lines
7.5 KiB
Markdown
187 lines
7.5 KiB
Markdown
# 扩展:Skills、插件、MCP 与自定义子 agent
|
||
|
||
所有扩展只在默认工具档(`--tools default`)下加载;`--tools minimal` 完全不受影响。
|
||
下文的“配置目录”指 `~/.config/cst-agent/`(`$XDG_CONFIG_HOME/cst-agent/`;Windows 为 `%APPDATA%\cst-agent\`)。
|
||
|
||
| 放在哪 | 什么 | 何时加载 |
|
||
|---|---|---|
|
||
| `<ws>/.agent/skills/*/SKILL.md`、`<ws>/.claude/skills/*/SKILL.md` | skill | 总是 |
|
||
| `<配置目录>/skills/*/SKILL.md` | skill | 总是 |
|
||
| `<ws>/.agent/plugins/*/plugin.json` | 插件 | 工作区被信任后(`/plugins trust`) |
|
||
| `<配置目录>/plugins/*/plugin.json` | 插件 | 总是 |
|
||
| `<ws>/.agent/mcp.json` | MCP 服务器 | 工作区被信任后 |
|
||
| `<配置目录>/mcp.json` | MCP 服务器 | 总是 |
|
||
| `<ws>/.agent/agents/*.md`、`<配置目录>/agents/*.md` | 子 agent 角色 | 总是 |
|
||
|
||
同名时先出现的生效:工作区 > 配置目录 > 插件。改完后 `/skills reload`、`/plugins reload` 或 `/mcp reload`
|
||
重新加载(会重启 MCP 服务器)。启动时首页和 headless 的 stderr 会打印一行汇总,例如
|
||
`2 skills · 1 plugin (3 tools) · 1 MCP server`。
|
||
|
||
## Skills
|
||
|
||
一个 skill 是一个目录,里面有 `SKILL.md`,可以附带脚本、参考资料等文件:
|
||
|
||
```
|
||
.agent/skills/pdf-forms/
|
||
├── SKILL.md
|
||
├── reference.md
|
||
└── scripts/fill.py
|
||
```
|
||
|
||
```markdown
|
||
---
|
||
name: pdf-forms
|
||
description: Fill PDF forms with the bundled script; use when the user asks to fill or inspect a PDF form.
|
||
---
|
||
# PDF forms
|
||
|
||
1. List the fields: `python3 scripts/fill.py --list form.pdf`
|
||
2. ...
|
||
```
|
||
|
||
- system prompt 里只有一张索引(`- pdf-forms: Fill PDF forms…`,总长 ≤ 4 KB),模型认为相关时调用
|
||
`skill(name)` 读正文和文件列表,再用 `skill(name, file="reference.md")` 读附带文件(只能读 skill 目录内的文件)。
|
||
- 没有 frontmatter 时,名字取目录名,描述取正文第一行非标题文字。
|
||
- `/skill pdf-forms 把 a.pdf 填好` 会把 skill 正文直接放进这条消息再发送。
|
||
|
||
## 插件(plugin.json)
|
||
|
||
```
|
||
~/.config/cst-agent/plugins/jira/
|
||
├── plugin.json
|
||
├── issue.py
|
||
└── skills/ # 可选:插件自带的 skills
|
||
```
|
||
|
||
```json
|
||
{
|
||
"name": "jira",
|
||
"description": "Read Jira issues.",
|
||
"tools": [
|
||
{
|
||
"name": "jira_issue",
|
||
"description": "Fetch one Jira issue (summary, status, comments).",
|
||
"command": ["python3", "issue.py"],
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"key": {"type": "string", "description": "issue key, e.g. CST-42"},
|
||
"comments": {"type": "integer", "description": "how many comments"}
|
||
},
|
||
"required": ["key"]
|
||
},
|
||
"perm": "net",
|
||
"timeout": 30
|
||
}
|
||
],
|
||
"skills": "skills",
|
||
"mcpServers": {
|
||
"jira-search": {"command": "npx", "args": ["-y", "some-jira-mcp"]}
|
||
}
|
||
}
|
||
```
|
||
|
||
工具字段:
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| `name` | 工具名(非 `[A-Za-z0-9_-]` 的字符换成 `_`,≤ 63 字节),不能和已有工具重名 |
|
||
| `description` | 给模型看的说明 |
|
||
| `command` | 字符串数组:直接执行,数组里能在插件目录找到的相对路径会换成绝对路径;或一个字符串:交给 `sh` 执行(可以用管道) |
|
||
| `parameters`(或 `inputSchema`) | JSON Schema;`required` 会在执行前校验 |
|
||
| `perm` | `read`(不询问,可并行)/ `write` / `net` / `shell`(默认),按对应类别审批 |
|
||
| `timeout` | 秒,默认 60,最多 600;超时整组进程被杀,退出码 124 |
|
||
|
||
执行约定:
|
||
|
||
- 参数按 schema 转成类型正确的 JSON 对象(`{"key":"CST-42","comments":3}`),**从 stdin 读**。
|
||
- 工作目录是工作区根目录;环境变量 `CST_PLUGIN_DIR`(插件目录)、`CST_WORKSPACE`、`CST_TOOL`。
|
||
- stdout + stderr 就是工具结果(上限 512 KB),退出码非 0 视为失败。
|
||
- `perm` 为 `shell` 且审批模式是 `auto`、系统有沙箱时,命令在沙箱里运行(只能写工作区和临时目录)。
|
||
- 目前插件工具只支持 POSIX 系统(Linux / macOS / Termux)。
|
||
|
||
一个最小的 Python 工具:
|
||
|
||
```python
|
||
import json, sys
|
||
args = json.load(sys.stdin)
|
||
print(f"hello {args['name']}")
|
||
```
|
||
|
||
## MCP 服务器(mcp.json)
|
||
|
||
格式与 Claude Desktop / Cursor 相同:
|
||
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"filesystem": {
|
||
"command": "npx",
|
||
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
|
||
},
|
||
"github": {
|
||
"command": "github-mcp-server",
|
||
"args": ["stdio"],
|
||
"env": {"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"},
|
||
"autoApprove": ["get_issue", "search_code"]
|
||
},
|
||
"old": {"command": "foo", "disabled": true}
|
||
}
|
||
}
|
||
```
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| `command`、`args` | 启动命令(按 `PATH` 查找);只支持 stdio 传输,带 `url` 的服务器会显示为 failed |
|
||
| `env` | 追加的环境变量;`${NAME}` 取当前环境里的值,密钥不必写进文件 |
|
||
| `cwd` | 工作目录(相对路径相对于工作区;插件里的服务器默认在插件目录) |
|
||
| `disabled` | `true` 时不启动 |
|
||
| `autoApprove` | `true` 或工具名数组:这些工具按只读处理(不询问、可并行) |
|
||
|
||
- 服务器在后台启动(握手、分页 `tools/list`),TUI 不等待;工具在握手完成后出现。headless 运行会先等最多 30 s。
|
||
- 工具注册为 `mcp__<server>__<tool>`,参数 schema 原样交给模型;默认按网络工具审批(`auto` 模式下会询问,`a` 可记住)。
|
||
- 结果里的 text 内容拼接返回;图片/音频只给出类型和大小;`isError` 视为失败。单次调用 60 s 超时,Esc 会发送
|
||
`notifications/cancelled`。
|
||
- 服务器退出后状态变为 exited(`/mcp` 显示 stderr 最后一行),之后的调用直接报错;`/mcp reload` 重启。
|
||
- 侧栏显示 `MCP 就绪数/总数` 和每个服务器的工具数。
|
||
|
||
## 工作区信任
|
||
|
||
工作区里的 `.agent/plugins/` 和 `.agent/mcp.json` 会在你的机器上执行命令,clone 下来的仓库可能带着它们,
|
||
所以默认不加载,首页会提示 “untrusted workspace: /plugins trust”。
|
||
|
||
- `/plugins trust`:信任当前工作区(按真实路径记在 `settings.json` 的 `trusted_workspaces`),立即加载。
|
||
- `/plugins untrust`:取消信任。
|
||
- skills 和子 agent 角色只是文本,不受信任设置影响。
|
||
|
||
## 自定义子 agent 角色
|
||
|
||
`.agent/agents/reviewer.md`:
|
||
|
||
```markdown
|
||
---
|
||
name: reviewer
|
||
description: Reviews a diff for bugs and missing tests; read-only.
|
||
tools: read_file, grep, glob, run_shell
|
||
readonly: true
|
||
model: deepseek-v4-pro
|
||
max_steps: 12
|
||
---
|
||
You review changes. Run `git diff` first, read the touched files around each
|
||
hunk, and report concrete problems with file:line and a suggested fix.
|
||
Do not restate the diff.
|
||
```
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| `name` | 角色名(默认取文件名);与内置 `general` / `explore` / `plan` 同名时覆盖内置角色 |
|
||
| `description` | 写进主 agent 的角色索引,决定它什么时候选这个角色 |
|
||
| `tools` | 允许的工具白名单(默认全部,`task` 和 `ask_user` 始终不给子 agent) |
|
||
| `readonly` | `true` 时去掉写文件和 shell 工具,并允许多个同类 task 并行 |
|
||
| `model` | 用别的模型(同一 provider) |
|
||
| `max_steps` | 子 agent 每轮的模型调用上限 |
|
||
|
||
正文是角色说明,追加在子 agent 的 system prompt 末尾。主 agent 调用
|
||
`task(description="review auth", prompt="…", agent="reviewer")`;子 agent 的转录保存在
|
||
`.agent/sessions/<会话 id>/sub-N.jsonl`,`/agents` 里选中一条记录可以查看它的提示、工具调用和报告。
|