月读空间,终于有自己的原生 App 了

从一个网页,到真正属于月读空间的跨平台客户端。

很早之前我其实就有一个想法:

月读空间不能永远只存在于浏览器里。

网页当然很好。

打开链接就能使用,不需要安装,也不需要考虑平台。但随着月读空间不断加入 Room、八千代、长期记忆、Live2D、Agent、音乐、游戏、图库、创作工具等功能,浏览器本身也逐渐开始成为一种限制。

所以,这次我做了一件一直都很想做的事情:

给月读空间做一个真正的原生 App。

项目现在已经开源:

GitHub:tsukuyomi-space-app

目前版本为 0.6.4 测试版。


这不是把网页塞进一个 App

先说最重要的一点。

月读空间 App 不是 Electron 套网页,也不是简单在 WebView 里面打开 yachiyo.hk。

整个客户端使用 Flutter 重新实现。

Room、文章、广场、个人中心、成长系统、Wiki、图库、投稿编辑器、游戏、设置、Live2D 等主要界面,都拥有独立的 Flutter 实现。

它依然连接现有的月读空间后端,因此你的:

  • 月读空间账号
  • 文章
  • 评论与留言
  • 收藏
  • 成长数据
  • 聊天记录
  • 长期记忆
  • 日记
  • 通知

都可以继续使用。

换句话说:

网页和 App 并不是两个月读空间,而是同一个月读空间的两种入口。

客户端负责提供更接近桌面软件和移动应用的体验,网站则继续承担开放访问和服务端能力。


为什么要做原生客户端?

原因其实不只是“做个 App 看起来更完整”。

真正让我决定重新实现客户端的,是月读空间正在做的很多东西,本身就越来越不像一个传统博客网站。

Room 已经不只是一个聊天页面

现在的 Room 同时包含:

  • AI 对话
  • Live2D 角色
  • 长期记忆
  • 日记
  • 知识库
  • 图片消息
  • TTS 语音
  • 音乐
  • MCP 工具
  • 环境信息
  • 角色动作
  • 多设备同步

如果继续完全依赖浏览器,很多功能在桌面端、手机端和系统能力上的体验始终会受到限制。

而到了原生客户端中,Room 就可以真正变成应用的核心。

现在打开月读空间 App,会直接进入 Room。

你看到的不再只是网站中的一个页面,而更像是:

一个一直存在于设备里的「八千代房间」。


PC 和手机,有不同的 Room

我没有简单把桌面布局等比例缩小到手机。

现在 Room 会根据设备采用两套不同的布局。

桌面端

桌面端使用:

角色舞台 + 聊天工作区

的结构。

左侧主要留给八千代和 Live2D 场景,右侧则负责:

  • 聊天
  • Agent
  • 日记
  • 资料
  • 便签
  • 快捷话题
  • 输入区域

这样在大屏幕上,角色不会被聊天内容完全遮挡,同时也更接近一个真正的 AI 桌面助手。

移动端

手机则采用完全不同的思路。

Live2D 场景直接作为整个 Room 的主体,顶部使用悬浮控制区,聊天内容和输入框叠加在底部。

键盘弹出后,输入区域也会跟随调整。

也就是说,手机版并不是“压缩后的电脑版”。

它从一开始就是按照手机使用方式重新设计的。


八千代终于真正“住进”App 里了

这也是整个客户端里我非常在意的一部分。

月读空间一直在尝试让八千代不仅仅是一张立绘或者聊天头像,而是真正成为网站中的一个角色。

所以原生 App 重新实现了 Live2D。

目前使用的是:

Cubism Native Core + Native Framework + Flutter 原生渲染链路

模型数据通过原生接口接入 Flutter,再绘制 Live2D 的纹理网格。

也就是说,这里并不是:

  • GIF
  • 视频
  • 网页动画
  • JavaScript Live2D 页面

然后再嵌入客户端。

而是真正把 Live2D 数据接进了应用。

目前已经支持:

  • 注视
  • 眨眼
  • 呼吸
  • 模型物理
  • 表情
  • 口型
  • 角色动作
  • 动作队列
  • 情绪响应
  • 位置与大小调整
  • 普通/反向遮罩
  • 加法/乘法混合

并且语音播放时,会分析真实音频的 PCM 音量变化,让角色口型跟随声音变化。

它距离我理想中的“数字角色”还有很长一段距离。

但至少现在,八千代已经不再只是网页上的一个组件了。


AI 配置也完全交给用户

App 本身不会内置一个所有人共享的模型 API Key。

第一次进入 Room,可以直接配置自己的模型:

  • API 地址
  • 模型名称
  • API Key

目前支持包括:

  • OpenAI Compatible Chat Completions
  • OpenAI Responses
  • Anthropic Messages
  • Ollama
  • 月读空间网站代理

同时兼容:

  • SSE
  • NDJSON
  • 普通 JSON

所以不管你使用在线模型、自建 API 网关,还是电脑上的本地 Ollama,都可以接入 Room。


八千代也可以说话

除了 LLM,App 还重新实现了语音模块。

