Community编程与开发github.com

Benchtop

将微控制器或3D打印项目从模糊的想法转化为可构建的完整包——包括概念、配实时价格的零件清单、经过检查的电路图、载板PCB或按比例绘制的插画式焊接指南、可3D打印的外壳、固件框架以及一个包含所有文件的设计精美的着陆页。

Benchtop 是什么?

Benchtop 是一个专注于物理电子硬件项目的 AI 助手技能,旨在将用户模糊的“我想做一个东西……”的想法,转化为一个其他人可以实际复现和构建的完整项目包。它支持 ESP32、ESP8266、Arduino、Raspberry Pi Pico 等主流微控制器平台,以及各种传感器、显示屏、LED、电机等元器件。该技能的核心在于**数据驱动**:所有图纸、清单、外壳、PCB 和固件都是从同一个 `project.json` 文件和 `assets/parts/` 目录下的零件定义自动生成的,确保了各部分信息的一致性,避免了手工绘制带来的错误。工作流程分为六个阶段:构想、零件与电路、采购与构建路径、构建文件生成、展示页面和最终交付。每个阶段都会产出可供用户审阅的阶段性成果,并在关键决策点暂停,等待用户确认方向。Benchtop 支持自动检查电路电气规则、自动获取零件价格、生成3D打印外壳和PCB制板文件,并提供固件框架。它特别强调几何精度验证,确保生成的3D打印件和PCB与实物尺寸一致。项目最终会打包成一个包含组装指南、零件清单、3D渲染图、演示页面的压缩包,方便分享和交付。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/filipjaj/benchtop/tree/HEAD/skills/benchtop

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Benchtop 是做什么的?

将“我想做一个东西……”转化为一个其他人可以构建的文件夹:包含一份指南、一份零件清单、一个可打印的外壳、一个可订购的电路板、可烧录的固件以及一个展示项目成果的页面。

核心理念

所有内容都从一个文件——project.json,以及 assets/parts/ 中的零件定义生成。你只需要编写和编辑这个文件;脚本会自动生成图纸、检查结果、外壳、电路板、引脚编号和展示页面。

正是这一点确保了输出的可靠性。手工绘制的接线图和手动输入的引脚表迟早会相互矛盾,而初学者无法判断哪个是错的。因此:永远不要手工绘制接线图,永远不要在固件中手动输入GPIO编号,永远不要引用零件文件中没有的尺寸。修改 project.json(或零件文件)然后重新生成即可。

scripts/lib/types.ts 是模式定义文件,每个字段都有注释。 examples/luft/project.json 是一个完整的项目文件(包含零件、连接、外壳、固件和展示区块);在编写你的第一个项目文件之前,请阅读它。该示例附带了 examples/luft/firmware/ 中的固件(这是唯一需要手写的部分,也是 main.cpp 编写的范例),但没有其他生成输出:在一个副本上运行脚本以查看每个脚本会生成什么。

环境设置

脚本是 TypeScript 语言,使用 bun 从本技能的目录运行。核心部分(检查、BOM、采购、指南、概念表、着陆页、固件框架)没有依赖项。

步骤需要如果缺失
外壳、PCBbun install --cwd scripts 一次(JSCAD、tscircuit,版本已锁定)脚本会打印命令并退出,返回代码3。告诉用户将要安装什么,然后运行它。
指南 PDF、截图Chrome、Chromium 或 EdgeHTML 仍然可以工作;用户从浏览器打印为 PDF。
编译固件PlatformIO (pio)仍然会生成框架;但会说明它尚未编译。
3D 渲染Blender 在 PATH 中render.ts 退出代码3并打印一行提示;页面会回退到线条图和3D查看器。

在用户选择的一个项目文件夹中工作(询问一次;默认为 ./<slug>/)。所有命令都以该文件夹为参数:bun <skill>/scripts/<name>.ts <projectDir>。

工作流程

