Skip to content

About

MoUI Studio — block / code co-source visual programming environment built on the MoUI framework (MoonBit). 中英双语积木与代码同源可视化编程环境,AI 只产出可预览、可 diff、可拒绝的结构化提案。

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

MoUI Studio — 用人话描述,用母语编程,用积木理解

English

MoUI Studio 是一个中英双语的可视化编程环境:同一份程序有三种同源视图—— 易语言式的窗体设计器、Scratch 式的积木编排、中英双关键字的 代码编辑器。自然语言交给 AI,但它只能产出结构化提案(可预览、 可 diff、可拒绝),结构上不存在"生成任意代码直接运行"的路径。产物可以 一键导出为独立 MoUI 应用(Web / macOS 双端)。

五分钟上手(Web,零安装)

git clone https://github.com/wzzc-dev/moui_studio.git
cd moui_studio
moon build web_wasm --target wasm-gc
# ES module 不能用 file:// 打开,需要起一个静态服务:
python3 -m http.server 8766 --directory web_wasm
# 浏览器打开 http://127.0.0.1:8766 即见 IDE

web_wasm/index.html 会自己探测 _build/ 下的 wasm 产物,debug 与 --release 两种 profile 都能直接用。

macOS 原生入口:moon run macos_skia --target native

界面地图(v4 IDE 壳)

┌─ 无边框顶带(仅 native 沉浸式)────────────────────────────────┐
│ [系统信号灯] 按住此条拖动窗口                                   │
├─ 顶栏 ─────────────────────────────────────────────────────────┤
│ 运行 · 单步 · 编译 MoonBit   撤销/重做 · 语言 · 搜索 · 设置    │
├────┬──────────┬────────────────────────────┬──────────────────┤
│图标│ 左栏     │ 中心工作区                 │ 右栏             │
│栏  │ 程序结构 │  实时应用 │ 设计态         │ 属性/状态/数据/  │
│    │ 本地数据 │  ────────────────────────  │ 动作/依赖        │
│    │ ──────── │  积木(分类 · 选中描边)   │ ──────────────── │
│    │ 最近修改 │  ────────────────────────  │ 编辑积木(选中时)│
│    │          │  代码(行号 ┼ IR 映射竖条) │ 快速操作         │
│    │          │                            │ 运行时监视       │
├────┴──────────┴────────────────────────────┴──────────────────┤
│ 运行审计 │ Console                            warn 0 · err 0  │
└───────────────────────────────────────────────────────────────┘
  • 切语言:顶栏 English / 中文(代码与界面一起切换:如果…则…结束 ↔ if…then…end)
  • 换模板:空舞台按钮(问候 / 点名册 / 空白程序)或 ⌘K 命令面板 (四模板 + 新建空白程序 + 打开/保存/导出)——教案里的口算训练营、 班级小卖部从命令面板可达
  • 工作区:图标栏切换可视化 / 代码 / 空舞台;再点当前项收起成空舞台
  • 积木视图:画布左侧是竖排分类轨(色点 + 名称,选中项带强调边)——分类 不占画布纵向空间;画布支持同层拖拽重排;窗格脚注说明画布底部是为 AI 层 预留的避让通道;长语句按块宽以省略号收尾。 语句在右栏改(IDEA 式「选中在画布、编辑在检查器」):选中一块积木后 右栏顶部出现「编辑积木」卡(种类徽章 + 语句输入 + 应用/复制/删除), 链条永远是一条连续的链——不再因选中被切成三段。旧版把编辑卡嵌在链条 中间,块一多上下两段就只剩几行,读到的现象是「点积木后内容显示不全」
  • 代码视图:左侧行号 + 代码,右侧 IR 映射竖条;悬停代码行或色块即 双向高亮对应路径(离开还原,与点击的驻留高亮互不干扰)(按行号对齐的分类色块, 点一下高亮对应积木;与「点代码行高亮积木」是同一状态的两个入口)
  • 左栏:程序结构树(可搜索、可折叠)、本地数据(从 IR 派生的文件名/表头预览)、 最近修改(区分「你」与「Agent」)
    • 创建入口在各分组头的 +(不是面板底部的全局按钮块):窗体 / 控件 / 变量 / 事件子程序 四组有 +,点开是内联菜单;本地数据没有——它的 条目从列表/表格控件的行派生,没有独立创建语义,所以不给一个点了没用的 按钮。创建入口贴着它创建的东西,与右栏「动作」页签建子程序、积木分类轨 建语句是同一范式
    • 控件组的菜单与 ControlKind 枚举等长:按钮 / 标签 / 输入框 / 选择框 / 列表框 / 表格 / 下拉框 / 进度条 / 图片。变量此前没有任何新建入口(只来自 AI 提案或手打代码), 现在变量组有「+ 新建变量」,改名会同步改写所有引用它的语句
    • 树上的每一类行都可点选:窗体 → 窗体属性(标题可改)、控件 → 控件属性、 事件子程序 → 代码/积木、变量 → 变量属性(改名/初值/删除)、数据条目 → 只读来源与内容预览。选中是单选:点一处会清掉其他两条槽 (控件 / 子程序 / 非控件对象),右栏永远只显示当前那一个对象的属性
  • 沉浸式(native):macos_skia 入口开 transparent_titlebar —— 系统标题栏透明、 内容延伸到窗口顶端;系统信号灯照常可用(关闭/最小化/缩放都是真的,app 不 重画它们),app 只让出左侧 78pt 并把这条顶带登记为拖拽区。Web 恒关闭
  • 右栏:属性/状态/数据/动作/依赖五个页签;选中积木时页签体顶部是编辑积木卡 (见上);快速操作是设计稿口径的单选控件对齐 (左 x=24、居中 x=(640-w)/2、右 x=640-w-24)+ 复制 + 删除 + AI 优化; 运行时监视列出被监视变量(未运行时显示空态)
  • 底栏:运行审计时间线(编译 / 启动 / 副作用 / 错误,副作用卡就地确认) 与 Console 原始日志两页签;点审计条目可跳到对应积木
  • 命令面板:⌘K 过滤 Studio 命令(每条都是既有消息的封装,不引入新状态通道)
  • AI 浮动层:默认居中贴底,可切左/右/停靠右栏,可收成药丸; 浮动时自动让出避让带,不会压住窗格内容
  • AI 会话线程:每次生成提案推一张 diff 线程卡(事件驱动,不是摆设), 折叠条显示「Agent 待审计 N」,采纳/拒绝后卡片标记已应用/已拒绝; 线程超过 3 条给「查看全部会话 →」直达 AI 历史;收成药丸后药丸本身显示 Agent 待审计 N——收起状态下这是唯一的待办读数
  • AI 输入条工具行:锚点读数(底部居中 / 左下角 / 右下角 / 停靠 · Context 侧栏)
    • 切换锚点 / 停靠右栏 / 收起三个带名字的按钮(停靠态自动改显「浮出」)
  • AI 输入条:模式段 修改 / 生成 / 解释 / 修复 决定「发送」走哪条既有通道 (解释=本地确定性讲解、修复=草稿回到 IR 规范渲染、生成=清空后走同一条提案 校验链、修改=直接提案)——模式只改入口路由,不新增执行路径;右侧是发送
  • 空舞台(三个工作区都收起)时输入框升格为 hero:加宽居中偏上,并列出三条 示例指令;点击示例只把文字填进输入框,按不按发送由你决定
  • 运行:点「运行」,按钮真的能点;提交数据 会让程序停下等你确认。 运行页里的舞台控件逐个事件真的会重新执行:随机数 每次给出新值 (种子跨事件连续推进),所以连点同一个按钮每次都能看到不同结果—— 两轨(解释/真编译)从同一个种子起算,逐位可比
  • 停止:点「停止」回到可视化工作区继续编辑(不是停在空白运行页)
  • 真编译:点「编译 MoonBit」在 TMPDIR/moui_studio-compile/<app> 里真跑 moon update / check / build,七步进度逐格可见(准备工作目录 → 解析依赖 → 类型检查 → 构建 Web 产物 → 构建 native 产物 → 启动产物自检 → 收集产物, 已完成点满、进行中高亮);产物是磁盘上的真实文件
  • 产物卡:native GUI 应用(可执行窗口程序)排在第一位,带 运行产物(一键开窗)/ 复制路径 / 在文件夹中打开 三个动作; 长路径做中间省略(保头保尾,文件名永远读得到)并给出真实字节数。 native_smoke 是无头启动自检(打印标记就退出,不开窗),单独标注, 不会被误当成要运行的应用
  • 「运行产物」是脱离式启动:进程 reparent 到系统 init,Studio 退出或 被关掉都不会带走正在用的导出应用(实测:杀掉 Studio 后窗口仍在)
  • 导出应用视口自适应:窗口按项目声明尺寸开,舞台在可用空间内等比缩放 (fit_scale,下限 0.4),所以任何窗口尺寸下设计稿都完整可见、不会被裁。 首屏是用户设计的表单 + 一行状态条,变量/消息/审计收进默认收起的 「变量与日志」面板(导出的是应用,不是调试台)

四个内置样例(各附教案)

样例 教什么 教案
问候小程序 三视图与运行闭环(最小起点) samples/hello/README.md
班级点名册 随机数、列表框取行 samples/roll_call/README.md
口算训练营 分支、变量、算术 samples/drill/README.md
班级小卖部 跨事件状态、外发闸门 samples/store/README.md

AI(真实模型)与新建工程

  • AI 恒走真实 OpenAI 兼容 provider:没有离线假模型。未配置密钥时 composer 下方给出接通引导(不弹假回复);endpoint/model/密钥在设置面板里热改。
  • 真实模型默认指向阶跃星辰(https://api.stepfun.com/step_plan/v1,step-5-preview)。
  • 凭据放在 gitignored 的 moui_studio/.config.json(可直接在 json 里换 key):
{ "provider": { "endpoint": "...", "model": "...", "api_key": "..." } }
  • Web 入口(浏览器)没有 HTTP 通道:AI 输入面显式降级为「需要 native 版本」 引导,不出假按钮。
  • 新建示例项目 = 落盘本地文件夹(空舞台按钮 / ⌘K 的模板与「新建」命令): 选一个空文件夹,Studio 写入 moon.mod + 可编译的 MoonBit 应用骨架 (内嵌领域内核,moon build 即过)+ .studio/program.json IR 快照。 关掉 Studio 再打开时激活该工程即可恢复程序,AI 可以继续在上面改 (比如「把按钮字号调大」——提案采纳后 handlers.mbt 与内嵌 IR 直接 写回工程文件夹)。

规范文档

包结构

  domain/ir/          程序 IR + 不变量 + 预算(零依赖)
  domain/studio_lang/  双语 DSL:关键字表/词法/解析/打印/指令机解释器
  domain/codec/       .studio.json 编解码 + 版本门
  domain/proposals/   AI 提案契约 + 校验链 + diff + 内置模板样例
  domain/blocks/      语句 → 积木规格表
  kernel/             插件内核:服务容器 / 事件总线 / 贡献点
  kernel/plugin_contract/  WASM 插件契约(清单 / 视图协议 / 宿主 API 面)
  chrome/             共享视觉原子(主题 + 尺寸常量 + ChipTone)
  plugins/blocks/     积木几何 + 绘制计划 + 洞/值命中(零 Model/Msg)
  plugins/project/    工程域:行模型 + ProjectState + ProjectMsg
  plugins/run/        预览数据层 + 运行态结构 + 预览视图贡献
  plugins/ai/         AI 会话切片 + 几何/视图贡献
  plugins/markdown/ plugins/terminal/
  services/export/    独立应用导出(内核快照 + bundle 生成)
  services/model_provider/  OpenAI 兼容协议(纯)
  services/provider_native/  native async worker + .config.json 读取
  services/plugin_runtime/   WASM 插件运行时(native,wasmoon 宿主 + 配额)
  services/plugin_runtime_web/  WASM 插件运行时(web,浏览器原生 wasm)
  app/                TEA shell + 组合根 + 壳级组装视图 + 中英 catalog
  web_wasm/  macos_skia/    薄组合根
  samples/plugin_fixture/    最小 WASM 插件(参考实现 + E2E 用)
  tools/sync_kernel/ tools/emit_bundle/

WASM 插件系统

Studio 可以加载运行时插件:第三方代码以 WebAssembly 形式被加载, 贡献命令、面板与界面。

  • 架构、清单格式、视图协议、宿主 API 白名单、安全边界: docs/plugin-system.md
  • ⚠️ 插件运行时不是安全边界(wasmoon 自述 experimental + insecure)。 只安装可信来源的插件。

最小验证循环

本仓库是独立模块(wzzc-dev/moui_studio),包路径不带 moui_studio/ 前缀——那是它作为 MoUI 主仓库 submodule 时的写法。

moon check --target native          # 0 错误 0 警告
moon fmt --check

# domain 是多个包(不是单包路径),一次传完
moon test domain/ir domain/studio_lang domain/codec domain/blocks \
  domain/proposals --target native
moon test kernel chrome plugins/ai plugins/markdown plugins/project \
  plugins/run plugins/terminal plugins/blocks --target native
moon test services/compiled_runtime services/diff services/compile_native \
  services/export --target native

moon test app --target native       # 474 个测试
moon test app --target wasm-gc

# WASM 插件系统:契约 + 运行时 + E2E(真实加载一个 .wasm 插件)
sh scripts/build_plugin.sh           # 先造 fixture 的 wasm 产物
moon test kernel/plugin_contract services/plugin_runtime --target native

# 导出内核漂移门:改了 domain 忘了同步 → 红
moon run tools/sync_kernel --target native -- --check

moon build web_wasm --target wasm-gc

tools/sync_kernel 的路径表按母仓库根书写(带 moui_studio/ 前缀), 但工具会按当前根自动解析:在本仓库根跑 moon run tools/sync_kernel, 在母仓库根跑 moon run moui_studio/tools/sync_kernel,两者等价。

上面这一套就是 .github/workflows/ci.yml 的全部内容——push / PR 自动跑, 单独 clone 本仓库也有回归网。不在本仓库 CI 里的两件事:i18n catalog 生成检查(生成器是母仓库的 tools/moui/generate_i18n_catalogs 工具,漂移由 母仓库 pr profile 把关)与真机 / 真 Skia 冒烟(路径触发,非每日门)。


MoUI Studio — describe in words, code in your language, understand with blocks

(中文说明见上。)

MoUI Studio is a bilingual visual programming IDE. One program, three same-source views: an E-language-style form designer, Scratch-style typed blocks, and a code editor whose keywords follow the UI language (如果…则…结束 ↔ if…then…end). AI may only produce structured proposals (previewable, diffable, rejectable) — there is no path from "generate arbitrary code" to "run it". Projects export to standalone MoUI apps (Web wasm-gc / macOS Skia).

Try it in five minutes (Web, zero install):

git clone https://github.com/wzzc-dev/moui_studio.git
cd moui_studio
moon build web_wasm --target wasm-gc
  • Switch language from the top bar (English / 中文); the DSL keywords switch with it.
  • New sample project = a real folder on disk: pick an empty folder from the empty stage or the ⌘K palette (all four samples plus a blank program). Studio writes moon.mod, a compiling MoonBit app skeleton (vendored domain kernel — moon build passes), and a .studio/program.json IR snapshot. Re-open later by activating the project; the AI can keep editing it (e.g. "make the button font bigger" — accepting the proposal rewrites handlers.mbt and the embedded IR right in that folder).
  • AI always uses a real OpenAI-compatible provider — there is no offline fake model. Without a key the composer shows a connect hint; Web has no HTTP channel, so its AI surface degrades to a "needs the native app" note.
  • Run: buttons really work, and submit_data pauses the program until you confirm — nothing is sent before you do.

macOS entry:

moon run macos_skia --target native

Provider configuration (default StepFun step-5-preview):

Credentials live only in the gitignored moui_studio/.config.json:

{ "provider": { "endpoint": "...", "model": "...", "api_key": "..." } }

Specs: DSL spec · IR & .studio.json schema.

About

MoUI Studio — block / code co-source visual programming environment built on the MoUI framework (MoonBit). 中英双语积木与代码同源可视化编程环境,AI 只产出可预览、可 diff、可拒绝的结构化提案。

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages