---
name: unidesk-tasktree
description: >-
  UniDesk TaskTree CLI 任务管理主入口，接管原文件式任务 CLI 的 TaskGroup、
  Task、Subtask、Subsubtask、状态、执行报告、统计、时间线和 Markdown 导入。
  用户提到用 CLI 管理任务、创建或更新任务、开始或完成任务、任务报告、
  TaskTree、taskgroup、task/subtask、milestone 或 execution report 时使用。
  TaskTree native、PostgreSQL、Temporal、API/worker、Web、CI/CD 和部署请求
  同样使用本技能，并按需读取开发运维 reference。
---

# UniDesk TaskTree

本技能遵循 Skill(cli-spec)。

## 任务管理合同

- 新的 CLI 任务管理统一使用 TaskTree：
  - TaskGroup 管理一个任务集合；
  - Task 是顶层任务；
  - Subtask 与 Subsubtask 通过父任务关系表达两级下钻；
  - ExecutionReport 保存执行证据；
  - Milestone 保存时间节点。
- 默认使用 L0 本地 dispatcher：
  - 只需要 native PostgreSQL；
  - 普通增删改查、状态、报告和统计不要求 API、worker 或 Kubernetes；
  - 只有 workflow 需要 Temporal worker；
  - 只有验证服务传输合同时才增加 `--overapi`。
- 公共 CLI 只使用 TaskTree 术语：
  - 不新增历史工具名、历史 operation 或兼容别名；
  - 历史 Markdown 任务文件只通过 `group import-markdown` 迁移；
  - 导入后以 TaskGroup、Task 与 ExecutionReport 为任务管理对象。
- 禁止为新任务创建或继续写入 MDTODO：
  - skill、长期文档或 issue 中仍引用 MDTODO 时，将其视为待迁移入口；
  - 历史报告、已退役服务名和只读过程记录可以保留原词，不能作为新任务权威；
  - 当前任务没有遗留 MDTODO 时，直接创建或继续 TaskTree 任务。
- CLI 输出必须是可见 JSON：
  - 成功必须检查 `ok=true` 和 `operation`；
  - 失败必须保留稳定错误码和非零退出；
  - 不把自然语言日志或数据库行数当作任务状态真相。

## 强制生命周期同步

- TaskTree 状态是当前工作的权威真相，不是事后可选记录：
  - 开始执行已有任务前先用 `task get` 确认状态；状态为 `pending` 时必须立即
    执行 `task start`；
  - 新建后立即开始的任务必须在同一工作回合执行 `task start`，禁止长期留在
    `pending`；
  - 验收完成后、向用户报告完成前，必须写 ExecutionReport；
  - `report write` 成功后默认在同一事务内把任务切换为 `completed`，日常闭环
    不再额外执行 `task complete`；
  - 相同报告幂等写入返回 `mutation=false`，但任务状态滞后时仍必须校正为
    `completed`；
  - 禁止因为代码已提交、issue 已关闭、服务已上线或准备执行 `$post-task`，
    就跳过 TaskTree 状态更新；这些事实只能作为报告证据，不能替代状态 mutation；
  - 当前仍受阻时及时更新为 `blocked` 并在任务说明中写明阻塞证据；阻塞解除并
    恢复执行时重新 `task start`，验收完成后再写 ExecutionReport；
  - 父任务的验收目标与全部必要子任务均完成后，父任务也必须写报告并完成，
    不能只完成叶子节点而让父节点永久停留在未开始或进行中。
- 每次任务收口必须执行状态复核：
  - 用 `task get` 确认当前任务为 `completed`，并能读到本次 ExecutionReport；
  - 用 `group stats` 检查所属 TaskGroup，不得把“实际完成但仍为 pending、
    in_progress 或 blocked”的任务留给后续代理修正；
  - 只有用户明确暂停、验收未通过或存在真实阻塞时，任务才可以非 completed
    状态结束当前回合，并必须向用户报告原因。
- 清理历史滞后状态时不得仅凭标题批量完成：
  - 逐项核对提交、issue、部署、测试或既有报告证据；
  - 证据充分时补写 ExecutionReport，由报告写入自动完成任务；
  - 证据不足时保持原状态并补充说明，不伪造完成事实。

## 能力映射