分为六个阶段。每个阶段都以用户可以查看的产出结束,并由用户做决策。不要在用户决策前自行推进:在第一阶段的错误猜测会浪费之后的所有工作。如果用户中途到达(“我有零件了,我需要一个外壳”),则从该阶段开始,并构建最小的 project.json。

1. 构想

阅读 references/imagine.md。了解这个产品是做什么的、为谁做的、用在何处、如何供电以及用户的技能和工具水平。提供两到三个真正不同的方向,而不是同一款产品的三种尺寸。一旦方向确定,编写第一个 project.json(零件和外壳区块,暂不包含连接),然后运行:

bun scripts/concept.ts <projectDir>      # out/concept.html: 闭合视图、内部视图、尺寸、成本

向用户展示概念表(打开它,或者用 shoot.ts 截图)。决策:这是你想要的东西吗? 在这里迭代;这是改变主意成本最低的阶段。

2. 零件与电路

阅读 references/circuit.md。从 assets/parts/ 中选择零件(列出文件夹内容;每个文件都有一个 blurb 描述)。如果某个零件不在其中,则将其放在 <projectDir>/parts/ 中。焊盘位置的来源决定了指南和外壳是否可信,因此在手工输入电路板或模块的焊盘数据之前,务必先查询零件目录。一个快照随本技能一起提供;无需额外设置:

bun scripts/catalog.ts find "<确切型号>"     # 此电路板或模块是否在目录中?
bun scripts/catalog.ts pads <part_id>           # 它是否包含来自制造商 CAD 文件的焊盘位置?
bun scripts/catalog.ts import-part <part_id> --id <id> --out <projectDir>/parts/<id>.json

当 pads 列出数据集时,import-part 会生成零件文件的草稿:来自制造商文件的焊盘和轮廓、接地引脚,以及目录中已有的 GPIO 编号、逻辑电平、高度和连接器开孔。它会打印出无法推导出的信息(电源引脚、价格、通常还有高度);根据数据手册补充这些信息。只导入你将购买的确切电路板,确保同一制造商和修订版本:品牌板子的焊盘数据对同一芯片的克隆品没有任何意义。当目录中没有该零件的焊盘数据时,根据数据手册或制造商的图纸手动编写文件,遵循 references/circuit.md(“添加零件”)中的指南。然后编写 connections 并进行检查:

bun scripts/validate.ts <projectDir>     # 电气规则检查,有错误则退出代码1

错误会阻止后续流程。每个发现都会说明哪里错了、为什么错以及如何修改;修改 project.json 并重新运行,直到检查通过。警告是需要判断的问题:要么解决它们,要么用通俗的语言告知用户。永远不要为了通过检查而修改零件文件,除非该零件文件确实有误,并且如果修改了,请说明原因。如果某个零件的实际功耗超过了供电能力,并且固件会进行限制,请在零件的条目中声明 peakMa 和 peakMaWhy(参见参考文档),而不是隐藏它。

3. 采购与构建路径

决策,需要明确询问:你想要一个成品 PCB,还是想自己焊接? 用一句话解释三种路径各是什么,并为这个项目和使用者推荐一种:

build.path用户需要做什么适合的情况
wire根据指南,用杜邦线或焊接的方式连接模块一次性项目,连接少,想要这周就完成
pcb-diy订购一块空载板,然后将模块焊接到上面需要制作多个单元,连接多,想要整洁和可靠
pcb-assembled订购带插座并已焊接好的电路板,然后将模块压入或插入没有烙铁,或是作为礼物送给没有烙铁的人

然后获取实时价格。先阅读 references/sourcing-stores.md;它涵盖了哪些商店有 API、哪些需要在网页上搜索,以及用户所在国家的增值税和关税情况。

bun scripts/shopping.ts <projectDir> --region NO   # out/shopping/index.html: 用户购买的清单
bun scripts/source.ts <projectDir>       # 每个零件的候选价格和库存信息,来自有 API 的商店
bun scripts/bom.ts <projectDir>          # out/bom.csv, out/bom.md, 预估总价

