Skip to content

快速开始 ​

目标:15 分钟内让一个最小插件出现在扩展工坊里、能被启用、能在日志里说话。


1. 最小插件长什么样 ​

一个插件 = 一个独立文件夹,根目录必须有 mod.json:

text
my_tool/
├── mod.json                 # 必选(或 manifest.json)
├── my_tool.py               # Python 入口(数据类插件不需要)
├── locales/                 # 推荐:插件自包含多语言词条
│   ├── zh-CN.json
│   └── en-US.json
├── icon.svg                 # 推荐;也会自动探测 icon.png/webp/jpg
└── README.md                # 可选,工坊展示说明

mod.json 最小内容:

json
{
  "id": "myteam.tool.hello",
  "name": "Hello Tool",
  "version": "1.0.0",
  "author": "MyTeam",
  "description": "最小示例:按热键把一句话送进字幕",
  "type": "tool",
  "entrypoint": "my_tool.py:HelloTool",
  "target_app_version": "0.2"
}

⚠️ target_app_version 必填:没写的话插件根本不会出现在扩展工坊里 (日志 [registry] 拒绝识别…未适配 0.2.0)。见 兼容与版本门禁。

my_tool.py:

python
from transbox.plugins.base import BasePlugin


class HelloTool(BasePlugin):
    def initialize(self, config=None) -> None:
        super().initialize(config)
        self.host.register_plugin_hotkey(self.id, "run", "Alt+T", name="我的工具")
        self.host.log("info", "Hello Tool 已就绪")

    def action_run(self, **kwargs) -> dict:
        ok = self.host.feed_direct_caption("hello", "auto", tts=False, drop_noise=False)
        return {"ok": ok}

    def shutdown(self) -> None:
        self.host.unregister_plugin_hotkeys(self.id)
        super().shutdown()

2. 让它被宿主发现 ​

宿主从这些目录扫描(仅自发行版才扫第 4 个):

扫描根谁放进去的说明
<安装目录>/extensions/随应用发布官方内置 / 示例
%APPDATA%/transbox/extensions/用户自己开发时放这里最方便
Steam 创意工坊 content/<AppID>/Steam 订阅Steam 客户端自动同步
<数据目录>/workshop/<id>/官网插件工坊自发行版专有;只认根目录 mod.json

开发期推荐流程:

  1. 把 my_tool/ 整个文件夹放进 %APPDATA%/transbox/extensions/
  2. 打开 设置 → 扩展工坊 → 刷新
  3. 打开插件卡片上的开关启用
  4. 引擎类(asr / mt / tts / theme / interpretation)还要在对应设置页把它选为当前引擎

同 id 冲突时的来源优先级:local > steam > web;随应用发布的 bundled 只有在工坊版本 semver 更高时才被覆盖。


3. 出问题了看哪里 ​

  • 设置 → 扩展工坊:卡片上的状态、错误提示、缺少前置插件 之类都在这里
  • 应用日志:<安装目录>/logs/app.log(含 [registry]、[plugin:xxx] 前缀的行)
  • 插件自己说话:self.host.log("info", "…")
  • 面向用户提示:self.host.show_toast("…")

宿主不会静默吞掉加载失败:模块导入失败、入口类找不到、min_app_version 过新、前置依赖缺失, 都会在日志与工坊卡片上留痕。

详见 热调试。


4. 把整份文档丢给 AI ​

如果你想让大模型在没有主程序源码的前提下独立写出一个合规插件,把 目录结构与 mod.json、类型总览 里对应类型的那张卡片、 以及 Provider 签名 一起贴给 AI,并要求它遵守:

  1. 目录结构合规:独立文件夹 + 根目录合法 mod.json,id 全局唯一,禁用 builtin.*;
  2. 契约继承完整:Python 插件从 transbox.plugins.base 继承对应基类,抽象方法全部实现,签名严格对齐;
  3. 线程安全:网络请求 / 推理 / 耗时计算必须 self.run_in_background(),事件用 self.emit_event() 派发, 严禁阻塞 Qt 主线程;
  4. 配置用 config_schema;需要「去获取 Key / 测试连接」的定制 UX 自带 ui_extensions.settings_view; 配置一律 self._config.get(key) 读取,禁止硬编码私钥或个人路径;
  5. 自包含多语言:locales/zh-CN.json + locales/en-US.json,词条前缀 plugin.<plugin_id>.*, 禁止改主程序核心词库;
  6. 视觉规范:QML 用 ThemeTokens 与 PluggableWindowBackground 自动适配主题; 禁止用 Emoji / 字符当图标,必须矢量 SVG;
  7. MT 插件必须声明 target_langs:写清模型能翻译成哪些语种(含中英),不要只写 supported_langs; 见 语言代码与可翻译语种。
  8. 本地服务型插件遵守 本地服务型引擎强制契约(惰性启动 / 端口顺延 / shutdown 杀子进程)。
  9. 输出:完整目录树 + 完整 mod.json + 完整源码(禁止用省略号带过核心逻辑)+ 本地测试与发布指引。

相关 ​

TransBox - 赋能全人类无界限跨语言交流