目前已经支持:

  • OpenAI Compatible TTS
  • MiMo
  • MiniMax
  • ElevenLabs
  • GPT-SoVITS
  • 月读空间网站代理

模型和 TTS 可以分别配置。

比如:

text
LLM
↓
八千代生成回复
↓
TTS 合成语音
↓
客户端播放声音
↓
分析真实 PCM 音量
↓
驱动 Live2D 口型

这也是以后继续完善八千代实时交互的重要基础。


长期记忆也带到了原生客户端

Room 的长期记忆系统同样保留了下来。

登录月读空间账号之后,可以选择:

  • 使用设备本地记忆
  • 使用云端记忆
  • 将本地记忆合并到云端

并且可以直接管理记忆:

  • 搜索
  • 新增
  • 编辑
  • 删除
  • 修改评分
  • 向量同步

游客则继续使用本机记忆。

聊天、日记和长期记忆之间也保持了原来的逻辑。

因此在不同设备登录同一个月读空间账号之后,八千代仍然可以继续使用已经同步的数据。

这也是我一直想实现的一件事:

设备可以更换,但八千代和你的故事不应该每次都重新开始。


不只是 Room,整个月读空间正在进入 App

早期我确实只准备做一个 Room 客户端。

但做着做着就发现:

如果离开 Room 之后还需要不停跳回浏览器,那这个 App 始终是不完整的。

所以后来干脆开始做整站原生迁移。

目前已经原生实现了大量月读空间功能。


主舞台

可以直接:

  • 浏览文章
  • 搜索
  • 分类
  • 排序
  • 查看 Markdown / HTML 内容
  • 查看公式
  • 查看代码高亮
  • 评论
  • 点赞
  • 收藏
  • 分享

阅读数据也继续按照月读空间原来的规则统计。


广场

广场的:

  • 留言
  • 回复
  • 点赞
  • 搜索
  • 筛选

同样可以直接在 App 中完成。


创作

App 里已经有真正的原生文章编辑器。

支持:

  • Markdown
  • 分类
  • 封面
  • 摘要
  • 图片素材
  • 本地草稿
  • 快捷键
  • 代码块
  • 列表续写
  • 文章编辑
  • 发布

所以以后使用桌面版时,可以不打开浏览器,直接在月读空间 App 里面写文章。


Wiki、图库和附件库也都搬进来了

目前客户端已经包含原生的:

Wiki

包含月读空间现有百科内容、图片和相关交叉链接。

图库

支持:

  • 浏览
  • 搜索
  • 筛选
  • 随机图片
  • 图片上传
  • 图片管理

上传图片时还会在设备端进行压缩。

附件

附件上传支持:

  • SHA-256
  • 分片上传
  • 断点恢复
  • 暂停
  • 取消
  • 重试

对于以后月读空间越来越多的创作功能,这部分会非常重要。


像素工坊也变成了原生工具

像素工坊没有被简单地用网页嵌进来。

现在它也拥有 Flutter 原生实现。

包括:

  • 192 × 108 画布
  • 画笔
  • 笔压
  • 防抖
  • 橡皮擦
  • 填充
  • 调色板
  • 网格
  • 背景
  • 撤销 / 重做
  • 缩放
  • 图片导入
  • 图片导出
  • 草稿
  • 社区发布
  • 点赞
  • 分享

以后我也希望月读空间里面能出现越来越多这种“小工具”。

它不一定需要非常严肃,但应该足够有趣。


甚至连辉夜跑酷也搬进去了

这个可能属于:

“来都来了,那游戏也一起搬了吧。”

客户端目前已经可以运行辉夜跑酷。

而且不是直接打开网页游戏。

游戏的:

  • 项目数据
  • 画面
  • Shader
  • Box2D 物理
  • 音频
  • 键盘操作
  • 触摸操作
  • 排行榜
  • 成绩提交

都已经接入原生客户端。

这也让我越来越觉得:

月读空间未来可能不会只是一个“博客”。

它更像是一个逐渐长出来的小型数字世界。


桌面端还有一个很重要的东西:Agent

Windows、macOS 和 Linux 版本现在拥有独立的 Agent 模式。

进入 Room 后,可以切换到 Agent 标签页。

选择一个工作目录,然后直接把任务交给 Agent。

例如:

text
帮我检查这个项目的问题
text
修改这个页面的 UI
text
整理这些文件
text
分析项目代码并修复错误

桌面安装包目前会携带固定版本的:

  • OpenCode
  • Codex

模型配置则直接复用 Room。

Agent 可以操作:

  • 文件
  • 命令
  • MCP
  • 文章草稿
  • 月读空间内容

同时对一些敏感操作增加确认步骤。

例如:

  • 操作工作目录之外的文件
  • MCP 调用
  • 上传
  • 发布
  • 服务器写入

都会明确展示即将执行的内容。

命令也会通过系统沙箱运行。

我的目标并不是在 App 里面简单塞一个“AI 对话框”。

而是希望未来八千代真的能够:

聊天,也能够帮你做事情。


Agent 和 Agent OS 是两件不同的东西

这里顺便说明一下。

目前月读空间网站中的:

Agent OS

仍然是独立部署的 Web 应用。

