第 3 / 8 节15 分钟
🛠️

自定义工具

高级

创建自己的 AI 工具扩展功能

🎬

视频教程即将上线

自定义工具

学习如何为 OpenCode 创建自定义工具,扩展其功能以满足特定需求。

# 工具类型#

OpenCode 支持多种自定义工具:

  1. Shell 命令 - 最简单,直接执行 shell 命令
  2. 脚本工具 - 运行 Python/Node.js 脚本
  3. MCP 服务器 - 完整的工具服务
  4. HTTP API - 调用远程服务

# Shell 命令工具#

最快捷的自定义方式,在配置文件中定义:

toml
1# ~/.opencode/config.toml
2
3[tools.shell]
4# 检查代码格式
5lint = "npm run lint"
6
7# 运行测试
8test = "npm test"
9
10# 部署到预览环境
11deploy-preview = "vercel --preview"
12
13# 清理构建产物
14clean = "rm -rf dist node_modules/.cache"

使用:

❯ /tool lint
Running: npm run lint
✓ No linting errors

❯ /tool deploy-preview
Running: vercel --preview
Preview: https://project-xxx.vercel.app

# 脚本工具#

## Python 脚本#

创建 ~/.opencode/tools/analyze.py:

python
1#!/usr/bin/env python3
2"""分析代码复杂度"""
3
4import sys
5import json
6from radon.complexity import cc_visit
7
8def analyze_file(filepath):
9    with open(filepath) as f:
10        code = f.read()
11
12    results = cc_visit(code)
13    return [{
14        'name': block.name,
15        'complexity': block.complexity,
16        'line': block.lineno
17    } for block in results]
18
19if __name__ == '__main__':
20    filepath = sys.argv[1]
21    result = analyze_file(filepath)
22    print(json.dumps(result, indent=2))

注册工具:

toml
1[tools.script]
2analyze = {
3  command = "python3 ~/.opencode/tools/analyze.py",
4  description = "分析代码复杂度"
5}

## Node.js 脚本#

创建 ~/.opencode/tools/deps-check.js:

javascript
1#!/usr/bin/env node
2/**
3 * 检查过时的依赖
4 */
5
6const { execSync } = require('child_process');
7
8async function checkDeps() {
9  const result = execSync('npm outdated --json', {
10    encoding: 'utf8',
11    stdio: ['pipe', 'pipe', 'pipe']
12  });
13
14  const outdated = JSON.parse(result || '{}');
15
16  return Object.entries(outdated).map(([name, info]) => ({
17    package: name,
18    current: info.current,
19    latest: info.latest,
20    type: info.type
21  }));
22}
23
24checkDeps()
25  .then(deps => console.log(JSON.stringify(deps, null, 2)))
26  .catch(err => console.error(err.message));

# 带参数的工具#

定义接受参数的工具:

toml
1[tools.parameterized]
2search-logs = {
3  command = "grep -r '$PATTERN' logs/",
4  params = ["PATTERN"],
5  description = "搜索日志中的特定模式"
6}
7
8create-component = {
9  command = "node scripts/create-component.js $NAME $TYPE",
10  params = ["NAME", "TYPE"],
11  description = "创建新组件"
12}

使用:

❯ /tool search-logs ERROR
❯ /tool create-component Button functional

# 交互式工具#

创建需要用户输入的工具:

toml
1[tools.interactive]
2select-env = {
3  command = "scripts/select-env.sh",
4  interactive = true,
5  description = "选择部署环境"
6}

脚本示例:

bash
1#!/bin/bash
2echo "Select environment:"
3select env in "development" "staging" "production"; do
4  case $env in
5    development) echo "DEV"; break;;
6    staging) echo "STAGING"; break;;
7    production)
8      read -p "Are you sure? (yes/no) " confirm
9      if [ "$confirm" = "yes" ]; then
10        echo "PROD"
11        break
12      fi
13      ;;
14  esac
15done

# 工具组合#

将多个工具组合成工作流:

toml
1[tools.workflow]
2pre-commit = {
3  steps = ["lint", "test", "type-check"],
4  stop_on_error = true,
5  description = "提交前检查"
6}
7
8deploy = {
9  steps = [
10    { tool = "test" },
11    { tool = "build" },
12    { tool = "upload", params = ["$BUILD_DIR"] },
13    { tool = "notify", params = ["部署完成"] }
14  ],
15  description = "完整部署流程"
16}

使用:

❯ /tool pre-commit
Running workflow: pre-commit
  [1/3] lint... ✓
  [2/3] test... ✓
  [3/3] type-check... ✓
All steps completed successfully!

# 工具权限#

控制工具的执行权限:

toml
1[tools.security]
2# 需要确认的工具
3dangerous = {
4  command = "rm -rf $PATH",
5  params = ["PATH"],
6  confirm = true,
7  warning = "这将永久删除文件!"
8}
9
10# 限制执行环境
11restricted = {
12  command = "deploy.sh",
13  allowed_dirs = ["/home/user/project"],
14  requires_git_clean = true
15}

# 工具输出处理#

## JSON 输出#

如果工具输出 JSON,OpenCode 可以智能处理:

toml
1[tools.json]
2api-status = {
3  command = "curl -s https://api.example.com/status",
4  output = "json",
5  description = "检查 API 状态"
6}
❯ /tool api-status
API Status:
  • status: healthy
  • version: 2.1.0
  • uptime: 99.9%

## 格式化输出#

toml
1[tools.formatted]
2coverage = {
3  command = "npm run test:coverage -- --json",
4  output = "json",
5  format = """
6Coverage Report:
7  Statements: {statements}%
8  Branches: {branches}%
9  Functions: {functions}%
10  Lines: {lines}%
11"""
12}

# 工具别名#

为常用工具创建别名:

toml
1[aliases]
2t = "tool test"
3l = "tool lint"
4d = "tool deploy-preview"

使用:

❯ /t      # 等同于 /tool test
❯ /l      # 等同于 /tool lint

# 分享工具配置#

导出工具配置供团队使用:

❯ /tools export > team-tools.toml

导入团队配置:

❯ /tools import team-tools.toml
Imported 15 tools from team-tools.toml

# 调试工具#

## 查看工具详情#

❯ /tools info deploy

Tool: deploy
Command: scripts/deploy.sh $ENV
Parameters: ENV
Description: 部署到指定环境

## 测试工具#

❯ /tools test deploy --dry-run
Would execute: scripts/deploy.sh production

## 查看执行历史#

❯ /tools history

Recent tool executions:
  [10:30] test - Success (2.3s)
  [10:28] lint - Success (1.1s)
  [10:25] deploy - Failed (exit code 1)

# 下一步#

了解自定义工具后,学习如何集成 GitHub 进行协作开发。