从 shopping.ts 开始。它不需要任何 API:对于每个零件,它会显示图纸、清单必须匹配的条件(尺寸、引脚顺序、供电范围、高度),以及打开用户所在地区零售商正确搜索页面的按钮(两位国家代码;商店列表在 assets/stores.json)。这个页面本身足够让用户进行购买,也是你无法自行查询价格时的正确交接方式。它永远不会实际下订单。然后,在可能的情况下,进一步查找真实的商品列表和价格:

捆绑的零件目录(references/catalog.md)包含制造商事实,而非价格:find 和 show 返回带有来源链接的尺寸和引脚信息,用于编写零件文件。一个完整的目录(通过 --db 或 BENCHTOP_CATALOG 指定)还包含商店列表:bun scripts/catalog.ts listings "<part>" --norway。其数字是卖家和制造商的声明,而非测量数据。

期望 API 商店找不到通用的克隆模块(大多数项目使用的廉价传感器和显示板),而是提供一个不同尺寸或引脚顺序的品牌电路板。那不匹配:在参考文档中命名的网络零售商处搜索零件文件描述的精确型号。

source.ts 收集候选信息;由你选择。优先选择一两家商店而不是五家(小订单运费占主导),检查每个商品列表是否与零件文件是相同型号(不同克隆品的引脚顺序和尺寸不同),并将你的选择写入 project.sourcing:每个零件一行,在其 note 中注明要选择的型号,每个商店一行 shipping 条目(如果商店只在结账时显示运费,则省略其 price)。当一个商品列表提供多个零件时(例如,一个电阻器套装中含有三个电阻),给它一行,并在 covers 中注明其他参考编号。用户声称已经拥有的零件,在其 parts 条目标记为 "owned": true 而不是一行商品信息:它仍会出现在指南和检查中,但不计成本,购物页面会告诉用户需要检查抽屉里那个零件哪些参数。重新运行 bom.ts;它会打印包含运费的实际总价。在用户下单前向他们展示这个数字。商店报告为“不可用”是其自身的问题,而不是停止的理由:继续与其他商店合作。

4. 构建文件

根据所选路径生成所需文件,然后在展示每个输出之前先自行检查。在迭代过程中,只运行正在处理的那个脚本。在交付任何成果之前,完整运行一次整个流程,以确保没有文件是过时或缺失的:

bun scripts/build.ts <projectDir> --region NO   # 按顺序执行每一步;如果电气检查失败则停止

它会打印每一步的一行摘要,将所有生成器标记的任何问题汇总到一个列表中,并写入 out/build-report.md。如果跳过了某一步,它会告诉你原因(缺少 Blender,还没有展示文案等)。它会编译固件:编译错误会导致构建失败,并且对某个芯片系列的第一次编译会下载其工具链(大约 1 GB,需要几分钟),这是正常现象。报告显示 NOT COMPILED 意味着固件未经检查;在交接时说明这一点。各个独立的脚本:

bun scripts/guide.ts <projectDir> --pdf  # out/guide/index.html + guide.pdf
bun scripts/enclosure.ts <projectDir>    # out/enclosure/: body.stl, lid.stl, .3mf, assembly.glb, print.md
bun scripts/pcb.ts <projectDir>          # pcb paths only. pcb/board.tsx + out/pcb/: gerbers.zip, schematic.svg, pcb.png, order.md
bun scripts/firmware.ts <projectDir>     # firmware/: platformio.ini, include/pins.h, bring-up test, main.cpp skeleton
bun scripts/compile.ts <projectDir>      # compiles bring-up and main with PlatformIO; errors as file:line
bun scripts/render.ts <projectDir>       # out/renders/: hero.png, hero-alpha.png, exploded.png, top.png (needs Blender)
bun scripts/drawing.ts <projectDir>      # out/drawings/: wiring plan, dimensioned case drawing, pin map, 1:1 fit-check sheet
bun scripts/shoot.ts <projectDir>/out/guide/index.html <projectDir>/out/shots --pages 1,3,4 --width 900

