crossmux
v0.1.0
Published
MuxOS device development CLI
Readme
muxos CLI
当前发行准备版本为[email protected],安装命令npm install -g crossmux、可执行命令muxos保持。
Registry按GitHub数字ID限制每环境UTC+8每天20次新上传授权、滚动60秒5次、一个有效上传会话;失败/中断/过期也计数。换登录/token/worktree不重置。429会显示额度重置或等待原因;收到上传编号后使用原包和publish --resume-upload <id>确认,不自动重建授权或再次PUT。实际新传输失败后重新发布会占用新额度。
muxos 提供开发环境诊断、离线资源转换、Lua 应用打包、公开包仓库管理及浏览器开发模拟器。
安装
npm install --global crossmux包名为 crossmux,可执行命令为 muxos。需要 Node.js 22 或更高版本。
图片依赖固定为 [email protected];常见平台随 npm 安装预编译二进制,需允许安装
optional dependencies。安装完成后转换离线运行,无需 Python、ESP-IDF 或工程目录。
特殊平台的依赖要求见 sharp 安装说明。
浏览器开发需已有桌面浏览器。Windows/macOS/Linux支持x64、arm64;Linux分glibc与musl。
npm自动安装当前平台的sharp/libvips,模拟器Wasm、字体与原生网络组件随CLI包提供;
用户无需Python、ESP-IDF、Emscripten或编译器,也无需先执行面向固件工作区的doctor。
安装需要联网;安装后图片转换和本地应用预览可离线使用。
当前0.1.0为未发布的本地候选版本;npm已发布的0.0.1不包含dev。
本地候选仅实测macOS arm64,使用生成的安装包:
npm install -g /absolute/path/crossmux-0.1.0.tgz
muxos --version
cd /absolute/path/to/application
muxos dev升级可再次安装候选包,应用私有数据保留。本地单平台包不等同完整发布包; 遇到缺失/损坏组件时重新安装对应候选包,避免用线上旧版本替代。
使用
muxos --help
muxos --version
muxos doctor
muxos assets --help
muxos dev --helpmuxos doctor 从当前目录向上查找 MuxOS 工作区,检查 idf.py,并验证
firmware/boards 下每块开发板的核心定义文件。检查通过返回 0,环境不完整
返回 1;无效命令返回 2。
应用打包
muxos pack [directory] [--output file.mpk]
# 未安装可直接调用仓库入口,无需 ESP-IDF 或图片转换依赖
node cli/src/muxos.js pack apps/pomodoro --output /tmp/pomodoro.mpk源目录必须自带符合 manifest schema的
manifest.json 和 MuxOS Lua API 的 Lua 文本入口(api: 1)。唯一身份为 name: @scope/name,展示名为 display_name,版本使用严格 SemVer;不再接受 id 和 version_code。
必填 files 白名单选择相对文件或目录,目录递归、重叠去重,不支持 glob;manifest 隐式入包,入口必须入选,未选文件不进入包。
按 MPK1校验路径、入口、硬件授权和资源预算:
≤128 文件、单文件≤256 KiB、总文件数据≤1 MiB、manifest≤16 KiB、压缩包≤1 MiB。
拒绝符号链接、特殊文件、非 UTF-8/越界路径、无法表示为 POSIX ustar 的路径;
输出为小写 .mpk,不能覆盖 manifest/选中文件或进入选中目录;允许位于源目录的未选 build/。
输入默认当前目录,默认输出为当前工作目录中的 <scope>-<name>-<version>.mpk。私有配额为 1–16384 KiB。
manifest 首条,其余按 UTF-8 字节排序,固定归档元数据和 zlib level 9。 同输入、同 Node/zlib 工具链得到相同字节;先完成校验与压缩,再原子替换输出, 失败保留旧包。成功打印文件数、包字节数、SHA-256;参数错误 exit 2,处理失败 exit 1。 打包仅使用 Node.js 标准库,未实现设备安装、发现或市场。 番茄构建工具使用 manifest 的运行文件白名单,设计和工具不入包。
muxos pack --encrypt <key-file> 返回 feature_unavailable,不读取密钥、不生成或覆盖输出。旧 muxos app ... 命令直接拒绝。
浏览器开发
muxos dev # 当前应用目录,自动打开浏览器
muxos dev apps/pomodoro --no-open
muxos dev . --port 8080 --no-watch真实 Lua、LVGL、字体和应用绘制在浏览器 WebAssembly Worker 运行,Canvas 显示 684×1216 的实际像素;触摸、鼠标及方向键可调试输入。工具显示日志、源码与行号、 错误堆栈,提供停止和重新启动。保存 manifest 或白名单内文件后,200ms 防抖并 完整重启;校验失败保留运行中的应用。仅接受应用目录,沿用 pack 的全部输入校验, 不会生成开发包或修改源文件。已有应用版本约定保持不变。
默认只绑定 127.0.0.1 的随机端口,打印带会话凭据的地址,一个会话允许一个
活动浏览器客户端;关闭或强退浏览器会释放网络及未提交事务,后台暂停轮询不会被另一客户端抢占。HTTP/HTTPS、TCP 和 UDP 由 CLI 转发;TLS 使用 Node 的公共 CA,
无法准确实现的底层选项返回 not_supported。HTTP 超时沿用网络等待语义,连续
有进展的传输可超过一次等待时限。浏览器可跨域访问的目标以 CLI 网络能力为准。
通过 SSH 连接开发主机时,将打印的远端端口转发到本机,并在本机浏览器使用
http://localhost:<本机端口>/#<会话凭据>;本机与远端端口可以不同。
仅接受 localhost、127.0.0.1 或 [::1] 的 Host,API 的 Origin 必须匹配浏览器
实际访问的 HTTP 地址,并携带会话凭据;不信任 X-Forwarded-* 请求头。
私有数据由 CLI 事务保存到系统应用数据目录的 crossmux/simulator/<摘要>/;
摘要包含规范项目路径及应用名,版本和监听端口不参与身份。成功返回前确认
持久化,失败保留旧数据;重启浏览器或 CLI 可复用数据,同一项目数据不能被两个
CLI 同时修改。提交回复丢失会用同一请求重试;仍无法确认时立即停止应用,重新启动读取最近持久提交。移动项目目录或改变应用名产生新的隔离数据。
发布包内包含前端、Wasm、字体、原生网络组件和许可证;开发者无需 SDK 或编译器。 从源码直接运行时须先由维护者构建制品,制品缺失 或平台不兼容会明确报错,启动时不自动下载工具。当前验收状态见 030 验证记录;全部平台及浏览器 验收完成前不发布正式制品。模拟器不包含设备完整系统、微信读书原生阅读 SDK、 真实硬件、加密包或断点调试,不能用来推断设备资源或性能。
公开包仓库
muxos login
muxos whoami
muxos publish # 默认当前目录,不写入额外包文件
muxos publish ./timer.mpk # 验证并发布原始包字节
muxos publish ./timer.mpk --resume-upload <upload-id> # 查询并确认原上传,不再 PUT
muxos search timer
muxos view @example/timer
muxos unpublish @example/[email protected]
muxos logout仓库默认来源为 https://registry.crossmux.com;可用 MUXOS_REGISTRY_ORIGIN 或
--registry https-origin 覆盖,flag 优先。origin 必须为 HTTPS,不含路径、账号、
query 或 fragment。此默认值不代表服务已上线,部署状态以服务端验证记录为准。
login 打印浏览器登录链接并轮询票据;打开链接完成 GitHub 登录及个人 scope
选择。CLI 不接收 GitHub token。Ctrl+C 取消并尝试删除票据;过期、重复领取或
领取响应丢失不会建立本地登录,后者需重新登录。仓库凭据默认保存在
~/.config/muxos/credentials.json,按 origin 隔离,目录权限 0700、文件 0600,
可用 MUXOS_CONFIG_DIR 指定配置目录。logout 确认远端撤销成功后才清本地凭据;
失败保留凭据便于重试。证书失败、API 重定向和超限响应会拒绝处理。
publish 目录复用离线 pack 的白名单、manifest 与资源检查;已有 .mpk 重新
验证压缩流、ustar、路径、成员与入口,源包保持不变。服务独立重验后提交不可变
版本;成功输出明确为 published,候选接收或处理中不算成功。finalize 响应丢失
时只查询同一 upload ID 或重试其幂等 finalize。收到编号即打印恢复用法;中断后用
publish <同一目录或包> --resume-upload <id>,先核对原包名、版本、大小和 SHA-256,
再查询或确认原操作,不创建上传、不再次 PUT、不延长授权。声明不符时停止,已发布
状态验证后返回,原失败或未受理已过期会明确报错。未完成 PUT 的上传不承诺恢复。
Ctrl+C 只取消本地等待,服务端结果可能已提交,应使用编号确认结果。
同版本同摘要重试返回已有结果,不同内容或仅 build metadata 不同的同优先级版本
冲突。包仍为普通 MPK1,未验签;未知格式和 029 加密包拒绝,不执行 Lua。
search [query] 和 view @scope/name 无需登录。每次仅取一页,最多 16 项,
search可用--category reading|tools|life与--limit 1..16筛选;搜索结果输出
previous_cursor与next_cursor,把任一非空值传给--cursor前后翻页。分类省略即全部。
搜索匹配最新可安装正式版的包名、展示名、用途与发布者;旧版本资料不会使包误命中。
view历史仍只输出next_cursor。目录修订变化
返回 revision_changed 时从第一页重新查询。历史保留撤回状态,latest 仅指最高
未撤回正式版本,预发布需精确选择。unpublish 必须在交互终端输入完整 selector
确认;没有自动确认参数。撤回保留版本占用且停止签发新下载 URL,已经签发的短期
URL 和本地副本不被即时删除。
接口、版本选择和错误码见包仓库契约。 manifest可选summary/category/description/release_notes随包校验和发布,UTF-8字节预算见包格式。CLI不提供设备管理连接;设备商店沿同一匿名查询与解析接口工作。
图标
准备 icons.json,源路径相对清单文件:
{"icons":[{"name":"book","path":"./book.svg"},{"name":"settings","path":"./settings.svg"}]}muxos assets icons --manifest icons.json --sizes 24,32,40,48 \
--format lvgl --output generated/icons --preview--format lvgl|lua 和 --output 必填。默认尺寸为 24/32/40/48 px,等比居中;
--threshold 默认 110,可在 0–255 调整,白底亮度低于阈值的像素绘制为黑色。
名字只允许 ASCII 字母开头的字母、数字、下划线,最长 48 字符,不允许重复。
清单最多 128 项,一次最多 16 个不同尺寸;源 SVG 必须自包含、UTF-8 编码。
支持路径、形状、片段引用和内置渐变,不加载外部图片、样式或字体。
图片
muxos assets image cover.jpg --width 684 --height 1216 \
--levels 16 --dither floyd-steinberg \
--format lua --output generated/cover --preview支持 PNG、JPEG、SVG;应用 EXIF 方向,使用 Lanczos3 等比缩放,居中留白。
未指定宽高时保持原尺寸;仅指定一边时按比例计算另一边。
--levels 为 2/4/16,默认 16;--dither 为 none/floyd-steinberg,默认后者。
灰阶是资源的目标级数,需按设备实际显示能力选择,不代表面板新增灰阶支持。
透明区域和留白合成到 --background 0..15(默认白色 15)。
--name 默认 image,用于生成资源名字;--preview 输出最终量化效果的 PNG。
单个源文件最多 32 MiB,解码与输出最多 1600 万像素、每边最多 65535 px; 单色图标尺寸最大 4000 px。动画、多页、损坏或超限输入报错。
生成结果
不同尺寸图片可一次生成同一份索引:
{"images":[{"name":"brand","path":"./brand.png","width":320},{"name":"next","path":"./next.png","width":56}]}muxos assets images --manifest images.json --levels 16 --dither none \
--format lua --output generated/assets路径相对清单,每项可选 width/height;灰阶、抖动、背景为整批选项。 每批 1–128 项,索引和所有分块合并计算输出预算;重名或转换失败不发布任何结果。
- LVGL:输出
assets.c/assets.h;图标默认使用透明 A1 掩码,--alpha-bits 4可生成带16级透明覆盖率的A4图标;此选项仅用于LVGL。图标同时输出mux_asset_<name>_<size>_center_y视觉中心,图片使用 I1/I2/I4 灰度调色板。 按 C17 编译.c,C++20 可引用头文件。lv_image_set_src使用&mux_asset_<name>_<size>(图标)或&mux_asset_<name>(图片)。 - Lua:输出
assets.lua和原始四位灰度.bin,通过require("icons.assets")加载索引。模块根据 require 名字确定包内相对路径, 可把整个输出目录复制到应用包中;路径的每段应为合法 Lua 模块名。 图标前景黑色,背景在转换时合成,不能像 LVGL 掩码一样透出底图。 - Lua 大图按完整行分为最多 64 KiB 的块;先完成整图抖动再拆块。
逐块
mux.app.read_resource/mux.display.bitmap,释放已绘制的数据,最后刷新。 不需要设备解码器或整幅图片的 Lua 字符串。
LVGL 软件解码会将索引图片展开为约 width*height*4 字节,A1/A4 图标展开为约
width*height 字节,另有解码器及对齐开销;CLI 会打印这个估算。
全屏图片应核算 LVGL 内存预算,不能把四位资源大小当作运行时开销。
下面的 LVGL 示例使用 128×128 图片;Lua 示例使用分块的 684×1216 图片。
Lua 输出检查本次生成资源的 128 文件、单文件 256 KiB、总量 1 MiB 上限, 并报告余量。预览 PNG 也计入本次输出统计,通常不必随应用分发。 这不替代应用包校验:应用代码、以前生成的其它资源、目录前缀仍需计入总量与 127 字节/16 层的包路径限制。LVGL 批次文本输出上限 64 MiB。
默认不覆盖已有文件;--force 替换同名普通文件,不删除以前生成的旧尺寸。
输出不能覆盖输入,不能经过符号链接。完整批次转换和检查成功后才逐文件原子发布,
转换失败保留旧文件;发布阶段的磁盘故障可能留下部分新结果,可修复后重新生成。
完整格式与共享向量见 contracts/assets-v1。
接入示例
仓库根目录执行(已安装 CLI 时);未安装可用 node cli/src/muxos.js 代替 muxos。
示例也随 npm 包包含在 examples/assets/,没有依赖外部图标库。
# Lua:生成一个独立示例应用目录
muxos assets icons --manifest cli/examples/assets/icons.json --sizes 24 \
--format lua --output /tmp/muxos-assets-demo/icons
muxos assets image cli/examples/assets/picture.svg --width 684 --height 1216 \
--format lua --output /tmp/muxos-assets-demo/pictures
cp cli/examples/assets/main.lua /tmp/muxos-assets-demo/main.lua把该目录内容复制到模拟器或设备的 sdcard/.muxos/dev/ 开发槽位,再从应用入口
启动;模拟器用 touch-684 配置查看全尺寸。其它屏幕按 mux.display.info() 返回的
逻辑尺寸生成图片,示例自身不在运行时缩放。
# 固件:生成标准 LVGL 静态资源
muxos assets icons --manifest cli/examples/assets/icons.json --sizes 24 \
--format lvgl --output /tmp/muxos-lvgl-demo/icons
muxos assets image cli/examples/assets/picture.svg --width 128 --height 128 \
--format lvgl --output /tmp/muxos-lvgl-demo/pictures把两个 assets.c 与 examples/assets/lvgl_example.c 加到使用方的编译源,
把输出根目录加到 include 路径,调用 mux_assets_example(parent)。
资源不会自动链接进系统页面;普通固件构建不调用转换器。
开发
cd cli
npm ci
npm test
npm pack --dry-run
# Linux:先按 firmware/README.md 构建模拟器,再检查真实资源消费者
npm run test:consumers
# 非默认模拟器构建路径也可显式指定
npm run test:consumers -- /absolute/path/to/simulator-build基础 CLI 使用 Node.js 原生 ESM 和标准库,assets 命令懒加载 sharp。
消费者检查复用模拟器的 LVGL 配置及 32 位 Lua 库,编译生成 C17 资源和 C++20
消费者,验证 A1/A4/I1/I2/I4 实际绘制、生产 Raster 解码以及完整 Lua 示例,输出 PNG
证据。它用本地 I/O 回调提供示例宿主,生产 Lua 沙箱与原始显示绑定另由现有模拟器
simulator_lua_raw_touch-480 / simulator_lua_raw_touch-684 检查覆盖。
本包当前为
UNLICENSED,未授予复制、修改或再分发许可。
