首页
/ EEZ Studio 的 Agent 原生 CLI 工具链:cli-anything-eez-studio 实战指南

EEZ Studio 的 Agent 原生 CLI 工具链:cli-anything-eez-studio 实战指南

2026-09-08 16:38:49作者:齐冠琰

cli-anything-eez-studio 是 CLI-Anything 生态为 EEZ Studio 提供的 Agent 原生(agent-native)命令行工具集,它让大模型 Agent 可以像人类工程师一样:直接读写原生 .eez-project 工程 JSON、批量搭建 LVGL 界面与控件、维护 SCPI 仪器指令元数据,并通过真实的 EEZ Studio Node/Docker 后端完成 LVGL 模拟器构建。读完本指南,你将掌握该工具从安装、日常命令、会话回滚到后端桥接的全部用法,能够在脚本、CI 与 Agent 工作流中可靠地自动化 EEZ Studio 项目。

一、工具定位与架构总览

EEZ Studio 是面向嵌入式 UI 的 Electron/Node 应用,主要承载 LVGL 代码生成、SCPI 仪器模型编辑与 Flow 流式自动化三类任务。官方工程文件是一个以 .eez-project 结尾的 JSON 文档。cli-anything-eez-studio 的总体设计遵循"双轨制":

  • 纯单元命令:直接在 Python 侧解析、改写原生 .eez-project JSON,不依赖 EEZ Studio 本体即可完成工程创建、LVGL 控件脚手架、SCPI 元数据维护;
  • 后端桥接命令:通过 EEZ_STUDIO_SOURCE 指向一个真实构建好的 EEZ Studio 源码树,调用其编译产物(如 build/project-editor/lvgl/docker-build/docker-build-lib.js)完成工程解析与 LVGL 模拟器构建。

这段设计意图可以在仓库的架构文档 EEZ_STUDIO.md 与入口 CLI 源码 eez_studio_cli.py 中互相印证。整个 agent-harness 的目录组织如下:

eez-studio/agent-harness/
├── setup.py
└── cli_anything/eez_studio/
    ├── eez_studio_cli.py        # click 命令行入口与全部命令组
    ├── core/
    │   ├── project.py           # .eez-project 原生 JSON 读写与 LVGL 结构构造
    │   ├── scpi.py              # SCPI 子系统/命令/参数模型维护
    │   ├── session.py           # 会话状态、undo/redo、持久化
    │   └── export.py            # 后端构建编排与产物校验
    ├── utils/
    │   ├── eez_studio_backend.py  # 定位 EEZ Studio 源码树、调用其 Node 模块
    │   └── repl_skin.py           # REPL 交互皮肤
    ├── skills/SKILL.md           # 本文所述的 Agent Skill 定义
    ├── tests/                    # 单元与端到端测试
    └── README.md

二、安装与环境准备

Skill 文档给出的安装方式如下,它本质上是把 eez-studio/agent-harness 以可编辑模式装入当前 Python 环境:

cd eez-studio/agent-harness
pip install -e .

查看 setup.py 可以看到安装约束:Python >= 3.10,运行依赖仅 click>=8.0.0prompt-toolkit>=3.0.0,并通过 console_scripts 注册了 cli-anything-eez-studio 命令。也就是说纯工程编辑场景的依赖非常轻。

后端命令还需要真实的 EEZ Studio 源码树。Skill 与源码 eez_studio_backend.py 中给出的标准流程是:

# 获取 EEZ Studio 官方开源源码树并构建
git clone https://github.com/eez-open/studio.git
cd studio
npm install
npm run build
# 关键:让工具定位到构建产物
export EEZ_STUDIO_SOURCE=/absolute/path/to/studio

环境中与后端相关的变量可以总结如下:

