本文件供在本仓库工作的 AI 编程助手使用,也供维护者审核和调整协作约定。适用于仓库根目录及子目录;子目录如有更具体的 AGENTS.md,在该目录范围内遵循其补充要求。用户当前任务中的明确要求优先于本文的默认约定。
- 默认使用简体中文沟通,代码标识符、命令和日志字段保持原文。
- 开始修改前检查
git status --short,按任务需要阅读相关源码、配置、测试和文档;不要把历史报告当作当前工作区的验证结果。 - 保留已有未提交修改和其他任务的工作,只修改本次任务相关文件。不要擅自执行
git reset --hard、git checkout --、git clean或批量清理证据目录。 - 不要过度优化项目内容。围绕当前需求和已确认的问题做必要修改,优先复用现有实现;避免没有明确收益的重构、抽象、依赖引入及无关优化。
- 保持项目简洁,不生成无用或重复的文件。优先更新已有文件;本次会话创建且不属于交付内容、也无需保留为验证证据的临时文件,必须在会话结束前删除。清理仅限本次创建且确认不再需要的文件,保留用户文件、其他任务成果、必要的测试及历史验证证据。
- 项目相关的文件生成(隔离构建目录、工作区快照、临时脚本、草稿和中间产物等)统一放在仓库根目录下,通过
.gitignore配置过滤不提交;不得在C:\、D:\等仓库外路径散落创建(历史反例如C:\p11、C:\px-rgb20、D:\project\fastbee-*,已于 2026-10-15 清理)。隔离构建目录和工作区快照以fastbee-开头命名,临时产物放入已忽略的tmp/。 - “只评估”“只诊断”“审核”按只读任务处理;“修改”“实现”“完善测试”则完成相应实现和验证。已明确授权的常规步骤继续执行,遇到目标设备不明、改动冲突或需要扩大范围时再说明具体阻塞。
- 用户要求继续完成某份计划时,以该计划及其当前实施记录为工作清单,逐项落实并更新证据;不要只输出方案,也不要把存在实物依赖的项目标成全部完成。
- 未要求提交或发布时,将结果保留为可审核的本地改动。
FastBee-Arduino 是面向 ESP32 系列的零代码 Web 物联网固件,通过“外设配置”定义并初始化硬件资源,通过“外设执行”配置触发器、条件、动作及联动规则,通过 MQTT/MQTTS 与物联网平台通信,通过 Modbus RTU 主站接入现场设备。
固件使用 C++、Arduino 框架和 PlatformIO;Node.js 用于 Web 资源构建及主机测试,不是设备运行时。芯片、Flash、PSRAM、分区和功能裁剪以 platformio.ini 及对应板卡配置为准。
| 路径 | 职责与修改入口 |
|---|---|
src/、include/ |
固件实现及对应头文件,按同名模块组织(core、network、peripherals、protocols、screen、security、systems、utils) |
src/core/ |
框架、外设管理、执行调度、规则和电机控制服务 |
src/network/、src/network/handlers/ |
网络适配、Web 服务和 API 路由 |
src/protocols/、src/peripherals/ |
MQTT、Modbus RTU 及外设驱动 |
src/screen/、src/security/、src/systems/、src/utils/ |
屏幕交互、认证、配置存储、日志、健康管理和通用工具 |
web-src/ |
HTML、JavaScript、CSS、页面模块和中英文文案源码 |
data/config/ |
LittleFS 默认配置,不代表在线设备当前配置 |
data/www/ |
自动生成的 Web 发布资源;源资产例外见下文 |
partitions/、platformio.ini |
分区布局、依赖、构建环境和编译能力 |
scripts/ |
构建、资源生成、部署、验证及诊断入口 |
test/ 根目录 test_*.cpp |
Native 主机测试用例(run_tests.cpp 为入口) |
test/unit/、test/helpers/、test/mocks/、test/fixtures/ |
主机测试、C++ 测试辅助代码、模拟依赖及测试数据 |
test/browser/ |
Playwright 离线/设备测试(设备发现辅助在 test/helpers/) |
docs/ |
公开配置样例、专项设计、改进计划和验收说明 |
images/ |
文档及 README 引用的图片 |
vendor/ |
仓内固化的第三方源码(如 esp-idf-rgb-*),配合 patches/ 维护 |
managed_components/ |
ESP-IDF 组件管理器输出,可由 dependencies.lock 恢复,不提交 |
tmp/ |
本地临时产物,不提交 |
.pio/、node_modules/、dist/、artifacts/ |
构建缓存、npm 依赖、发布产物和本地验证证据,不作为业务源码编辑 |
- 固件修改沿用现有 manager/service/driver 分层,同时检查对应头文件、调用方和错误路径。外设访问、资源仲裁及电机动作通过既有服务处理,避免在 Web 路由或页面中绕开它们。
- 区分“已编译”“用户已启用”和“运行时实际可用”。增加能力时同步检查编译宏、运行时开关、资源预算、API 和 Web 展示,不能只让页面显示为可用。
- 对具有额外内存开销、且并非所有设备都必需的功能,优先纳入现有“功能配置”,复用
RuntimeFeatureManager、features.json和资源预算机制,让用户按需启用。新增可选功能默认关闭,保留已有设备的用户选择,避免另建平行开关体系。 - 功能开关应控制实际资源生命周期:未启用时避免初始化专属资源或启动后台任务,关闭后停止相关任务并安全释放可回收的专属 RAM/PSRAM;需要重启才能生效或无法动态回收的资源应明确说明。资源节省区分估算与实测,运行时关闭不等于减少固件 Flash 体积,Flash 体积优化通过编译期裁剪处理。
- 修改配置结构、逻辑 ID 或协议字段时保留旧配置兼容;迁移失败不能静默重置用户配置。新增 API 或改变裁剪行为时检查
scripts/device-api-test-matrix.json及相应契约测试。 - 修改 Web 页面只编辑
web-src/,再通过构建脚本生成发布资源。data/www/assets/logo.png与data/www/assets/favicon.ico是受 Git 跟踪的源资产例外,隔离构建时必须保留。 - HTML/JS/CSS 发布资源采用 gzip-only 形式,使用现有清单和资源检查流程;不要直接修改生成的 bundle、
.gz或 Service Worker 清单来修复问题。 - 界面文案直接以中文硬编码(UTF-8),与现有硬编码文案保持一致;新增或修改文案时检查窄屏布局、加载状态、失败提示和离页后的异步回调。
- 遵循
.editorconfig和相邻代码风格,避免顺手格式化无关文件。文本使用 UTF-8;C/C++ 以.clang-format为参考。 - 依赖或底层库补丁通过现有配置及
patches/、补丁脚本维护,不把对.pio/、node_modules/的手工修改作为交付结果。
项目目标是让 ESP32、ESP32-C3、ESP32-C6、ESP32-S3 在各自受支持的硬件、内存配置和声明负载范围内长期稳定运行。资源不足时必须明确拒绝超限配置或进入可恢复的保护状态,不得崩溃、静默丢失配置或伪造业务成功。本文规定开发与验收要求,不代表设备已经通过长期验证。
正式发布矩阵以 platformio.ini、README.md 和生成的能力矩阵为准;当前包括:
| 芯片 | 构建环境 |
|---|---|
| ESP32 | esp32-F4R0、esp32-F8R0、esp32-F8R8 |
| ESP32-C3 | esp32c3-F4R0 |
| ESP32-C6 | esp32c6-F4R0、esp32c6-F8R0 |
| ESP32-S3 | esp32s3-F8R0、esp32s3-F8R8、esp32s3-F16R8 |
- 环境名中的
F表示 Flash,R表示 PSRAM;内部 RAM 还需按芯片和运行时实际可用量评估。部署时核实实际容量、总线模式及初始化结果,不能只按环境名推断内存可用。 - 跨芯片公共逻辑、内存管理、调度、协议或构建配置变更,应覆盖全部正式构建环境,并按芯片、PSRAM 有无及容量、板卡和业务负载分别记录实机结果。缺少对应硬件或证据时标记“待验证”,不以一台 S3 的结果代表其他组合。
- 其他容量、厂商自定义板卡及 RGB 专用构建需单独核验配置、资源预算和实机行为,不能直接继承正式环境的通过结论。新增或删除正式环境时同步本表及相关测试清单。
- 离线浏览器覆盖以
test/browser/offline-device-profiles.json和实际执行用例为准;检查其与目标矩阵的差异,不能把部分模拟配置通过描述为全部内存组合通过。
- 内存与容量准入:分别统计内部可按字节访问的 DRAM、最大连续块、任务栈和 PSRAM;PSRAM 余量不能代替内部 RAM 预留。组合预算计入外设、规则、首次执行、日志、Web 响应及网络缓冲峰值,分配失败须可处理。新建、修改、导入和启动加载使用一致的容量校验,超限时保留原有效配置及运行态。
- 有界调度与积压:队列、缓存、历史、日志、连接数和并发任务均设置容量及回收规则,通信、锁等待和重试有明确超时。沿用既有任务池、总线仲裁和非阻塞调度,避免拖住主循环或长期饿死采集任务;看门狗反映实际任务进展,不能靠盲目喂狗掩盖阻塞。计时逻辑覆盖计数器回绕及 NTP 校时变化。
- 功能与保护状态:功能生效须满足编译支持、用户启用、依赖就绪、资源预算和初始化成功,并受运行期保护状态约束。临时限流或降级保留用户原有启用意图,显示原因和恢复条件,不因一次资源不足永久关闭规则或删除配置。
- 断线与外设故障恢复:WiFi、MQTT 和外设通信失败采用有界超时与退避,恢复后验证连接、订阅和业务数据。具备离线运行条件的本地采集及规则继续工作;无响应外设不能阻塞其他任务。过期、结果不明或未获准的电机、继电器等动作不得在恢复后擅自重放。
- 持久化与 Flash 寿命:配置保存、导入及迁移使用既有事务或原子替换机制,覆盖写入失败、断电和重启恢复;失败时保留可恢复的有效版本。避免每次采样或轮询写 Flash,按需求合并写入、限制频率并轮转日志,文件空间不足时明确报错。
- 业务数据完整性:采集值保留时间及有效性,缺失、过期或错误读数不能用零值伪装成功;有效的零值仍应正常处理。HTTP 成功需包含完整正文,SSE 心跳不代表业务数据更新,按钮确认或指令入队不代表动作完成。
- 验证前固定设备身份、固件/Web 摘要、配置版本、启用功能、预期业务及负载范围;按同一套配置和执行模型覆盖无 PSRAM、带 PSRAM、资源受限及组合峰值场景。预期功能依据用户配置确定,不能从故障后的降级状态反推验收目标。
- 相关变更覆盖重复启停、持续采集与上报、浏览器访问、断网重连、外设超时、分配失败及配置恢复。正常负载长测与超负载/故障注入分开记录;后者预先定义预期错误、恢复时限和输出安全状态,不能把预期注入故障混入正常窗口后忽略失败。
- 正式长期验收按
scripts/README.md的 8 小时 Web 功能验收、24 小时及后续 72 小时设备观察流程执行,逐硬件组合核实实际时长、采样覆盖和预期业务持续有效。只读探活不能替代 MQTT/Modbus 数据、规则执行及必要的实物反馈证据;特殊场景有更严格要求时遵循对应计划。 - 内存、延迟、失败率和重启门槛复用
scripts/device-stability-thresholds.json及对应验收脚本,按实际硬件条件选择并核验。新增容量分档需有测量依据,不为取得通过结论放宽阈值;报告同时保留内部 RAM、最大连续块、PSRAM、任务栈、积压量及其趋势,缺少相关采样时明确说明覆盖不足。 - 正常声明负载下的异常重启、OOM/看门狗复位、持续内存泄漏、超阈值下降、正文截断、非预期失败、
no-memory降级或 WebGuard503均不得判定为严格稳定性通过。超负载下的保护行为需另外验证拒绝有界、状态可见、恢复后业务正常。 - 只有本次报告的退出状态、结果字段、时长、覆盖和业务门槛均满足要求,才能对对应组合报告“长期稳定通过”。中断、跳过或不足时长不得判通过;支持续跑的观察须保留原始证据且停机时间不计入有效时长,要求连续运行的窗口不能靠拼接中断前后数据满足。
以下命令从项目根目录执行。使用 Node.js 20+、Python 3 和 PlatformIO;本机 python 可能指向旧版本,执行 Python 脚本前确认解释器,优先使用已配置的 PlatformIO 虚拟环境或脚本支持的 FASTBEE_PYTHON。Native 测试还需要可用的主机 C++ 工具链。
需要首次安装或恢复锁定依赖时执行;已有可用依赖时不必重复安装:
npm ci
npm ci --prefix test/browser
npx --prefix test/browser playwright install chromium按改动范围选择检查,命令定义以当前 package.json、test/browser/package.json 和脚本为准:
断点续跑原则(2026-10-15 约定):测试链、部署流程和其他多步骤脚本在某一步报错时,修复该处问题后从失败步骤继续执行,不要每次从头全量重跑(如 npm test 失败于 test:contracts,就修复后先单独重跑对应脚本/套件,确认绿后再视需要补跑后续段;部署四台设备失败于第二台,就修复后从第二台继续,不重复已成功的第一台)。全量重跑只用于最终整体验证或失败根因不明的场合。
| 场景 | 入口 | 验证范围 |
|---|---|---|
| 纯文档修改 | node scripts/check-utf8-text.js AGENTS.md,将文件参数替换为实际改动路径 |
编码;另检查链接和 diff,不要求固件编译 |
| 日常代码回归 | npm test |
静态门禁、契约与主机单元测试;包含 Web 资源生成 |
| 定向单元回归 | npm run test:unit 或对应测试脚本 |
受影响逻辑,不能自动替代其他相关门禁 |
| C++ Native | npm run test:native |
主机编译与 Native 用例,不连接设备 |
| 主机加 Native | npm run test:regression |
主机门禁和 Native 回归 |
| 指定固件环境 | npm run test:firmware -- esp32s3-F16R8 |
固件、LittleFS 构建及当前产物校验,不烧录 |
| Web 发布资源 | node scripts/build-web-assets.js --env=esp32s3-F16R8 |
生成目标环境的 data/www/,不上传 |
| 浏览器用例收集 | npm run test:e2e:collect |
检查用例能否解析,不证明界面功能通过 |
| 离线浏览器回归 | npm run test:e2e:offline |
本地模拟服务上的交互及布局,不代表实机结果 |
| 默认构建回归 | powershell -NoProfile -ExecutionPolicy Bypass -File scripts/test-all.ps1 |
默认启用 static/native/build:主机回归、Native 和九个正式固件环境构建;不含独立 artifacts 阶段及完整离线浏览器矩阵 |
表中的 esp32s3-F16R8 只是示例,必须按实际改动选择目标环境。npm run test:firmware 不带环境参数会运行全部正式环境。npm run test:e2e、test:e2e:device 属于设备测试入口,不能当作默认离线测试执行。
发布前应补齐产物与浏览器检查:在 PowerShell 中执行 ./scripts/test-all.ps1 -Checks static,native,build,artifacts,并单独执行 npm run test:e2e:offline。这些检查仍属于本地验证;设备检查、部署和实物验收按本次发布范围及授权另行执行,不能以默认命令通过代替全部发布验收。
逻辑和行为变更应补充能覆盖原问题的测试,并检查 scripts/validate-test-coverage.js 的登记要求。修改芯片宏、驱动、库或分区时执行相关固件构建;跨芯片改动和发布验证按影响范围扩展矩阵。仅文字调整使用文档检查即可。
- 同一工作区的 PlatformIO、Host/Native 回归、Web 资源生成,以及同一设备的串口读写和部署需串行安排;共享构建或设备操作使用
scripts/firmware-build-lock.ps1。锁被占用时等待,不删除锁文件或终止其他任务的进程。 deploy.ps1、test-all.ps1和 Native/固件测试入口已接入锁;直接运行npm test、Web 构建或其他未包锁命令时,在外层获取同一把锁。Web 构建自身的发布锁不能代替整个构建/部署流程的协调。deploy.ps1入口固定~/.platformio/penv/Scripts到 PATH 最前并清除PYTHONHOME/PYTHONPATH(penv 环境守卫),防止旧版 mingw64/Git 运行时抢占导致 pio 子进程随机失败;主机单元测试由scripts/run-unit-tests.js做同样的编译器运行时前置。- 多个任务正在修改源码时,正式构建应固定源码、配置和测试输入并保留摘要。构建期间输入变化,产物不能作为该次发布的有效证据。
手动包锁示例,try 内替换为本次需要的命令,并检查每条命令的退出码:
. ./scripts/firmware-build-lock.ps1
$taskBuildLock = Enter-FastBeeFirmwareBuildLock -ProjectRoot (Get-Location).Path -Label 'host-regression'
try {
npm test
if ($LASTEXITCODE -ne 0) { throw "npm test failed: $LASTEXITCODE" }
}
finally {
Exit-FastBeeFirmwareBuildLock -Handle $taskBuildLock
}需要统一构建入口且不烧录时,可执行:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy.ps1 -Env esp32s3-F16R8 -BuildOnlydeploy.ps1 不带 -BuildOnly 会进入设备写入流程;执行前必须满足下节的目标核验和配置保留要求。RGB 触屏等专用板卡还需对应板级配置,不能仅凭同为 ESP32-S3 就使用通用构建替代。
- 设备测试、烧录、配置导入、重启和外设动作必须处于用户已授权范围。代码修改本身不代表要操作任何已连接设备;已有明确部署授权时,不重复询问相同授权。
- 每次访问设备前核对连接目标与预期 MAC/芯片身份;网络访问核对当前 STA 地址,串口访问核对当前端口。历史 IP、串口编号和相同构建环境都不能单独证明是同一台设备。
- 烧录、分区调整或文件系统写入前,再核对 Flash/PSRAM、分区布局及适用时的活动 OTA 槽。只读 API/Web 巡检无需为这项写入预检额外打开串口或让设备进入下载模式。
- 升级在线设备时,先备份并保留设备身份、网络、认证、MQTT、外设、协议、规则、屏幕布局及非 Web 文件。公开
docs/样例和data/config/不能直接覆盖现场配置,不能把另一台设备的备份套用到目标设备。 - 区分完整固件更新与仅 Web 更新。仅 Web 更新应保留应用固件、启动和分区信息、NVS 及非 Web 文件;写入范围、当前产物摘要和校验结果必须可追溯。普通全量烧录不能默认视为配置保留升级。
- 设备轮询保持适当间隔,按现有脚本处理超时及限流;不要用高并发重试、无效零值、反复重启或关闭用户功能掩盖异常。
- 电机、继电器和其他输出遵循现有资源仲裁、行程准入及故障保护。电机提示
TRAVEL_REFERENCE_REQUIRED时检查参考位置和准入条件,不通过取消保护或自动重试启动来消除提示。 .device-config-backups/、Flash 备份、认证 Cookie 和含凭据的日志属于私有材料,不提交、不写入公开样例,也不在回复中输出其敏感内容。
| 结论 | 所需证据与边界 |
|---|---|
| 本地通过 | 本次相关测试的退出码、结果和输入版本;不代表设备通过 |
| 构建通过 | 对应环境的实际编译及产物校验;不代表已经写入设备 |
| 部署完成 | 本次目标设备、产物摘要、写入与读回校验;使用部署报告时核实本次 written=true、verified=true 等字段,不能沿用旧报告 |
| 设备 API/Web 通过 | 当前设备的请求、资源和界面证据;按钮响应或寄存器读回不证明物理动作 |
| 实物通过 | 实际触摸、输出动作、测量或现场反馈;电机运动不能仅凭 UI 确认或 Modbus 成功判断 |
| 长期稳定通过 | 对应芯片、内存配置和负载满足上述长期验收的时长、采样、资源及业务门槛;短时恢复或其他硬件的通过不能替代 |
- 未执行、缺少硬件、输入变化、观察中断或时长不足时,明确标记“待验证”及原因。
- 新一轮验证使用独立输出目录,保存输入摘要、日志和报告;脚本支持的同一轮断点续跑可在核对原设备、版本和配置后向原目录追加记录。保留历史失败,不能覆盖失败文件,也不能让后续恢复把整个观察窗口改成通过。
- 最终交付说明修改了什么、验证了什么、尚缺哪些证据,并给出关键文件及报告路径。涉及既有计划时同步维护对应实施记录,不扩大完成范围。
- 设备端文档维护在独立的
FastBee-doc仓库,本机目录为D:\project\gitlab\FastBee-doc\src\device。修改前先检查该仓库适用的AGENTS.md和git status --short,保留已有改动;本机目录不存在时,查阅在线设备端文档。 - 项目能力与构建环境:README.md、生成的能力矩阵。
- 测试、部署和诊断脚本:scripts/README.md。
- 公共资源、容量准入及恢复要求:资源与稳定性验收约束;量化验收门槛:设备稳定性阈值。历史实施记录不作为本次通过证据。
- 设备样例与私有备份边界:docs/README.md,再按目标板卡查看对应子目录。
- 系统改进任务:项目审计与改进计划(含顺序执行步骤与在途事项接管);2026-10-01 系统改进计划集群与 2026-10-05 交接文档已于 2026-10-13 清理,历史内容见 git 记录。
- 持续集成检查:.github/workflows/ci.yml。
AGENTS.md文件约定:OpenAI 官方说明。