在运行每一步之前,阅读相应的参考文档:references/guide.md、references/enclosure.md、references/pcb.md、references/firmware.md、references/renders.md、references/drawings.md。每个文档都解释了需要检查什么,以及当结果不正确时需要在 project.json 中修改什么。然后,将实际的固件行为写入 firmware/src/main.cpp,仅使用 pins.h 中的常量。

外壳和 PCB 脚本会打印警告(通风口被另一个零件挡住、端口够不到外壳壁、线接式零件未放置在电路板上)。这些是设计问题,不是噪音。修复布局,或者告知用户后果。

guide.ts 和 drawing.ts 在每次构建时都会自我检查它们生成的图纸,并对每个问题打印一行信息:一根线结束在隐藏于更高组件后面的焊盘上;一个引脚名称没有清晰的放置位置;在分解视图中零件重叠;接线图中的线穿过另一个零件。每一行都会指明页面、步骤和零件。布局问题可以使用 bench 修复;渲染问题属于生成器,未解决的几何问题需要源数据。不要为了消除渲染器的发现而修改正确的零件几何数据。标记为 geometryEvidence.status: "unresolved" 的零件(其文件的布局与证据相矛盾;目前是 INMP441 麦克风)仍然可以构建:外壳、图纸、指南和包都是根据文件中的数字制作的,每次构建都会打印一次 warning:,并且每个受影响的输出都会带有“布局未经验证”的标记。在交接时首先重复该警告,告诉用户在打印前测量零件并在项目的 parts/ 文件夹中更正它,并且永远不要将这样的外壳称为“准备好打印”。适配性测试打印是最后一道关。--strict-geometry(或 BENCHTOP_STRICT_GEOMETRY=1)会将警告变回拒绝,并附带一个部分逻辑指南;载板 PCB 在任何模式下都会被拒绝,因为电路板需要花钱,没有廉价的适配性测试。--strict 会在任何图纸发现未解决时以非零状态退出。干净的检查仅意味着测试的图纸不变性成立,而不是零件文件本身是正确的。

5. 展示

阅读 references/showcase.md。编写 showcase 区块(标题、工作原理、特点、统计数据、常见问题解答、主题),然后:

bun scripts/package.ts <projectDir>      # dist/<slug>/ (index.html, guide/, files/) + dist/<slug>.zip
bun scripts/shoot.ts <projectDir>/dist/<slug>/index.html <projectDir>/out/shots --width 1320 --height 2400

仔细查看页面:--from 2400 会捕获从 2400 像素向下开始的窗口。文案由你负责,它是区分产品页面与仅仅替换了名词的模板的关键;参考文档说明了如何编写文案以及如何选择主题。一旦每个零件都有对应的商品行,页面上的价格就来自 project.sourcing。以项目货币以外的货币购买的商品行,会带有自己的 currency;然后按每种货币显示总价(“401 NOK + 7.95 USD”),并且从不进行转换。没有采购信息的页面会说明该数字是基于典型价格的估算。

package.ts 每次都会根据 project.json 重新生成指南,因此永远不要手工修正生成的文件:修正会在下次运行时丢失,并且在此之前这些文件彼此不一致。如果一个生成器有问题,请修改其输入,如果无法通过这种方式使其正确,则在输出中告知用户问题所在,而不是静默地修补。

6. 交付

简要告知用户:打包文件的位置、项目总成本、首先需要做什么,以及哪些内容尚未经过验证。请具体说明。参见“此处的精度含义”。

此处的精度含义

在将克隆零件用于外壳或载板 PCB 之前,请阅读 references/geometry-evidence.md。检查 assets/geometry-evidence/ 文件夹,了解测量的验证状态。

关于 Philosophy

...(原文后续部分,包括“关于 Philosophy”、“关于 lang”和“关于代理”等章节,因翻译提示中标记为已截断,此处保留原文结构但按注释说明处理;若需完整翻译,需提供全文)


(原文后续内容涉及项目理念、语言设置、AI 代理行为等,因原始输入被截断,已无法精确翻译。如需完整中文版 SKILL.md,请提供技能完整的原始英文文档。)

相关技能