插件、界面扩展与数据资产
两套插件体系
One Works 现在有两套并行的插件使用方式:
- 统一 One Works plugin:通过
plugins配置加载 npm 包里的rules / skills / specs / entities / mcp / hooks,也可以加载界面入口、前端视图、server 命令和 scoped API - adapter 原生插件:通过
oneworks plugin --adapter <adapter> add ...安装 adapter 自己的原生插件格式,再转成项目可复用的 One Works 资产
如果你要安装 Claude Code 插件、配置 marketplace,继续看 Adapter 原生插件与 Marketplace。
安装方式
- Relay、内置浏览器控制(IAB)、浏览器控制和电脑控制 - CUA 是默认启用的内置 One Works 插件。浏览器控制当前仅支持 Chrome;外部浏览器与 CUA 的设置入口统一位于“外部控制”分组。CUA 可按 macOS Bundle ID 配置“无需询问 / 每次询问 / 拒绝访问”,未匹配应用默认每次询问。
- 内置 One Works 插件会按运行时声明的版本从全局 package cache 解析;缺失时会安装到该 cache。
- 其他插件通过 npm 安装到你的项目 workspace,或使用目录路径引用;如果包解析不到,会直接报错。
id支持简写:例如配置logger时,会优先解析logger,失败后再尝试@oneworks/plugin-logger;旧的@vibe-forge/plugin-logger仍作为兼容路径解析。
如果某个 workspace 不需要宿主控制插件,可以显式关闭;这不会卸载安装包里的插件:
{
"plugins": [
{
"id": "@oneworks/plugin-browser-driver",
"enabled": false
},
{
"id": "@oneworks/plugin-external-browser-driver",
"enabled": false
},
{
"id": "@oneworks/plugin-cua-driver",
"enabled": false
}
]
}Standard Development 继续作为独立 npm 包兼容已有配置,但官方市场不再提供第二个顶层入口。新配置应通过 @oneworks/plugin-demo 的可选 standard-dev child 启用它。
全局 package cache 默认位于 ~/.oneworks/bootstrap/npm;如需调整根目录,可以设置 __ONEWORKS_PROJECT_PACKAGE_CACHE_DIR__。
自动安装内置插件时,npm 源和鉴权读取标准 npm 配置:用户 ~/.npmrc、项目 .npmrc、环境变量,优先级依次升高。 支持 registry=...、@oneworks:registry=... 和 //registry.example.com/:_authToken=... 这类标准写法。 如果没有显式配置 registry,One Works 会先探测默认官方源;官方源发生网络错误、超时或 5xx 时,会自动 fallback 到 https://registry.npmmirror.com。 如果你已经配置了公司私服或其它 registry,One Works 不会自动切到公共镜像;需要兜底时,显式设置 ONEWORKS_NPM_REGISTRY_FALLBACKS,多个源用逗号分隔。
项目 .npmrc 示例:
@oneworks:registry=https://registry.npmmirror.com
//registry.npmmirror.com/:_authToken=${NPM_TOKEN}示例:
pnpm add -D @oneworks/plugin-demo @oneworks/plugin-logger基本配置
默认情况下,在解析后的 workspace 根目录的 .oo.config.json 或 .oo.config.yaml 中配置 plugins:
{
"plugins": [
{
"id": "@oneworks/plugin-demo",
"scope": "demo",
"children": [
{
"id": "standard-dev",
"scope": "std"
}
]
},
{
"id": "logger",
"enabled": false
}
]
}支持字段:
id: 插件包名或简写名version: 可选。用于内置 One Works 插件的全局 package cache 版本;未配置时使用latestscope: 可选。给该插件实例的资源加命名空间,避免重名enabled: 可选。默认true;设为false时,该实例不会进入当前项目的有效插件图watch: 可选。开启后监听该 plugin 目录文件变更,并通过 plugin watch 通道刷新对应 runtime;.oo/plugins.dev自动发现的 plugin 默认开启options: 可选。当前插件实例的配置值;插件详情页的「配置」tab 会把交互表单保存回这里children: 可选。显式启用或覆写 child plugin
插件名称与图标规范
每个 One Works plugin 都必须在顶层 manifest 提供稳定机器名和完整展示元数据:
{
"name": "@acme/plugin-workspace-tools",
"displayName": "Workspace Tools",
"displayNameI18n": {
"en": "Workspace Tools",
"zh-Hans": "工作区工具"
},
"icon": "./assets/icon.svg"
}displayName是英文兼容兜底,不能用 npm package id 代替。displayNameI18n至少包含非空的en与zh-Hans;插件列表、详情标题与搜索会使用这些名称。icon指向 plugin 根目录内的相对图片或 SVG。禁止绝对路径、空路径和..父级穿越。- 推荐把图标放在
assets/icon.svg。宿主会优先展示插件图标;旧插件没有图标时才生成稳定的字母图标。
使用插件创建页或仓库内 create-plugin skill 生成新插件时,这四个展示字段属于必填项。
插件实例配置
插件作者可以在 manifest 的 config 字段里声明配置结构。用户仍然在项目配置的 plugins[].options 中保存具体值;manifest 只描述这些值如何展示和编辑。
最小示例:
{
"__oneworksPluginManifest": true,
"name": "@acme/plugin-workspace-tools",
"config": {
"schema": {
"type": "object",
"properties": {
"greeting": {
"type": "string",
"default": "Hello",
"titleI18n": {
"en": "Greeting",
"zh-Hans": "问候语"
},
"descriptionI18n": {
"en": "Text shown by plugin commands.",
"zh-Hans": "插件命令展示的文本。"
},
"x-oneworks-ui": {
"icon": "waving_hand",
"placeholder": "Hello"
}
},
"mode": {
"type": "string",
"default": "auto",
"oneOf": [
{
"const": "auto",
"titleI18n": { "en": "Auto", "zh-Hans": "自动" }
},
{
"const": "manual",
"titleI18n": { "en": "Manual", "zh-Hans": "手动" }
}
]
}
}
}
}
}插件详情页 /ui/plugins/<scope>?tab=config 会读取 config.schema 或 config.jsonSchema, 把 JSON Schema 渲染成和主配置页一致的交互表单。保存时会写回当前项目配置里的同一个 plugin 实例:
{
"plugins": [
{
"id": "@acme/plugin-workspace-tools",
"scope": "tools",
"options": {
"greeting": "Hello",
"mode": "auto"
}
}
]
}当前交互表单支持 string、number / integer、boolean、字符串数组、enum、 oneOf / anyOf 中的字符串 const 选项,以及 JSON 兜底字段。format: "password"、 writeOnly: true 或 x-oneworks-ui.sensitive: true 会按敏感字段展示。 需要完全控制 UI 时,也可以在 manifest 里提供 config.uiSchema,直接使用配置页内部的 ConfigUiObjectSchema 结构。
Config Hook
插件也可以提供一个 config hook,在 One Works 读取完 global/project/user config 后返回一段临时 config patch。这个 patch 会合并到最终 user 层,因此运行时、Web UI 和 adapter 都能看到最终生效的 modelServices、默认模型、MCP、权限等配置。
适合放在这里的逻辑:
- Relay 服务按用户、团队、项目白名单下发
modelServices - 插件根据
plugins[].options判断哪些字段允许合并 - 插件读取服务端提前同步到本地目录的配置文件,再合并到本次启动的最终配置
这类规则不应该直接放到普通设置页字段里编辑。用户可见的规则、项目 allow/deny 列表、可合并字段白名单、本地变更自动同步云端等能力,应由对应插件自己的插件页或服务协议承载;普通配置页只展示合并后的最终 config。
插件包可以通过 package export 暴露 ./config:
{
"exports": {
".": "./dist/index.js",
"./config": "./dist/config.js"
}
}也可以在 manifest 里声明相对入口。config 字段仍用于插件实例配置表单 schema,config hook 使用独立的 configHook 字段:
module.exports = {
__oneWorksPluginManifest: true,
configHook: { entry: './dist/config.js' }
}./config 入口导出一个函数,返回要合并的 config patch:
module.exports = async (ctx) => {
const service = ctx.plugin.options.serviceKey || 'relay'
return {
defaultModelService: service,
modelServices: {
[service]: {
apiBaseUrl: ctx.jsonVariables.RELAY_BASE_URL,
apiKey: ctx.jsonVariables.RELAY_API_KEY,
models: ['gpt-relay']
}
}
}
}ctx 中包含当前 cwd、env、jsonVariables、projectConfig、userConfig、mergedConfig 和当前插件实例元数据。config hook 应尽量读取本地已同步数据;如果需要访问网络,建议插件自己做缓存和失败降级。
Scope 与资源引用
- scope 完全由用户控制,不由插件作者定义。
- 如果插件配置了
scope,资源标识会变成scope/name,例如std/standard-dev-flow、std/dev-planner。 - 如果没有配置
scope,可以直接写name,但只有在该类资源全局唯一时才能成功解析。 - 当本地项目资产目录中的资源和插件资源同名时,建议给插件实例增加
scope,避免歧义。
Child Plugin
插件可以声明 child plugin,你也可以在配置里显式覆写:
{
"plugins": [
{
"id": "bundle",
"scope": "corp",
"children": [
{
"id": "review",
"enabled": false
},
{
"id": "logger",
"scope": "corp-logger"
}
]
}
]
}说明:
- child plugin 可以来自父插件 manifest,也可以是任意已安装依赖
- child 未显式设置
scope时,会继承父实例的scope children[].enabled: false可以关闭默认激活的 child plugin
可加载的资产
统一插件资产支持:
rulesskillsspecsentitiesmcphooks
其中 spec 和 entity 还支持在文档前置元数据里通过 plugins: { mode, list } 对当前任务的插件列表做 extend 或 override。
界面 plugin runtime
界面 plugin 继续使用同一个 plugins 配置和 manifest,可以提供数据资产、界面贡献、server 命令和 scoped API。详细说明拆到下面几个短文档: