最早听笑来老师的课,知道他在写一款叫 VMark 的 Markdown 编辑器。当时看了看,觉得还有不少问题,就继续用着 MarkText。最近又看到笑来老师发的《我为什么制作了一个 Markdown 编辑器 VMark?》 ,正好自己这段时间一直在用 IDEA 的 cc-gui 插件配合 Claude Code 做 Vibe Coding。我发现,自己平时更多是在编辑 Markdown、在 AI 会话里聊天,可 IDEA 侧重的毕竟是源码编辑,一旦切到分栏或预览模式,渲染效果就很差,体验不好;而 cc-gui 虽然提供了多标签,方便多任务,却经常卡死,逼得我不得不重启 IDEA。于是,自己动手写一款 Markdown 编辑器的念头,就慢慢成形了。我已经写了自己的 SSH 客户端管理工具 vshell,那么再定制一款自己的 Markdown 编辑器,似乎也不是不可以。
前面说过,我平时最常用的 Markdown 编辑器是开源的 MarkText(虽然也买了 Typora)。又因为我是程序员,深知 Git 的重要性,而自己最常用的编程工具 IDEA,它的 Git 集成做得相当好。把这些凑到一起,就有了 GMark —— 一个 AI 驱动的创作编辑器。它的核心理念是:
人用 Markdown 下达指令(工作区),AI 生成内容(制品区),人审核确认,Git 全程记录。
简单说,GMark = Git + Markdown + AI,这也是它叫 GMark 的由来 —— 名字也参考了 VMark。

GMark 的另一个核心理念,是工作区与制品区的分离:用两个目录(两个 Git 仓库)。一个是工作区目录,里面是各种 Markdown 文件,还包含 AI 引擎相关的文件,比如 Claude Code 的 .claude、CLAUDE.md 等;另一个是制品区目录,用来放生成的代码、图片、文件等等。这样做最大的好处,是不用再纠结哪些文件该进 Git、哪些不该进 Git —— 比如苹果官方 App 误打 CLAUDE.md 上新闻那种事,就不会发生。
GMark 支持多个 AI 引擎,一个是 Claude Code,一个是 SolonCode。其实 AI 给我规划方案的时候,还顺带配了 Codex 的适配,但我想着自己完全没用过 Codex,适配反而给自己增加难度,就取消了。如果你听过笑来老师的课,他把「人审核」这一步也交给 AI 了 —— 这或许会是 GMark 下一步的方向。笑来老师用的是自己写的 cc-suite 插件,而我得想办法让两个 AI 引擎能彼此沟通起来。
GMark 和 vshell 用的是同一套技术栈:Go + Wails3 + Vue3 + Naive UI;Markdown 编辑器核心用了 MarkText 的编辑器 Muya,源码编辑器用的是 Monaco,其他一些辅助选型是 AI 帮我挑的。GMark 目前没有开源计划:一来它本身是个很个性化的需求;二来它还有不少问题,只适合自己用。更重要的是 —— 如果你有心,我也已经把技术栈交代清楚了,你应该会想自己造一个,而不是用我的版本。随着 AI 让软件创建越来越容易,定制化的需求也会越来越多。但 AI 的本质是基于概率的,存在「抽卡」式的不确定性,所以需要沉淀 —— 而 GMark,只是我沉淀出来的一个版本。
VMark 是一个高度固执己见(Highly Opinionated)的东西 —— 事实上,我猜,以后所有 Vibe Coded Software/Services 都是高度固执己见的…… 这其实是没办法的事儿,因为一切 Vibe Coding 的过程自然而然地都是「不需要与人开会」的「生产过程」—— 只有我自己和另外一个绝不争辩的执行者。
我只是一个 Producer(制作人)。
另外,还有个「高度固执己见」自动带来的后果:VMark 就算开源了,也不能指望「社群贡献」。首先,这完全是为了让自己顺手才写的东西,很多功能对别人来说并无太大价值。最为关键的是,Markdown 编辑器不是什么科技前沿的东西,是个无数人实现过无数次的编辑器中的一个简单分子,所以,AI 可以帮助我们解决关于它的任何问题。
本来计划用 GMark 来改进 GMark,吃自己的狗粮,让 GMark 实现自举、自我迭代。无奈问题还是太多,而且自举的时候需要重启自己,要么就得维护多个版本来回切换,徒增麻烦,于是放弃了自我迭代。
最近看到两样东西。一个是小木老师的 TokUI —— 号称全球首个「For AI & 零依赖」的流式 UI 描述与渲染框架:后端用极简 DSL 描述组件,经 SSE 或 WebSocket 流式推送,前端增量解析,首个 Token 就开始渲染,让 AI 用极少的 Token 输出更灵活、更有表现力的 UI。GMark 的 AI 会话记录,就是用 TokUI 渲染的,用下来感觉不错。另一个是 Martin Fowler 的一篇文章,《DSLs Enable Reliable Use of LLMs》。如果 DSL 确实更可靠,那 TokUI 应该是个正确的发展方向;再加上之前也看过「HTML 比 Markdown 更好」的说法,所以 —— 为什么不用 DSL/UI 来当练手项目呢,也能继续吃自己的狗粮,迭代 GMark。
于是在 cnb.cool 上建了两个仓库,一个工作区,一个制品区。目前两个仓库都是公开的,有兴趣的同学可以拿去参考。不过,如果你想拿 TurboUI 用于生产,请谨慎:一来我还在实验阶段,内容变动会比较大;二来它没有经过验证,使用有风险。真要上生产,我还是推荐你用 TokUI,能获得更多支持。
1 | # 工作区仓库,设计 |
TurboUI 第一个版本的需求,其实非常粗暴。我当时应该是在动车上,用手机的 DeepSeek 网页端写的。别问我为什么用 Turbo、Stimulus —— 这只是个人喜好,我喜欢 37signals(Basecamp),而 Hotwire 的技术也确实先进。就像笑来老师新 AI 课里讲的,不过是搜索空间的不同。

