九个chipcode插件全开源,一年下来最后悔的是图标
九个插件全部开源,是我做产品这几年最不后悔的决定,也是最麻烦的一个。
不后悔是因为,一个能操作你编译器、串口、EDA 软件的东西,闭源等于要求你无条件信任我。麻烦是因为,开源之后要维护的东西比代码多得多。
这篇说说为什么开、开了什么、以及一年里被绊倒的几次。
起因是一个用户的问题
早期有人问我:「你们的 Arduino 插件会不会偷偷往我的代码里塞东西?」
我可以说「不会」,但这句话没有任何分量。他凭什么信我?
一个能执行 arduino-cli、能读写项目文件、能开串口的进程,权限和用户自己一样大。这种位置上的「请相信我」,本质上是把风险转嫁给用户。
所以决定开源。九个插件,Apache-2.0,源码放在那儿,谁都能看、能改、能 fork。
核心编辑器没开——那部分不涉及你机器上的操作,开不开不影响信任问题。插件层必须开。
开源了什么,没开什么
九个插件分别是:Arduino、ESP-IDF、STM32Cube、51(SDCC)、OpenSCAD、立创EDA、Wokwi 模拟器、浏览器自动化、插件开发脚手架。
选 Apache-2.0 而不是 GPL,理由很实际:GPL 会传染,用 GPL 意味着任何集成了这些插件的商业软件都得跟着开源。我们不想强迫别人,只想让人能查。Apache-2.0 还带专利授权条款,对商业使用更友好。
仓库里带了 NOTICE 文件,把第三方版权一条条列清楚——立创EDA 那部分是从官方 run-api-gateway fork 的,STM32 的器件支持文件有自己的许可证。这种事不写清楚,将来就是法务问题。
开源的第一版只放了七个插件。后来加了 51 和 OpenSCAD,仓库里的 README 我改了三次才把插件表对齐。
插件模型:一个 JSON 说清楚一切
我们自己最满意的设计是这个:一个插件就是一个目录,只有 plugin.json 是必填的。
{
"id": "my-toolchain",
"name": "我的工具链",
"version": "1.0.0",
"icon": "🔧",
"capabilities": {
"compile": {
"transport": "internal", "service": "arduinoCli", "method": "compile" }
}
}
关键在于 transport 这一层抽象。插件要跟外界打交道,无非七种方式:跑命令行(cli)、调 HTTP、连 gRPC、用 MCP、连 MQTT 设备、复用宿主能力(internal)、或者挂一个长驻的 stdio 后端。声明是哪种,宿主就用对应的驱动去跑。
好处是插件作者不用碰宿主代码。坏处是我们得把这七条路都写稳,而且每加一条,测试矩阵就翻一倍。
第一个坑:图标要在三个地方一致
这个坑很蠢,但绊了我们不止一次。
插件的 icon 字段决定它在界面上长什么样。问题是这个标识串同时存在于三个地方:
- 插件自己的
plugin.json - 市场后端的插件目录表
- 官网的插件广场页面
任何一处不一致,用户看到的就是旧图标。我们改了 OpenSCAD 的图标,用户装了新版,界面上还是那个默认的小扳手。
排查了半天才发现是市场那张表没同步。
后来写了份核对清单,六处要改:manifest、市场元数据、官网插件页、官网首页、宿主渲染层的图标分发、本地已安装插件的 registry。改完还得重装一次才会刷新。
这种坑不会报错,只会让你看起来很不专业。
第二个坑:manifest 必须校验得比想象中严
插件能声明「新建项目时生成哪些文件」:
"projectTypes": [{
"id": "my-firmware",
"scaffold": [{
"file": "main.cpp", "content": "// {name}" }]
}]
{name} 会被替换成用户输入的项目名。
如果用户输入的是 ../../Windows/System32,而你不校验,插件就能在任意位置写文件。
所以安装时 validateManifest 会检查:能力 key 是否合法、transport 是否在枚举内、命令的 placement 是否有效、scaffold 的路径是否包含绝对路径或 ..。任何一条不过,拒绝安装。
同样的问题还有 views.webview 的 entry 路径,必须是插件目录内的相对路径,通过自定义协议加载时只服务当前启用的插件,还带 MIME 白名单。
这些校验写起来枯燥,但少一条就是一个洞。
第三个坑:第三方插件怎么办
开源之后自然有人想写自己的插件。我们把官方插件和第三方分开了:
- 官方插件:组织账号维护,软件内一键安装
- 第三方插件:走 GitHub 的
triecode-plugintopic 发现,不进官方市场
后一条被问过很多次「是不是太保守」。
我的理由很简单:插件以用户权限运行,能执行任意命令。官方市场里的东西,用户是默认信任的——点一下「安装」,就等于把机器交出去。我们要对得起这个「点一下」,就只能收自己能审的代码。
第三方插件不是不让用,是不给「官方背书」这层滤镜。你要装,你自己判断来源。
开源之后,改得最多的是文档
代码改动没想象中多,文档改了一大堆。
最典型的是插件开发指南。第一版写成了内部设计文档,满篇「对齐业界成熟做法」「我方」「你可能需要看」。一个外部开发者看了完全不知道从哪下手。
后来全部重写成面向第三方的口吻:先给一个能跑的最小插件,再讲七类通道,最后给 manifest 完整字段表。
还有左侧栏 UI 的适配规范。插件面板宽度可以拖到 200px,任何固定宽度的元素在窄面板下都会变形。我们把踩过的坑写成一条清单:输入框必须 min-width: 0、按钮 flex-shrink: 0、长文本 word-break: break-all。
这类东西不写,每个插件作者都要自己踩一遍。
说句实话
开源不会让产品变得更好用。用户装插件的时候不会去读源码,他只会关心点一下能不能跑起来。
开源的真正作用有两个:一是让「你可以查」这件事成立,二是让我们自己不敢乱写。
第二条比第一条重要。当你知道这段代码会被放在 GitHub 上、会有人点开看,写的时候会认真一点。
至于为什么最后悔的是图标——因为那是最不该出错的地方,却是我们出错最多的地方。