| 任务管理能力 | TaskTree CLI |
| --- | --- |
| 任务集合创建、查询、删除、统计 | `group create\|list\|get\|delete\|stats` |
| 顶层任务创建、查询和批量创建 | `task create\|list\|get\|create-batch` |
| 子任务与二级子任务 | `task create --parent <task-id>` |
| 标题、说明、状态和时间更新 | `task update` |
| 开始、完成和删除 | `task start\|complete\|delete` |
| 执行报告写入和查询 | `report write\|list\|get` |
| 时间节点和时间线 | `milestone create`、`timeline` |
| 历史 Markdown 任务迁移 | `group import-markdown` |
| GitHub 灾备快照、校验与恢复规划 | `backup create\|status\|verify\|restore` |

## 最短闭环

- 从 UniDesk 仓库根目录执行。
- 统一入口从 owning YAML 选择 HWLAB workspace 和 native target，并从统一
  Secret source 注入数据库地址。
- 创建对象后从 JSON 结果读取 ID，不按名称猜测对象。

```bash
bun scripts/cli.ts tasktree group create \
  --name "示例任务组"
bun scripts/cli.ts tasktree task create \
  --group <group-id> --title "实现功能"
bun scripts/cli.ts tasktree task create \
  --group <group-id> --parent <task-id> --title "完成验证"
bun scripts/cli.ts tasktree task start \
  --task <task-id>
```

- 完成任务时写入 ExecutionReport，报告与完成状态在同一事务内提交：

```bash
bun scripts/cli.ts tasktree report write \
  --task <task-id> --title "执行报告" --stdin <<'EOF'
验证已完成，记录命令、结果和关键证据。
EOF
bun scripts/cli.ts tasktree group stats \
  --group <group-id>
```

- L1 只在原命令末尾增加 `--overapi`：
  - 参数、DTO、输出和错误合同不得变化；
  - 不维护第二套 API 专用命令。

## 命令面

```text
tasktree health
tasktree group list|overview|get|create|delete|stats
tasktree group import-markdown --file <path> [--name <taskgroup>] [--dry-run]
tasktree task list|get
tasktree task create|create-batch|update|delete|remove|start|complete|done
tasktree milestone create
tasktree report list|get|write
tasktree timeline
tasktree backup create|status|verify|restore
tasktree workflow start
```

- 标题和正文输入：
  - 单个创建与更新支持 `--title` 或 `--stdin`；
  - 二者互斥；
  - 标题必须是非空单行文本；
  - 批量创建使用 `task create-batch`；
  - 同批任务必须在一个事务内全部成功或全部失败；
  - 报告使用 `report write --stdin` 或 `--body-file`；
  - 相同任务、标题、正文和状态的重复报告返回 `mutation=false`。
  - `report write` 返回完成后的 `task` 和 `taskMutation`；
  - 报告内容幂等但任务尚未完成时，`mutation=false` 且
    `taskMutation=true`。
- 参数合同：
  - 多余位置参数返回 `invalid_arguments`；
  - 未知选项或命令不支持的选项返回 `invalid_option`；
  - 同一选项重复出现返回 `duplicate_option`；
  - 缺少选项值返回 `missing_option_value`；
  - 不得静默忽略、覆盖或猜测参数；
  - 帮助中未列出的历史命令返回 `unsupported_command`。
- 子任务层级：
  - Task 的子级是 Subtask；
  - Subtask 的子级是 Subsubtask；
  - Subsubtask 禁止继续创建下级。
- 状态流转：
  - `task start` 把任务标记为 `in_progress`；
  - `report write` 成功后自动把任务标记为 `completed`；
  - `task complete` 与 `task done` 保留为已有报告场景的显式完成入口，并要求
    至少一份 ExecutionReport；
  - 禁止使用 `task update --status completed` 绕过报告门禁；
  - `task update --status blocked` 用于标记阻塞；
  - `task delete` 与 `task remove` 使用相同删除合同。
- 时间节点：
  - Task 同时存在开始和截止时间时，开始时间不得晚于截止时间；
  - 创建或更新形成反向范围时返回 `invalid_time_range`；
  - Milestone 绑定的 Task 必须属于同一 TaskGroup；
  - 跨组绑定返回 `task_group_mismatch`。
- 查询与收口：
  - 任务执行前用 `task get` 读取当前状态与报告；
  - 批量查看使用 `task list --group <group-id>`；
  - 收口使用 `group stats --group <group-id>`；
  - 最终回复前必须按“强制生命周期同步”完成当前任务的报告、状态 mutation
    和复核；
  - 删除不存在的对象必须返回 `not_found`，不得伪装成功。
