0%

Everyday CLI 更新一览:v0.13 → v0.18 演进与经验

【本文由 AI 辅助完成】

上篇《Everyday CLI开发经验谈》记录到 v0.10–v0.11 时代。此后两周,Everyday CLI 从 v0.13.0 迭代到 v0.18.0,跨了 11 个版本点。本文按「版本时间线 + 主题深挖」双线梳理这段演进,最后单独成章,分享这期间最有代表性的一类经验——在 WorkBuddy 沙盒不稳定性下的工程实践。

版本时间线

版本 日期 主要内容
v0.13.0 08-09 WebDAV 同步(D001-D003)
v0.14.0 08-10 auth 环境变量凭证回退(R020)
v0.15.0 08-10 MCP server over stdio(F014)
v0.16.0–2 08-10 tracing 分级日志(F015)
v0.17.0 08-14 daemon 守护进程(F016)
v0.17.1 08-14 日期序列 ID + PID(R021)
v0.17.2 08-18 task 命令执行 + cron(F017)
v0.17.4 08-18 task/config/output 重构
v0.17.6 08-19 rss digest –since(F008 修订)
v0.17.7 08-21 日历时区修复(Utc → Local)
v0.18.0 08-24 mail search –cached + mail gc

两周 11 个版本点,节奏相当密集。以下按主题展开。

同步与凭证

v0.13.0 引入 WebDAV 同步(src/modules/sync/,D001-D003),跨设备数据打通,这是 daily 数据能跟随 agent 迁移的基础设施。

v0.14.0 的 R020 补强了凭证体系:[auth] env_credentials = trueEVERYDAY_ENV_CREDENTIALS=1 双通道,变量命名 EVERYDAY_<MODULE>_<ACCOUNT>_PASSWORD,读取链 keyring → env → 报错。这条规则解决了无钥匙串环境下 agent 取不到凭据的问题——CI 或容器里没有系统 keyring,环境变量回退是刚需。

MCP server over stdio

v0.15.0(F014)让 everyday 可直接作为 MCP server 被 WorkBuddy 等客户端拉起。这个版本定下的契约后来成为所有模块被 agent 稳定调用的基础:

  • stdout 专供 JSON-RPC,任何日志、调试信息一律走 stderr;
  • JSON 输出三系形状 {"_log"} / {"_warning"} / {"_error"} 不可变。

日志与可观测

v0.16.0–2 落地 tracing 分级日志(F015),默认 WARN 静音。原因很实际:agent 会话里如果默认 INFO,调试噪音会淹没真正的问题;需要细粒度追踪时再显式调级别。

daemon 守护进程

v0.17.0(F016)是走向「个人 Info Agent」的关键一步。daemon run [--once] / daemon status,周期性同步 timeline + mail + rss,状态落在 ~/.config/everyday/daemon-state.json。设计上值得注意的两点:

  • pid 存活检测防重入:同一时刻只允许一个 daemon 实例;
  • 同步 = timeline run_sync + mail 全 folders 增量(每周期 IMAP LIST)+ rss。

编号体系与 task 子系统

v0.17.1 定稿 R021 编号规则:id = {前缀}{YYYYMMDD}-{当日序号}(n/t/b/m/ev/mc/ri),按天重置、每前缀独立计数;旧格式共存不迁移。

v0.17.2(F017)给 task 模块加入命令执行与 cron 能力,v0.17.4 又对 task/config/output 做了一轮重构(Scheduler 上下文)——这是 v0.17.x 里真正的 SOLID 依赖反转对象。

rss 与日历

v0.17.6 修订 F008:rss digest --since 支持时间窗口聚合。

v0.17.7 修了一个隐蔽的日历时区 bug:cal list 对 UTC 存储事件直接输出 UTC 字符串、不转本地,导致日程显示早 8 小时。修复是 format_date_perhaps_timedate_perhaps_time_to_naiveUtc 变体先转 Local 再输出。更深一层是服务端数据缺陷:QQ 日历对手动创建的事件按「钟面时间直接标 Z」存储(naive-as-UTC),对同步导入事件存正确 UTC,两者从 ICS 无法区分——这个只能留作已知限制。

mail 收尾

v0.18.0 补齐 mail 模块最后两块拼图:mail search --cached(M006,信封缓存内搜索)与 mail gc(M007,缓存回收)。

开发经验:WorkBuddy 沙盒下的工程实践

v0.17.x 期间踩得最深的一类坑,来自开发环境本身——WorkBuddy 沙盒在 Windows 上对命令执行有各种不稳定性。沉淀出三条铁律:

1. 输出落盘 + 哨兵行,日志是唯一事实来源

1
cmd > log 2>&1; echo "EXIT=$?" >> log

vitest 等工具经管道输出时退出码会误报(管道吞掉真实 exit code);\r 进度条刷新符在管道捕获层被吞,工具返回空但命令其实已跑完。做法:所有测试/构建/安装命令重定向到日志文件,末尾追加哨兵行,只以日志为判断依据,绝不凭管道退出码下结论。

2. 工具空返回 ≠ 命令失败,先读日志再决定

「命令执行完 ≠ 工具感知到」。工具返回空或超时,先读日志、再查进程是否存活(tasklist),最后才决定是否重跑——盲重跑不仅浪费,还会掩盖真实的间歇性失败。

3. 怀疑命令执行错误时,用 Python subprocess 落盘验证

工具层报 Permission denied / os error 5 / 空返回,先写一次性 Python 脚本用 subprocess 把 stdout/stderr 落盘跑一遍。沙盒文件层写入受限而命令本身可正常执行,是 Windows 沙盒下的常见情况——工具报错不一定是命令真的失败。

附一个 Rust 专属边注:多次强杀 cargo 后,沙盒文件层可能持有 .cargo-build-lock 句柄,导致所有 target 构建失败(WinError 5)。cargo clean 直接根治,比重启应用快得多。

现状与下一步

当前 v0.18.0:13 个模块 + MCP server + WebDAV 同步,350+ 测试,冷启动 <100ms。下一步重心在 timeline 聚合的深化,以及 system/fs/network 模块缺口的评估。

参考链接:

扫码加入技术交流群🖱️
QR code