当然,新学的招得用上 —— 多模型互搏,于是我把需求也发给了 ChatGLM。

经过它们几轮「互殴」,我选了 TurboDSL/TurboUI 这套名字,但整体方案用了 GLM 的。最终形成的文档,在 TurboUI-Design 的 design.md 里。然后 AI 照着文档一顿设计:architecture.md、sdk-architecture.md,还生成了 sdk-spec —— 也就是 TurboDSL 的契约。接着它自己把剩下的事也包圆了,顺手给我整了个小 demo,我一看,像那么回事。
不过,笑来老师不是说要 Grill yourself 么?于是我在让它 Grill 拷问自己的时候,它给我生成了 why-dsl-grill.md。
核心论点(贯穿全文):把「TurboUI 值得做」和「必须是一门方括号 DSL」拆开看。前者成立;后者的每一条理由都可用「受约束 HTML profile + server-resolve 桥 + 词表校验」等价达成,且保留 HTML 的语料红利。所以「为什么是方括号 DSL」这道题,design.md 目前答不及格。
它推荐用 HTML 的子集,而不是用方括号。后来它自己做了对比测试,只能说是不相上下,于是我就继续保留了方括号的形式,以保持和 TokUI 一致。
不过在逐步讨论的过程中,其实也补强了我的一些主张。比如,click 是一个 token,clk 看起来更短,却不一定是一个 token —— 人觉得更短,AI 分词的时候未必这么认为。不能一味用简写,要尽量用常见的单词,一方面能确定 token,另一方面能减少误解。
后面陆续让 AI 处理、生成 TODO,逐步核查和修改。碰到最多的问题,其实笑来老师的课里也讲过 —— 就是只处理一半问题,或者在处理过程中说「这个是旧问题,不是这次改动引入的」。没办法,还是没办法,得好好看看笑来老师提供的 Skills 了。

实现的过程中,还得顺手修 GMark 的各种问题:工作区和制品区的限制问题、AI 提供的审核问题、Git 扫描 node_modules 导致 CPU 飙升卡顿、文件引擎的问题、AI 引擎切换时参数没完整切换导致接口异常、发布后路径无法识别、Claude Code 被判离线、Terminal 没识别到环境变量,等等。光是自己在使用时就登记下来的问题,就有 80 多个。总而言之,这狗粮,是真难吃。

不过看着 TurboUI 相对干净的工作区和制品区,感觉还是挺好的。

最后,我让 AI 看 TokUI 的演示站点,给我重新生成一个更完整的 Demo,效果也还不错 —— 它直观地展示了 DSL 相比 HTML 节省的 Token 数,效果满意。
1 | # 获取代码后执行 |
