Repository navigation
v2.2.0
定时/触发式 AI 任务(YAML Recipes)
AI 此前只在你守在编辑器前时才工作:打开 AI 助手、选文档、下指令、审阅草稿、手动插入。
所有加工动作都要人在环。现在你可以写一条 YAML 配方,让 Flymd 按 cron 或保存事件自动加工笔记。
配方放在 <库根>/.flymd/recipes/*.yaml,随库走、能被 WebDAV 同步。
三十秒上手
id: daily-report
name: 每日汇总
trigger:
type: schedule
cron: "0 9 * * *"
prompt: |
汇总 {{date}} 的日记要点。
output:
mode: note
path: "AI/日报.md"每天 09:00 自动跑一次,结果追加到 AI/日报.md。
两种触发器
| 触发器 | 说明 |
|---|---|
schedule |
标准 5 段 cron(分 时 日 月 周),支持 * / 列表 / 范围 / 步长,以及 @daily @hourly @weekly @monthly @yearly 宏 |
on-save |
保存文件时触发,paths 用 glob 过滤(*.md / 日记/*.md / **/*.md),并有防抖窗口 |
cron 的日与周同时写死时按惯例取或:0 9 1 * 1 = 每月 1 号或每周一。
提示词变量
{{date}} {{time}} {{datetime}} {{weekday}} {{library}} {{file}} {{content}} {{todos}} {{files}}
{{todos}}只取未完成的待办(- [ ] xxx){{files}}是全库文件清单,会触发一次全库扫描——只在真的引用时才付这个代价- 变量名拼错不报错,但会替换成空串并记进运行日志(不会静默让你以为"AI 没读到数据")
三种输出
output.mode |
行为 |
|---|---|
none |
不落盘,只在运行日志留摘要(最安全,适合先试) |
note |
追加到 output.path,已存在就往下追加并加分隔标题 |
replace |
覆盖 output.path |
写回照样能回滚
所有落盘都先过 AI 写入护栏:写入前的原内容先快照到 <库根>/.flymd/ai-guard/。
- 快照失败(内容超 1 MB 等)会中止写入,不会留下写了一半的文件
- 结果可用 MCP 的
rollback_write,或 AI 助手的「回滚上一次 AI 写入」菜单撤掉 - 定时任务的写入与 MCP 客户端的写入落在同一个快照目录,互相可回滚
AI 配置不用重复填
优先级:recipe 内 ai: 段 > AI 助手插件的 ai.config > 内置免费模式。
也就是说你在「插件 → AI 助手」里配好的 baseUrl / apiKey / model,recipes 直接复用——
在 AI 助手里改一次 key,所有配方立刻跟着生效。没配过就走免费模式。
运行留痕
每次执行往 <库根>/.flymd/recipes/runs.jsonl 追加一行:成功与否、耗时、写到哪个文件、
对应的 snapshotId、AI 输出摘要。
「昨天那次定时任务到底跑了没、写了什么、能不能回滚」——一眼可查。
runs.jsonl 是设备本地的,不参与 WebDAV 同步;配方本身(*.yaml)跟着库走。
为什么放在核心而不是做成插件
三样能力插件都拿不到:
- on-save 触发源:插件 API 没有事件订阅机制,没有任何
onSave/subscribe钩子 - 全库扫描:
flymd_list_markdown_files/flymd_search_files_content在插件 denylist 里(防插件扫全库) - 护栏写入:
ai_guard_snapshot等四个命令同样在 denylist,插件只能走宿主提供的可信入口
走插件路线要先给宿主补两套新 API(事件总线 + 库结构化访问)、再改 76KB 的插件文档,
而这三样恰好都是核心层天然拥有的。所以定为核心模块 src/core/recipes/。
其它
- 配方写错不会静默失效:控制台会打出是哪个文件、哪个字段、期望什么,其余配方照常运行
output.path必须是库内相对路径,绝对路径与..越界一律拒绝- WebDAV 默认排除
.flymd/recipes/runs.jsonl(设备本地痕迹),但配方本身要同步 - 新增 104 个单测(含用真实文件系统的目录读写测试,以及出厂示例的解析校验)
- 引擎按需动态加载——
js-yamlchunk 不进入口静态闭包(仓库既有的 NFR-2 门禁)