LegalAVA · 副产品
Vibe side project · Android + Mac

DailyNotesvibe 副产品

给 Obsidian 日记用的手机端:上半屏月历,下半屏 Markdown,断网照常看、照常写;一旦连上,改动几秒内出现在电脑上的 Obsidian 里。它和上面的法律 agent 产品线没有关系——是同一套「agent 驱动开发」的工作方式,顺手做出来的东西。

它长什么样

三张设计图对应三种状态:阅读、编辑、冲突。手机上只有这一屏,没有第二级页面。

20:14▲ ▮▮ ▮
2026年8月 ▴今天 ⚙
8月26日 周三已同步
上午 客户开会-项目合同谈判
下午 一审开庭-施工合同纠纷
工时登记汇总
项目工作内容时长
客户 A合同谈判会议2.5h
案件 B一审开庭3.0h
整理开庭笔录
起草补充代理意见
Pasted image 20260826….png
双击进入编辑 · 上滑收起日历 · 左右滑切日
阅读(默认)完整渲染:表格、可点选的任务框、内嵌图片。今天是空心环,选中是实心,有日记的日子有一个点。
20:15▲ ▮▮ ▮
2026年8月 ▾今天 ⚙
8月26日 周三待上传 完成
上午 客户开会-项目合同谈判 下午 一审开庭-施工合同纠纷 ## 工时登记汇总 - [x] 整理开庭笔录 - [ ] 起草补充代理意见 1.5h **合计:5.5h** ✅ 已提交
H2**
编辑月历折成一行让位给键盘;标题、加粗、任务框在输入时即时套样式,语法符号仍在原处。停止输入 0.6 秒自动保存。
08:41▲ ▮▮ ▮
2026年8月 ▴今天 ⚙
8月26日 周三冲突
上午 客户开会-项目合同谈判
下午 一审开庭-施工合同纠纷 3.0h
工时登记汇总
项目工作内容时长
客户 A合同谈判会议2.5h
整理开庭笔录
起草补充代理意见
离线 / 待上传 / 同步中 / 冲突 —— 都在那颗芯片上
冲突两端同时改同一行才会到这一步;不同段落的并发修改会被行级三方合并自动吃掉。永不静默覆盖。

设计理念

先在真实 vault 上量了一遍(229 篇日记、中位数 498 字节、表格与任务清单高频、附件与笔记同文件夹),设计是从这些数字里长出来的,不是从功能清单里。

只碰一种文件读写范围限定为 daily/YYYYMMDD/YYYY-MM-DD.md;同一文件夹里的 docx、pdf、子目录一概不列不写。图片只读。范围越小,越敢做原子写和乐观锁。
本地是唯一真相源界面永远只读手机上的 SQLite,编辑先落本地;同步引擎在后台对账。断网不是异常状态,是默认状态。
服务器无状态Mac 上的服务不建库、不存缓存,真相就是 vault 里的文件本身;ETag 是文件内容的哈希。停掉服务、删掉代码,vault 毫发无损。
用文件系统的语义说话PUTIf-Match,服务端 412 时把当前版本一并交回;写文件先临时后 rename,Obsidian 永远读不到半截。
冲突不静默base / 本地 / 服务端三方行级合并;合不上就把两版都留下,让人选。日记是单人、追加为主的文本,绝大多数并发都能自动合并。
按 Obsidian 的规矩渲染![[图片]] 按「同文件夹 → assets → 全库同名」解析;单回车即换行;[[wikilink]] 只显示不跳转;^块ID 隐藏但绝不改动。
阅读为默认,双击才编辑打开就是排好版的一页,没有按钮;双击哪一段,光标就落在哪一段末尾。单击不做任何事,避免误触。
手势即导航上滑收起月历、左右滑切前后一天、顶部下拉刷新、点任务框直接改源码。单屏应用,导航都交给手指。
安全边界要实在一枚固定令牌,所有请求都要带;令牌不进仓库、不进配置文件,只在 Mac 上一个 600 权限的文件里。有了它,服务放在局域网还是公网,只是一个路由决定。

怎么同步

不用 WebDAV,不走 NAS,不引入任何新基础设施:一个 400 行的 Python 服务跑在 Mac 上,直接读写 vault。

手机 · Compose UI只读写本地库
Flow
Room / SQLite唯一真相源content · base · etag · dirty
HTTP · mDNS
SSE
daily-serverMac 上的 launchd 服务index / note / attach / events
直接读写
vault 文件Obsidian 热重载Synology Drive 下游不动
服务端变了?本地改过?动作
无事
拉取,覆盖本地与合并基线
PUTIf-Match;成功即更新基线
三方合并 → 干净就推送;否则进入冲突,等人
服务端没有新建(服务端自动建文件夹)
PUT 返回 412对账后又被电脑改了:拿 412 里带回的最新版本再合并一次

整个决策矩阵就是上面六行。它小到可以被完整测试,也小到出了问题一眼能看出在哪一行。

为什么叫 vibe 副产品

这个 App 从零到能用只花了一天,中间没有写过一行「手工」代码:agent 先实测 vault 的文件结构与 Markdown 用法,写出设计文档;人只做了四个决定——不走 NAS、默认只读双击编辑、图片要显示、仅限局域网;随后服务端、客户端、单元测试、launchd 配置一路落地,之后的十几次迭代全部由真机上的一句话反馈驱动。

「vibe」不是不认真——恰恰相反,认真的部分被前移到了设计与约束上:范围写死、真相源唯一、冲突显式、语义跟随 Obsidian。有了这些,实现就可以放心交给 agent 快速试错,出了问题也知道该往哪一层看。这和 LegalAVA 做法律工具时的态度是同一个:先把边界与方法讲清楚,再谈自动化。

技术与状态

手机端Kotlin · Jetpack Compose · Room · Markwon(表格 / 任务清单 / 图片 / 编辑器)· kizitonwose Calendar · WorkManager · OkHttp SSE。minSdk 26,无原生库。
服务端Python 3.11 · aiohttp · zeroconf。六个接口、私网限制、原子写、2 秒轮询推送 SSE、X-Token。launchd 常驻。
测试服务端 29 项 curl 回归(含 412、路径穿越、SSE);客户端 23 个单元测试(三方合并、Obsidian 语法、API 客户端)。
状态个人自用中,每天在真机上跑。不上架、不分发;源码仓库暂为私有。