跳到主要内容

Everything as Code

UnderControl 将任务和笔记存储为带有 YAML frontmatter 的纯 Markdown 文件。文件格式由开源的 JSON Schema 定义,发布在 ud-schemas 仓库中。

这意味着你的数据始终是:

  • 人类可读 — 使用任何文本编辑器编辑
  • 可追踪差异 — 在版本控制中跟踪变更
  • 可移植 — 无厂商锁定,标准格式
  • AI 友好 — LLM 可以原生读写你的任务

Schemas

Schema描述
task.v1.schema.json任务文件 — 标题、状态、标签、截止日期 + Markdown 正文
note.v1.schema.json笔记文件 — 通过 task_id 关联到父任务 + Markdown 正文

两个 Schema 均使用 JSON Schema draft-2020-12


任务文件格式

任务文件是一个 Markdown 文件,在 --- 分隔符之间包含 YAML frontmatter:

---
id: 550e8400-e29b-41d4-a716-446655440000
title: 发布 v1 版本
status: in-progress
tags:
- release
- urgent
deadline: 2025-06-01
created_at: 2025-01-01T00:00:00Z
updated_at: 2025-05-20T14:30:00Z
---

v1 发布前的最终清单:

- [ ] 运行完整测试套件
- [ ] 更新变更日志
- [ ] 打标签发布

任务字段

字段类型必填描述
idUUID有值 = 更新现有任务。无值 = 创建新任务。
titlestring任务标题。也用于生成文件名。
statusstring可选值:todoin-progresspendingstaledonearchived。默认:todo
tagsstring[]标签列表
deadlinestringISO 8601 或 YYYY-MM-DD 格式的截止日期
created_atdate-time由服务器设置,请勿修改。
updated_atdate-time由服务器设置,用于同步冲突检测。

状态值

规范值使用连字符。客户端在读取时自动标准化:

输入标准化结果
in_progressInProgressin progressin-progress
to-dotodo
completedcompletedone
archivearchived

截止日期格式

以下格式均可接受,会自动标准化为 ISO 8601:

deadline: 2025-03-15
deadline: 2025/03/15
deadline: 2025-03-15T14:30:00
deadline: 2025-03-15T14:30:00Z
deadline: 2025-03-15T14:30:00+08:00

笔记文件格式

笔记通过 task_id 关联到父任务:

---
id: 7a8e6f4f-1234-5678-abcd-ef0123456789
task_id: 550e8400-e29b-41d4-a716-446655440000
created_at: 2025-05-20T15:00:00Z
updated_at: 2025-05-20T15:00:00Z
---

与团队讨论了部署策略。
决定采用蓝绿部署方案。

笔记字段

字段类型必填描述
idUUID有值 = 更新。无值 = 创建。
task_idUUID父任务的 UUID
created_atdate-time由服务器设置
updated_atdate-time由服务器设置

创建 vs 更新(声明式语义)

任务和笔记文件均遵循 kubectl 风格的声明式语义

  • frontmatter 中没有 id → 创建新资源
  • id → 更新现有资源(ID 可以是完整 UUID 或唯一前缀)

这适用于 CLI 的 ud apply 命令和本地同步文件扫描。

# 创建:文件中没有 id
echo '---
title: 新任务
status: todo
---
描述内容。' | ud apply -f -

# 更新:有 id
echo '---
id: 550e8400
title: 更新后的标题
status: done
---
更新后的描述。' | ud apply -f -

文件名规则

任务文件

任务文件使用 normalizeFilename(title) 命名:

  1. 将不安全字符(/\:*?"<>|%!#$&'()+,;=@[]^{}~)替换为 -
  2. 将多个连续空格/短横线合并为单个短横线
  3. 去除首尾短横线
  4. 截断到 100 个字符
  5. 结果为空则使用 untitled
  6. 重复时添加 -2-3 后缀

示例:Ship v1 releaseShip-v1-release.md

笔记文件

笔记文件命名为:{normalizeFilename(taskTitle)}-{normalizeFilename(noteFirstLine)}.md

任务标题前缀在文件系统中将笔记与其父任务视觉关联。


URL 规则

内容可以使用以下 URL 方案交叉引用其他资源:

应用协议(存储在后端)

方案格式
resource://resource://{resourceId}
tasks://tasks://{taskId}
note://note://{taskId}/{noteId}

本地文件路径(同步文件夹中)

类型格式
资源./resources/{resourceId}.{ext}
任务./{Task-Title}.md
笔记./{TaskTitle}-{NoteFirstLine}.md

客户端在同步期间进行格式转换。


验证文件

使用 check-jsonschema(Python)

pip install check-jsonschema
check-jsonschema --schemafile task.v1.schema.json your-task.json

使用 ajv(Node.js)

npm install -g ajv-cli ajv-formats
ajv validate -s task.v1.schema.json -d your-task.json --spec=draft2020

编辑器集成

大多数支持 YAML/JSON Schema 的编辑器可以使用这些 Schema 进行自动补全和内联验证。


Schema 仓库

Schema 作为开源仓库发布:

  • 仓库: ud-schemas
  • 许可证: MIT
  • 版本控制: Schema 使用 v{N} 后缀。破坏性变更会提升版本号。

仓库包含示例文件和使用说明。