关于 aif-archive
aif-archive 将已完成的计划和 ultra 套件目录从活动计划区移入归档,也可为已关闭的路线图里程碑创建快照。它会检查任务完成状态、验证套件并防止覆盖目标;批量或路线图操作需确认。
主要功能
- 01归档已完成计划和套件
- 02列出归档计划与快照
- 03为已关闭里程碑创建快照
- 04检查计划任务完成状态
- 05移动前验证 ultra 套件
- 06检测目标路径冲突
适用场景
- 01将完成的计划移出活动计划区
- 02查看已归档计划和路线图快照
- 03用带日期的快照保存已完成里程碑
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lee-to/ ai-factory --skill aif-archive安装后在 Claude Code 中输入/aif-archive确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
tests/archive-completed-plan.yamlarchive-completed-ultra-bundle.yamlcollision-stops-before-overwrite.yamllist-archived-plans.yamlroadmap-snapshot-collision.yamlskip-incomplete-plan.yaml详细介绍
归档 — 移动已完成的计划和路线图快照
将已完成的单文件计划和 ultra 捆绑目录从
paths.plans/ 移动到 paths.archive/plans/,并可选择将已结束的里程碑从
ROADMAP.md 移至 paths.archive/roadmap/ 下带日期的快照中。
工作流
步骤 0:加载配置
如果 .ai-factory/config.yaml 存在,则读取以解析:
paths.plans(默认值:.ai-factory/plans/)paths.archive(默认值:.ai-factory/archive/)paths.plan(默认值:.ai-factory/PLAN.md)paths.fix_plan(默认值:.ai-factory/FIX_PLAN.md)paths.roadmap(默认值:.ai-factory/ROADMAP.md)workflow.plan_id_format(默认值:slug)— 当前有效值:slug和sequential。timestamp和uuid保留,其行为与slug相同。 将任何未知值视为slug。- 面向用户的提示词所用的
language.ui
如果配置不存在,则使用上述默认值。
如果 .ai-factory/skill-context/aif-archive/SKILL.md 存在,则读取它 —
项目特定的覆盖规则优先于通用说明。
步骤 1:解析参数
从参数中提取模式:
(no args) → interactive mode: scan, show completable plans, ask which to archive
list → show archive contents, then STOP
--roadmap → trim closed milestones from ROADMAP.md into a snapshot
--all → archive ALL completed plans (ask confirmation first)
<plan-name> → archive a specific plan by filename or partial stem match
解析规则:
list和--roadmap不能与<plan-name>和--all同时使用- 如果给出了多个互相冲突的模式,则输出错误并停止
<plan-name>可以是:- 完整文件名:
0005_feature-auth.md - ultra 目录/入口文件:
0005_feature-auth或0005_feature-auth/index.md - 不带扩展名的文件名:
0005_feature-auth - 部分匹配:
feature-auth(必须且只能匹配一个计划)
- 完整文件名:
步骤 2:执行模式
模式:交互式(无参数)
- 使用
Glob扫描paths.plans/,查找根目录下的*.md文件和直接子目录中的*/index.md候选项。排除解析后的paths.plan和paths.fix_plan;只有当目录的入口文件声明 `` 时,才将其计为计划。不要将阶段文件或无关目录视为计划。 - 对每个条目,读取入口文件的
## Tasks部分。 - 判断完成状态:当所有任务复选框均为
- [x]时,计划才算已完成。含有任何- [ ]的计划均未完成。 - 如果没有找到已完成的计划:
→ 停止。No completed plans found in <paths.plans/>. - 显示已完成的计划:
Completed plans ready to archive: 1. 0001_feature-alpha.md (completed 2026-05-20) 2. 0003_feature-gamma.md (completed 2026-05-24) Incomplete plans (skipped): - 0005_feature-delta.md (3/7 tasks done) - 询问要归档哪些计划:
AskUserQuestion: Which plans to archive? Options: 1. All completed plans listed above 2. Select specific plans (enter numbers) 3. Cancel - 对选定的计划执行归档操作(参见归档操作)。
模式:list
- 检查
<paths.archive>/plans/是否存在。 - 如果不存在:
Archive is empty. No plans have been archived yet.→ 停止。 - 使用 Glob 查找根目录下的
<paths.archive>/plans/*.md文件,以及直接子目录中的<paths.archive>/plans/*/index.md入口文件;入口文件必须恰好包含一个 ``。 - 对每个已归档条目,从 YAML frontmatter(完整计划)或紧跟在 ultra
标记之后的 `` 中提取日期(
index.md)。 - 显示:
Archived plans (<paths.archive>/plans/): 1. 0001_feature-alpha.md (archived: 2026-05-20) 2. 0003_feature-gamma.md (archived: 2026-05-24) Total: 2 archived plans - 检查
<paths.archive>/roadmap/中是否有快照;如果有,则列出:Roadmap snapshots (<paths.archive>/roadmap/): 1. 2026-05-20_roadmap-snapshot.md (3 milestones) - 停止。
模式:<plan-name>
- 将
<plan-name>解析为paths.plans/中的一个条目:- 尝试精确匹配根目录文件名、ultra 目录或精确匹配
*/index.md - 然后尝试追加
.md扩展名 - 然后尝试与根目录文件名和 ultra 目录名进行部分匹配
- 尝试精确匹配根目录文件名、ultra 目录或精确匹配
- 如果没有匹配项:输出
Plan not found: <plan-name>并提供建议 → 停止。 - 如果有多个匹配项:列出它们并请用户提供更具体的信息 → 停止。
- 如果匹配项是目录,则读取入口文件并要求其包含 ``; 否则它不是可归档的 AI Factory 计划。
- 读取匹配的入口文件并检查完成状态。
- 如果未完成:
→ 停止。Plan <filename> is not completed (5/8 tasks done). Only completed plans can be archived. - 执行归档操作(参见归档操作)。
模式:--all
- 扫描
paths.plans/中已完成的计划(逻辑与交互式模式相同)。 - 如果没有已完成的计划,则告知用户并停止。
- 显示列表并请求确认:
AskUserQuestion: Archive ALL completed plans? 1. 0001_feature-alpha.md 2. 0003_feature-gamma.md Options: 1. Yes, archive all 2 plans 2. Cancel - 对所有已确认的计划执行归档操作。
模式:--roadmap
- 读取已解析的
paths.roadmap文件。 - 如果文件不存在:
No ROADMAP.md found at <path>.→ 停止。 - 查找复选框为
- [x]的里程碑(已完成的里程碑)。 - 如果没有已完成的里程碑:
No closed milestones to archive.→ 停止。 - 显示并请求确认:
Closed milestones found in ROADMAP.md: - [x] MVP Launch — core features shipped - [x] Beta Testing — user feedback round AskUserQuestion: Trim these milestones from ROADMAP.md into a snapshot? Options: 1. Yes, create snapshot and trim 2. Cancel - 创建快照:
mkdir -p <paths.archive>/roadmap/- 确定快照文件名:
YYYY-MM-DD_roadmap-snapshot.md - 检查文件名冲突。 写入前,确认目标文件尚不存在:
如果文件存在,添加数字后缀,生成不冲突的文件名:Read <paths.archive>/roadmap/YYYY-MM-DD_roadmap-snapshot.mdYYYY-MM-DD_roadmap-snapshot-2.md、YYYY-MM-DD_roadmap-snapshot-3.md等。 逐一检查候选文件名,直到找到可用名称。 - 使用以下内容写入已解析的快照路径:
# Roadmap Snapshot — YYYY-MM-DD Archived from: <paths.roadmap> ## Archived Milestones - [x] MVP Launch — core features shipped - [x] Beta Testing — user feedback round
- 编辑
paths.roadmap:从## Milestones部分移除已归档的- [x]行。如果存在## Completed表格,则保留。 仅当第 6 步的快照写入成功后,才可编辑paths.roadmap。 - 日志:
INFO [aif-archive] roadmap snapshot: <resolved-path> (<N> milestones archived)
归档操作(计划)
对于每个要归档的计划产物:
-
mkdir -p <paths.archive>/plans/ -
冲突检查。 移动前,确认目标路径不存在:
Read <paths.archive>/plans/<original-name> # full plan Read <paths.archive>/plans/<original-name>/index.md # ultra bundle如果文件已存在:
- 单个计划(交互式或
<plan-name>):停止并报错:ERROR [aif-archive] destination already exists: <paths.archive>/plans/<filename> A previously archived plan has the same filename. This can happen when sequential numbering reuses a freed number after archiving. To resolve: rename the existing archive file, or delete it if it is no longer needed. - 批量(
--all):跳过此计划并发出警告,继续处理下一个:WARN [aif-archive] skipped: <filename> — destination already exists
两种情况下都不得覆盖。
- 单个计划(交互式或
-
移动前验证 ultra bundle。 读取
index.md并要求:- 恰好有一个
, 位于第一行,或紧接在可选的首行之后; - 有非空的
## Phase Index; - 每个链接的阶段路径都是 bundle 的直接子项,且实际存在。
格式错误的 bundle 不可安全归档。单个计划时停止;在
--all模式下则发出WARN [aif-archive] skipped malformed ultra bundle: <filename>并继续。 - 恰好有一个
-
先将完整源产物移动到归档路径:
mv <paths.plans>/<name> <paths.archive>/plans/<name>对于 ultra,
<name>是整个目录,因此所有链接的阶段文件都会一起移动。 这会以原子方式将计划从活动发现范围中移除。 -
向已移动的入口文件添加归档元数据,使用
Edit(ultra 使用index.md,其他情况使用移动后的计划文件)。对于 ultra,保留规范标题,并在 `` 之后立即插入此注释:
切勿添加 YAML 前置内容,也不要移动 ultra 标记:它必须位于第一行,或紧接在可选的首行 Handoff 注释之后。
对于完整计划,如果文件已有 YAML 前置内容(位于文件顶部的
---标记之间):- 使用
Edit在现有前置内容块中添加archived: YYYY-MM-DD字段。
如果完整计划没有 YAML 前置内容:
- 使用
Edit在首行之前添加最简前置内容块:--- archived: YYYY-MM-DD ---
原始文件名或目录名将保持不变,包括任何顺序编号
NNNN_前缀。 - 使用
-
日志:
INFO [aif-archive] archived: <filename> -> <paths.archive>/plans/<filename> -
处理完所有计划后,显示摘要:
## Archive Complete Archived N plan(s) to <paths.archive>/plans/: - 0001_feature-alpha.md - 0003_feature-gamma.md Skipped: K (destination already exists) - 0002_feature-beta.md Plans directory: <paths.plans/> (M plans remaining)当 K 为 0 时,省略“Skipped”部分。
完成状态检测算法
满足以下条件时,计划视为已完成:
- 计划入口文件包含
## Tasks部分(标题匹配不区分大小写)。 - Tasks 部分(及其子部分)中所有匹配模式
- [x]或- [ ]的行均已勾选:每个复选框都必须是- [x]。 - 如果 Tasks 部分不包含任何复选框,则计划视为未完成(空计划不可归档)。
边缘情况:
## Tasks之外的复选框(例如## Settings或## Commit Plan中的复选框) 不计入完成状态。- 嵌套复选框(缩进的
- [x])计入完成状态。 - 入口文件中没有
## Tasks的计划不可归档——发出WARN [aif-archive] <name> has no ## Tasks section; skipping。
完成日期推断
在交互模式下显示“已完成”日期时:
- 检查 YAML 前置内容中的
completed字段——如果存在则使用。 - 回退到 git:
git log -1 --format=%ai -- <plan-file>,获取最后修改日期。 - 回退到文件系统:入口文件的修改时间。
重要规则
- 绝不归档未完成的计划 —— 所有任务都必须为
- [x] - 在执行
--all和--roadmap操作前,始终先征求确认 - 保留原始文件/目录名称 —— 包括顺序编号前缀
NNNN_ - 添加归档元数据 —— 完整计划使用 YAML frontmatter;计划包使用 ultra 标记后的稳定 `` 注释
- 不要修改快速计划(
paths.plan)或修复计划(paths.fix_plan)——这些是由/aif-implement和/aif-fix管理的单文件产物 - 顺序编号时不要计入已归档的计划 —— 已归档的计划位于
paths.archive/plans/,而非paths.plans/,因此/aif-plan的顺序扫描不会包含它们
产物所有权
- 负责管理:
paths.archive/plans/*.md、已归档的 ultra 计划包目录,以及paths.archive/roadmap/*.md - 读取: 根目录下的
paths.plans/*.md、直接子级 ultra 计划包中的*/index.md及其链接的阶段文件,以及paths.roadmap - 修改:
paths.roadmap(仅在使用--roadmap时,且仅在获得确认后) - 不会触及:
paths.plan、paths.fix_plan、paths.description、paths.architecture、paths.rules_file