环境变量 作用 取值来源
EEZ_STUDIO_SOURCE 指向构建好的 EEZ Studio 源码树(其 package.jsonname 须为 eezstudio 源码 find_source_tree()
EEZ_STUDIO_NODE 覆盖 node 可执行文件路径,缺省时用 shutil.which("node") 查找 源码 find_node()
EEZ_STUDIO_BUILD_COMMAND 自定义的原生 EEZ 构建命令,配合 lvgl build-files 使用 源码 run_custom_build_command()
EEZ_STUDIO_RUN_LIVE_BACKEND 置 1 时开启需要真实后端的在线 E2E 测试 测试文档

全量 LVGL 模拟器构建(lvgl simulator-build)额外要求 Docker 可用。若后端缺失,相关命令会**大声失败(fail loudly)**并给出上述安装指引,而不是静默返回错误结果。

三、核心用法:JSON 输出与工程脚手架

Skill 明确强调:面向 Agent 的输出一律使用 --json。在 CLI 顶层传入 --json 后,所有子命令都会输出结构化的 JSON(实现见 eez_studio_cli.pyoutput()/_emit_error()),便于下游直接 json.loads;不加 --json 时则以人类可读的缩进文本输出。

Skill 中给出的最小可用流程,是一口气完成"建工程 → 放控件 → 查看控件"的闭环:

cli-anything-eez-studio --json project new -o panel.eez-project --name Panel
cli-anything-eez-studio --json --project panel.eez-project lvgl add-label --text "Ready"
cli-anything-eez-studio --json --project panel.eez-project lvgl add-button --text "Run"
cli-anything-eez-studio --json --project panel.eez-project project widgets

这里体现了一个重要的会话/持久化语义:单条带 --project 的命令会自动保存工程变更,除非显式传 --dry-run。这个"自动保存"由 CLI 的 call_on_close 钩子实现(见 _auto_save,仅当非 REPL、非 --dry-run 且工程确有修改时触发)。

顶层全局选项汇总如下(均出自 CLI 入口 eez_studio_cli.py):

选项 含义
--json 输出机器可读 JSON
--project / -p PATH 打开指定的 .eez-project 文件
--session ID 指定会话 ID
--dry-run 不自动保存工程修改

3.1 创建工程时的重要参数

project new 并不是只写一个文件名,它会根据 EEZ Studio 原生模型生成一个结构完整的 LVGL 工程。可用参数与默认值如下(对应源码 create_project()):

选项 默认值 说明
--name / -n Untitled 工程名,写入 settings.general.projectName
--width 800 LVGL 显示宽度(必须为正整数)
--height 480 LVGL 显示高度(必须为正整数)
--lvgl-version 9.2.2 LVGL 版本号,常量见 project.pyDEFAULT_LVGL_VERSION
--destination src/ui 构建输出目录,写入 settings.build.destinationFolder
--flow-support 关闭 是否启用 EEZ Flow 支持标记
--output / -o 必填 生成的 .eez-project 文件路径

从源码 create_project() 可以看出生成的原生 JSON 骨架:settings.general(projectName、projectType=lvgl、projectVersion=v3、lvglVersion、displayWidth/Height、colorBpp=32 等)、settings.build(含 6 个带 //${eez-studio LVGL_*_DECL/DEF} 标记的模板文件 ui.h/ui.c/screens.c/screens.h/vars.h/actions.h、destinationFolder 等)、userPages(默认一个名为 Main 的页面及其 LVGLScreenWidget 根组件)、以及 scpiinstrumentCommandsvariablesstylesfonts 等空白集合。工程还会附带一个 cliAnything 标记字段,记录是由哪个 harness、在什么时间以何种格式生成的,便于溯源。

3.2 工程查看与修改命令

project 命令组还包含一组常用子命令(技能原文 + README 均给出全量清单):

子命令 作用
project open PATH 打开现有工程并做结构校验
project save [PATH] 保存当前工程
project info 输出工程摘要(名称、类型、版本、LVGL 版本、显示尺寸、页面/控件/SCPI 统计等)
project validate [PATH] 校验原生工程结构并返回 {"valid": true}
project pages 列出页面/屏幕及各自控件数
project widgets [--page NAME] 列出控件(可过滤页面),含坐标尺寸、文本与父子关系
project set KEY VALUE 设置 settings.general 白名单键
project set-destination DIR 设置 settings.build.destinationFolder
project add-build-file FILE --template ... 新增或替换构建模板文件

注意 project set 并不是任意键都能写:源码 project.py 只允许 projectNamelvglVersionflowSupportdisplayWidthdisplayHeightcolorBpp 六个键,其中宽高会被强转正整数、flowSupport 会做布尔字符串归一化(true/1/yes/on 等)。

四、LVGL 界面脚手架:页面、标签与按钮

lvgl 命令组在 Agent 场景里最常见的使用方式是"照需求快速搭 UI"。核心命令:

子命令 关键选项 说明
lvgl add-page NAME [--width] [--height] 宽高缺省继承工程显示尺寸 新增 LVGL 页面/屏幕
lvgl add-label --text TEXT --page(默认 Main)、--name--x(20)、--y(20)、--width(160)、--height(32) 在页面根组件下加 LVGLLabelWidget
lvgl add-button --text TEXT --page(默认 Main)、--x(20)、--y(72)、--width(140)、--height(48) LVGLButtonWidget,并自动挂一个同名 _label 子控件

从源码可以看出控件在 JSON 中的落位方式(project.py):

  • 每个控件都通过 objID = uuid4().hex 生成唯一对象 ID;
  • 控件统一携带 left/top/width/heighthidden/clickableFlag/checkedFlag/disabledFlag 等 LVGL 原生字段;
  • 标签与按钮都挂到目标页面 components[0](即屏幕根组件)的 children 数组里;
  • 控件名若未显式提供,会用文本经 sanitize_identifier() 归一化生成(非字母数字统一转下划线、首字符为数字时加 screen_/button_ 前缀)。

所以执行完 Skill 示例后,project widgets 输出的就是"Main 页上有几个标签、几个按钮以及它们的位置尺寸"这类信息,Agent 可据此判断 UI 是否已按预期搭建。

4.1 准备构建目录

cli-anything-eez-studio --json --project panel.eez-project lvgl ensure-destination

该命令读取工程 settings.build.destinationFolder(默认 src/ui),在工程文件同级的对应路径下创建目录,并返回绝对路径与 exists 标记。源码要求工程必须先保存为文件(需要 project_path)才能确定"工程文件同级"的位置,否则会报错提示。这是纯本地、不依赖后端的命令,适合在脚本早期阶段调用。

五、SCPI 仪器指令元数据管理

针对"仪器前端"型项目,工具提供 SCPI 模型的三级结构维护:子系统(subsystem)→ 命令(command)→ 参数(parameter)。Skill 给出的示例:

cli-anything-eez-studio --json --project panel.eez-project scpi subsystem-add SOURCE
cli-anything-eez-studio --json --project panel.eez-project scpi command-add SOURCE :VOLTage?
cli-anything-eez-studio --json --project panel.eez-project scpi parameter-add SOURCE :VOLTage? channel --type nr1 --optional

各子命令能力一览(实现见 scpi.py):

子命令 作用与校验
scpi subsystem-list / scpi subsystem-add NAME [-d DESC] 列出/新增子系统,重名会直接报 ValueError
scpi command-list [-s SUBSYS] 列出命令并计算 query(名字以 ? 结尾)、参数个数、响应类型
scpi command-add SUBSYS NAME [-d] [--response-type] 新增命令;命令名以 ? 结尾时自动判定为查询并生成 response.type(默认 quoted-string,可覆盖,如 nr3
scpi parameter-add SUBSYS COMMAND NAME [--type] [--optional] 为命令追加参数;--type 默认 nr1--optional 写入 isOptional

查询命令的"响应"设计比较值得注意:command-add :VOLTage? 后,工具的 list 输出里该命令的 query 字段为 true,说明工具明确理解了 ? 后缀在 SCPI 协议中代表查询请求的语义,并据此自动配置响应类型结构。

六、后端桥接:真实 EEZ Studio 的解析与模拟器构建

当需要让 EEZ Studio 亲自处理工程(而不是让 Python 模拟导出)时,使用后端命令:

cli-anything-eez-studio --json backend status
cli-anything-eez-studio --json --project panel.eez-project lvgl backend-inspect
cli-anything-eez-studio --json --project panel.eez-project lvgl simulator-build build/sim

6.1 backend status:探测后端可用性

backend status 会按以下逻辑探测(源码 eez_studio_backend.py):优先用命令行的 --source,其次读 EEZ_STUDIO_SOURCE,找到 package.jsonname == "eezstudio" 的目录后,再检查 build/project-editor/lvgl/docker-build/docker-build-lib.js 是否存在。返回的 JSON 包含 available、源码路径、EEZ Studio version、node 路径、docker-build-lib 是否就位等探测信息。后端不可用时返回 {"available": false, "error": ...}(不会让整条命令崩溃),而真正的后端操作命令则会抛错。

6.2 backend-inspect:借上游库解析工程

lvgl backend-inspect 会写一个临时 Node runner,调用 EEZ Studio 构建产物中的 docker-build-lib.jsreadProjectFile() 来解析工程元数据,把 { ok, projectInfo, logs } JSON 返回给调用方(源码 eez_studio_backend.py)。如果源码树在但未构建(缺 docker-build-lib.js),命令会提示先执行 npm run build——这正是 Skill 中"backend 命令缺失时应大声失败"的具体体现。

6.3 simulator-build:完整的 LVGL 模拟器 Docker 构建

lvgl simulator-build OUTPUT_DIR 是能力最重的命令。它以 docker-build-lib.js 为底座,串起"解析工程 → 检查 Docker → 准备工程 → 构建 → 提取产物"全流程,并额外校验关键工件非空。可用参数:

选项 默认值 说明
--repository-name eez-framework 传给 EEZ Docker 构建的仓库名
--docker-volume eez-studio-cli-anything Docker 卷名
--timeout 900(秒) 子进程超时
--source / --path 各自回退到环境变量/当前打开工程 后端源码树与工程路径

命令结束后 CLI 会立刻对输出目录执行产物校验(verify_simulator_output):要求 index.htmlindex.jsindex.wasm 三个文件都存在且非空,其中 index.html 头 32 字节需含 <!DOCTYPE html/<htmlindex.wasm 前 4 字节必须是 WebAssembly 魔数 \x00asm。这套"结构 + 魔数"的双重校验也可单独通过 lvgl verify-simulator OUTPUT_DIR 触发,非常适合作为 CI 的收尾断言。

6.4 build-files 与自定义构建命令

cli-anything-eez-studio --json --project panel.eez-project lvgl build-files

lvgl build-files 走的是 EEZ_STUDIO_BUILD_COMMAND 通道:它把环境变量中的命令以 shell 分词后执行,并把工程绝对路径作为最后一个参数追加。需要说明的是,这一命令面向"未来 EEZ Studio 发布公开 headless 代码生成命令"或"本地打过补丁的构建"这类场景;当下没有配置该变量时它会明确报错并指引改用 lvgl simulator-build。正如 EEZ_STUDIO.md 所强调的:"harness 不会在 Python 里自行合成 EEZ 的导出结果"——这是刻意保持的边界。

七、会话管理:undo / redo 与自动保存

Skill 建议在 REPL 或脚本会话中使用会话命令做状态控制:

cli-anything-eez-studio --json session status
cli-anything-eez-studio --json session undo
cli-anything-eez-studio --json session redo

会话语义的完整实现位于 session.py。值得展开的机制点:

  • checkpoint 快照:每个会修改工程的命令(add-page、add-label、add-button、set、SCPI 系列等)在动手前都会调用 session.checkpoint(),把当前工程做一次 deepcopy 压入撤销栈;每次新变更都会清空重做栈。
  • 深度上限:撤销栈上限 MAX_UNDO_DEPTH = 50,超出时从栈底丢弃最旧快照。
  • 自动保存触发链--project 一次性命令在进程退出(call_on_close)时若工程 is_modified 为真则写盘;REPL 模式与 --dry-run 会绕过自动保存,REPL 退出前若仍有未保存修改会给出提示。
  • 跨会话持久化session save-state 把会话状态 JSON 写到 ~/.eez-studio-cli/sessions/<session_id>.json(Linux 下即 $HOME/.eez-studio-cli/sessions),session list 按时间戳倒序列出这些状态文件;默认 session_idsession_<unix时间戳>,也可用顶层 --session 显式指定。

八、REPL 交互模式

不带任何子命令直接运行即可进入 REPL:

cli-anything-eez-studio --project panel.eez-project

REPL 由 prompt-toolkit 驱动(repl_skin.py),交互时它会为当前行自动注入 --project--json 前缀,让用户输入 lvgl add-label --text Hello 即可操作当前工程;内置 help 列出各命令速查、quit/exit 退出。REPL 内若发生业务错误不会终止会话,而是打印错误后回到提示符,适合人工/Agent 半交互式探索工程。

九、错误输出契约与调试

无论一次性命令还是 REPL,CLI 都用统一的错误契约(handle_error 装饰器 + _emit_error):--json 模式下错误被序列化为

{"error": "<消息>", "type": "RuntimeError|FileNotFoundError|ValueError|..."}

并写入 stderr;非 JSON 模式输出 Error: ...。一次性命令模式下业务异常会以退出码 1 结束,便于脚本捕获。这让 Agent 可以精确区分"后端未安装""页面不存在""参数不合法""文件已存在"等失败类型并给出相应处置。

十、测试与验证方法

仓库自带两层测试来保障上述行为(测试入口见 tests/EEZ_STUDIO.md):

cd eez-studio/agent-harness
python3 -m pytest cli_anything/eez_studio/tests/test_core.py -v
python3 -m pytest cli_anything/eez_studio/tests/test_full_e2e.py -v
  • test_core.py(纯单元,无后端依赖):覆盖"工程包含原生 section、save/load 往返、set general/destination、页面控件增查、SCPI 三级结构、session undo/redo 数量精确性、CLI --json project new 输出可解析"等断言,还验证了默认 LVGL 版本、默认 src/ui 目录与根组件类型(LVGLScreenWidget)。
  • test_full_e2e.py(默认免后端):验证 backend status 探测以及"后端不可用"的结构化错误路径。只有设置了 EEZ_STUDIO_RUN_LIVE_BACKEND=1 且提供已构建的 EEZ_STUDIO_SOURCE 时,才会真正跑 backend-inspect 类的在线用例。

这种"默认离线可测、在线深度用例显式开关"的测试设计,使得该 harness 可以在完全没有 EEZ Studio 的环境里做回归,同时保留了对真实后端的契约测试通道。

结语

project new 生成带模板标记的原生工程,到 lvgl add-button 拼接控件树,再到 scpi command-add 维护仪器指令、simulator-build 借真实 EEZ Docker 后端产出 index.html/index.js/index.wasmcli-anything-eez-studio 提供的是一条从"纯 JSON 编辑"到"真实工具链构建"的完整自动化链路。其核心方法论可以归纳为三点:一是直接编辑原生格式而非造自己的中间格式,保证与 EEZ Studio 的互操作性;二是统一 --json 输出 + 结构化错误,让 Agent 每次调用都有确定性的可解析结果;三是后端缺失即大声失败并给出修复指引,把环境依赖问题转化为明确的行动项。掌握这些模式后,你可以把它嵌入 LVGL 原型生成、测试仪器前面板搭建、CI 模拟器构建流水线等各类自动化场景。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525