- 配置与传输错误：
  - L0 缺少数据库地址返回 `missing_database_url`；
  - `--overapi` 缺少 API URL 返回 `missing_api_url`；
  - API 无法连接返回 `api_unreachable`；
  - API 返回非 JSON、错误 operation 或 HTTP/envelope 冲突时返回
    `invalid_api_response`；
  - workflow 缺少 Temporal 地址返回 `temporal_address_required`。
- GitHub 灾备：
  - `backup create --dry-run` 只生成快照摘要；
  - `backup create` 发布当前 PostgreSQL 一致性快照；
  - `backup status` 查看最近尝试、成功、Git commit 和失败；
  - `backup verify` 对比数据库与 GitHub 内容 SHA；
  - `backup restore` 默认只生成恢复差异；
  - 真实恢复必须同时提供 `--confirm --expected-sha <sha256>`。

## 历史任务迁移

- 当前任务引用的 MDTODO 必须在继续实施前迁移：
  1. 用 `group import-markdown --dry-run` 核对层级、任务、报告、缺失报告和压平 warning。
  2. 执行正式导入，并保存 TaskGroup、Task、Subtask、Subsubtask 与 ExecutionReport ID。
  3. 用 `group stats` 和必要的 `task get`、`report list` 核对状态、层级和报告数量。
  4. 确认 GitHub 自动备份包含新快照；自动备份未生效时使用受控手动备份。
  5. 运行 `backup verify`，要求数据库 SHA 与 GitHub 快照 SHA 一致。
  6. 只有上述步骤全部成功后，才一次性删除原 MDTODO FILE 及其专属报告目录。
  7. 删除后从已导入的 TaskTree 对象继续任务，不再回写或重建原文件。
- 迁移失败、报告缺失未裁决或备份未验证时：
  - 禁止删除原文件；
  - 禁止在旧文件上继续推进；
  - 保留现场并修复导入或备份入口。
- 只读历史材料不自动批量迁移：
  - 当前任务真正恢复、修改或依赖其中任务状态时才触发迁移；
  - 不篡改历史报告中的旧系统名称、命令和运行面事实。
- 迁移入口：

```bash
bun scripts/cli.ts tasktree group import-markdown \
  --file <path> --dry-run
```

- 映射规则：
  - 一个历史任务文件映射为 TaskGroup；
  - 顶层 R 项映射为 Task；
  - `R2.9` 映射为 `R2` 的 Subtask；
  - `R2.9.1` 映射为 `R2.9` 的 Subsubtask；
  - 第四级及更深层级压平到第三级；
  - 压平必须返回 `nested_task_flattened` warning。
- 标题与报告：
  - 标题不得按冒号截断；
  - Markdown 链接和 URL 后正文必须完整保留；
  - 本地任务报告链接自动读取为 ExecutionReport；
  - 报告文件缺失时保留任务；
  - 缺失报告返回 `report_file_missing` warning。
- 时间规则：
  - 缺少显式时间时，以任务文件最后修改时间作为截止时间；
  - 开始时间为截止时间前一天；
  - 存在报告时，以最新报告文件修改时间为准；
  - 父任务时间范围必须覆盖全部子任务；
  - 导入报告的 `createdAt` 使用报告文件修改时间；
  - 数据统一以 UTC 存储，显示时按用户时区渲染。
- 执行规则：
  - 先用 `--dry-run` 核对 task、subtask、report、missing 和 flattened 计数；
  - 实际导入必须在单个 PostgreSQL 事务内完成；
  - `--overapi` 时由 CLI 读取本地文件并通过 DTO 传给 API；
  - API Pod 不挂载调用端文件系统。

## 按需参考

- 日常 CLI 任务管理只使用本文件，不读取开发运维 reference。
- 出现以下任务时，完整读取
  [开发与运维参考](references/development-operations.md)：
  - 修改 TaskTree 源码、数据库或 Temporal workflow；
  - 启动 L1 API、worker 或 HMR Web；
  - 使用部署态 `--overapi`；
  - 配置、验证或恢复 GitHub 灾备快照；
  - 执行 Web 视觉验收；
  - 创建 PR、进入 L2 或观察自动交付。