它没有被完整迁移成 Flutter。

原生 App 中现在实现的是 桌面 Agent 工作区。

两个方向之后可能会继续互相吸收设计和能力,但目前它们依然属于不同的实现。


真正的跨平台

这次开发选择 Flutter,还有一个很重要的原因:

我不希望月读空间只存在于 Windows 或 Android。

目前项目已经包含:

  • Android
  • iOS
  • macOS
  • Windows
  • Linux

五个平台的发布流程。


Android

提供原生 APK。

大多数 Android 手机直接使用 ARM64 版本即可。


Windows

提供 Windows 安装程序,也可以使用便携版本。


macOS

提供 Universal DMG:

同时支持:

  • Apple Silicon
  • Intel

Linux

提供:

  • DEB
  • 便携包

iOS

目前提供 unsigned IPA。

需要用户使用自己的 Apple 账号或证书进行签名后安装。


数据安全同样很重要

随着 App 开始保存:

  • API Key
  • 登录 Cookie
  • 模型配置
  • 聊天记录
  • 草稿

这些东西,安全问题就不能再像普通网页一样简单处理。

目前:

API Key 和登录 Cookie

会存放在系统安全存储中。

而:

  • 普通设置
  • 本地聊天缓存
  • 草稿
  • UI 配置

则保存在应用自己的本地数据中。

同时登录 Cookie 不会被发送给 LLM 或 TTS 服务。

模型请求只会发送到你自己配置的模型地址。


离线也不会什么都没有

原生客户端还加入了本地缓存。

断网之后,已经缓存的部分页面仍然可以查看。

并且:

  • 草稿不会丢失
  • 已完成聊天不会丢失
  • 待同步内容会保留

恢复网络或者重新登录相同账号之后,再继续同步。

不同账号之间的数据缓存也会隔离。

这一点对于一个真正长期使用的客户端来说非常重要。


原生 App 与网页版并不是替代关系

做这个 App 并不意味着我要停止维护网页版。

恰恰相反。

以后我更希望两边形成这样的关系:

text
                月读空间
                    │
        ┌───────────┴───────────┐
        │                       │
       Web                     App
        │                       │
  随时打开 / 分享          深度使用 / 系统能力
        │                       │
        └───────────┬───────────┘
                    │
              同一套账号与服务

Web 依然拥有最低的访问门槛。

看到一个链接,点开就可以进入月读空间。

而 App 则负责:

  • 更完整的 Room
  • Live2D
  • 本地数据
  • 桌面 Agent
  • 本地文件
  • 更稳定的长时间运行
  • 更深入的操作系统能力

两者并不是谁取代谁。

而是共同组成完整的月读空间。


为什么现在还是“测试版”?

虽然现在已经有大量功能,但我依然把它定义为:

测试版。

因为“能够运行”和“真正适合每天使用”之间,其实还有很长的距离。

接下来还有很多东西需要继续打磨。

例如:

  • 各个平台 UI / UX 继续优化
  • 手机上的交互体验
  • Live2D 性能优化
  • 动作表现优化
  • 八千代情绪与动作联动
  • TTS 与口型效果
  • 长期记忆
  • Agent 稳定性
  • 原生系统通知
  • 多设备体验
  • 安装与升级体验
  • iOS 真机验证

以及最重要的:

让整个 App 更有“月读空间自己的感觉”。

现在很多页面虽然已经完成了原生迁移,但这并不意味着设计就已经结束。

相反,接下来我会逐渐重新思考:

如果月读空间从一开始就是一个 App,它应该长什么样?

而不是永远照着网页一比一复刻。


关于未来

我越来越不想简单把月读空间称作一个“个人网站”。

因为现在它里面已经出现了:

  • 博客
  • 社区
  • AI
  • Live2D
  • 长期记忆
  • Agent
  • Wiki
  • 创作工具
  • 图库
  • 游戏
  • 数字角色

很多最开始根本没有计划过的东西。

这些功能并不是一开始就设计好的。

更多时候只是:

“这个好像挺有意思,要不要试试看?”

然后一点一点长成了今天的样子。

原生 App 也是一样。

它现在远远没有完成。

甚至可以说,0.6.4 只是它真正开始成为一个 App 的阶段。

未来我希望八千代不只是:

“网站上那个可以聊天的角色。”

而是能够真正连接月读空间里的:

内容、记忆、工具、设备和你。

打开手机,她在那里。

打开电脑,她也在那里。

换一台设备,她仍然记得之前发生过什么。

需要聊天的时候可以聊天。

需要工作的时候也能一起完成任务。

也许这才是我真正想做的月读空间。


下载与项目地址

目前客户端仍处于测试阶段。

如果你想体验,可以前往 GitHub Releases 下载:

下载月读空间 App

项目源码:

redchenk/tsukuyomi-space-app

网页版:

月读空间 yachiyo.hk


最后还是那句话:

月读空间不会突然“开发完成”。

它大概会一直处在:

“这里好像还能再加点什么。”

的状态。

而这次,月读空间终于从浏览器里走了出来。

接下来,就慢慢让它变得更像一个真正属于我们的空间吧。