项目一多,终端标签就失控了:我用 Rust 写了个 macOS 启动工作台,还让 AI 能自己重启服务

自从开始用 AI 写代码,手上同时开着的项目就没少过。正经项目几个,再加上一堆随手起的原型,起了就懒得关。

代码是写得快了,但每天还是在一堆终端标签里来回切:这个起一下,那个停一下,后端到底在哪个 tab 里,5173 现在是谁占着......说实话挺烦的,注意力全被这些碎事打断了。

所以我写了个工具,叫 DevStart。原生 macOS 应用,刚开源,v1.0,MIT 协议。这篇聊聊它是干嘛的,为什么用 Rust + egui 写,哪些东西故意没做,以及我自己用得最多的 MCP 部分。

它干的事其实很朴素

选一个文件夹,DevStart 把里面的项目扫出来,顺带识别项目里本来就有的启动脚本和端口。Vue、UniApp、Next.js、Node、Python、Java、PHP 都能认,认不出端口的就显示 --,不瞎猜。扫描只读,不执行任何代码,也不往你仓库里写管理文件。

导进来以后就是一个列表。点一下启动,停止、重启也是点一下。一个项目可以配多个启动入口,比如正式和测试分开,各自独立启停。日志在 Console 里看,多标签,或者平铺着同时盯几个,能搜能过滤,ANSI 颜色也保留着。

另外塞了几个我自己天天要用的东西:基础的 Git 工作区(提交、推送、拉取合并、看历史和多标签 diff),每个项目一个交互终端,还有个简单的编辑器,带冲突检测和原子保存,每个启动入口保留最近 10 个版本,改坏了能回滚。

为什么是 Rust + egui

这类工具常驻后台,一开就是一整天,同时还挂着一堆子进程在疯狂往外吐日志。我不太想为了一个启动器再背一个浏览器内核,所以没走 Electron 或 WebView 那条路。现在 DevStart 本身不依赖 Node.js,也没有 WebView,打出来是一个 Universal 包,Intel 和 Apple Silicon 都能跑,macOS 12 以上。

几个具体的设计,也算是 Rust 写起来比较顺手的地方:

GUI 和本地 API 操作的是同一个 Service,界面只管展示和交互,配置、进程、文件版本都由后端校验和持久化。所以后面接 CLI、接 MCP,几乎是顺手的事,AI 调的和你点按钮走的是同一套逻辑。

进程生命周期检查放在后台跑,界面不会因为某个服务停得慢就卡住。停止时先请求优雅关闭,超时了才强制结束。还有一条我比较在意:端口被一个不知道归属的进程占着,它会直接报错,不会按端口盲目去杀进程。误杀别的服务可不是闹着玩的。

日志这块是有上限的。Console 用有界缓存加虚拟行渲染,落盘日志按单文件 10000 行 / 10MiB、全局 200MiB / 50 份 / 7 天来清理。一个话多的 dev server 跑一整天,也不至于把内存和磁盘吃光。

当然也有代价。egui 是 immediate mode,写起来快,但界面跟原生 Cocoa 应用比还是差点意思,这个我认了。进程和端口检测靠系统的 ps 和 lsof,有点糙,但够用。Linux 的图形和进程工具路径还没适配,Windows 的进程组管理压根没实现,所以暂时只推荐 Mac 用。

故意没做的事

DevStart 不管项目之间的依赖。没有启动顺序编排,没有就绪检查,也不做复杂的工作流。前端要连本地 API?你就先找到 API 项目点一下,再切回前端的 Console 接着干。

听起来有点简陋,但这是想清楚之后的选择。编排类需求已经有专门的工具了,我只想要一个日常开开关关够用的东西,操作越少越好。

还有一条:脚本属于原项目。DevStart 只引用项目里已有的文件、命令和参数,自己的启动定义存在它自己的数据目录里(默认在 ~/Library/Application Support/devstart),不往你的仓库里塞任何东西。配置、日志、编辑历史都留在本机。哪天不用了,删掉就完事,项目本身一点不受影响。

MCP:让 AI 自己重启服务、自己翻日志

我自己用得最多的反而是这块。

DevStart 对外有三种接法:本地 JSON-RPC API、CLI,还有一个走 stdio 的 MCP Server。接到 Cursor、Claude Code、Codex 这类工具上以后,AI 能列出项目、启动停止重启、查日志搜日志,还能编辑文件和回滚版本。

配置就这么几行,把路径换成你本地编译出来的二进制:

json 复制代码
{
  "mcpServers": {
    "dev-start": {
      "command": "/absolute/path/to/dev-start",
      "args": ["--mcp"]
    }
  }
}

需要先开着 GUI,或者用 --serve 不带界面跑同一个工作区。不想用 MCP 的话,命令行也能直接调:

bash 复制代码
cargo run --locked -- --serve
cargo run --locked -- --api api.describe
cargo run --locked -- --api projects.list

客户端接入时先调一下 api.describe,就知道当前版本有哪些能力,以运行中的二进制为准。日志查询是分页的,AI 读长日志也不会一口气全塞进上下文。

实际用下来,变化挺直接的:AI 改完代码,自己把服务重启了,再去日志里翻有没有报错。以前这一步都是我手动复制日志贴回去,现在省了不少事。

写在后面

代码写得比较糙的地方肯定不少,界面也就那样吧,egui 的风格大家懂的。下一步打算做多账号的 Git 身份和凭据管理,具体时间还没定。

用着哪里别扭、你平时是怎么管一堆项目的、还想支持什么技术栈,都欢迎在评论区说,或者直接去提 issue。

GitHub:github.com/dennislee66...

相关推荐
Amos_Web1 小时前
通过 Rspack 源码学 Rust(零):Cargo workspace 与统一依赖版本
rust
福大大架构师每日一题3 小时前
rust 1.99.1 正式更新:聚焦 UEFI、嵌入式、x86_64 FFI 与 macOS 链接体验的三项修复
开发语言·macos·rust
小道士写程序3 小时前
Rust 元组详解:复合类型的基础
开发语言·rust
小灰灰搞电子16 小时前
Rust+Slint 实现FTP客户端调试助手源码分享
开发语言·后端·rust
Flynt17 小时前
Cloudflare 用 Rust 重写了 TypeScript:我拿同一批代码跑了跑,报错一模一样,退出码不一样
rust·typescript·前端工程化
miofly1 天前
GitHub 今日推荐|pandacode:本地桌面统一管理多个AI编码代理
rust·开源·github
怪我冷i1 天前
Rust 核心语法与内存安全机制
开发语言·安全·rust
程工造Agent2 天前
从 0 到 1 学 Codex 源码:顺着 main 读懂 Rust 闭包与 async move
rust·ai编程
shimly1234562 天前
(done) RUST 指针详解
rust