迁移布局
概览
上游 agent-skills 将工作文件放在项目根目录。团队将它们保存在 .claude-work/ 中(参见团队覆盖中的路径表)。此技能将正在进行的项目迁移到团队布局,一次提交完成。每个文件保留其 Git 历史。任务复选框随文件移动,因此工作可以从中断处继续。
参数是计划和任务文件的 <id>,例如 /agent-skills-jksim:migrate-layout fl-debug。
何时使用
- 项目根目录中存在
SPEC.md、tasks/plan.md、tasks/todo.md或CONSTRAINTS.md。 - 项目同时存在根工作文件和
.claude-work/。
请勿用于新项目。规范阶段从一开始就写入 .claude-work/。
过程
1. 检查起始状态
当以下任一情况成立时,停止并告知用户:
- 该文件夹不是 Git 仓库。
git status --porcelain --untracked-files=no显示对已跟踪文件有更改。要求用户先提交或 stash 它们。未跟踪的文件可以保留:第 8 步使用git add -u,它永远不会添加未跟踪的文件。git check-ignore -q .claude-work/spec/SPEC.md成功。检查文件路径:诸如.claude-work/的模式在文件夹存在之前不会匹配。消费项目会提交.claude-work/。
2. 查找旧文件
仅查看以下相对于项目根目录的路径:
| 旧路径 | 团队路径 |
|---|---|
SPEC.md, docs/SPEC.md | .claude-work/spec/SPEC.md |
SPEC-<module>.md | .claude-work/spec/SPEC-<module>.md |
CAPABILITY-MAP.md | .claude-work/spec/CAPABILITY-MAP.md |
tasks/plan.md | .claude-work/tasks/plan-<id>.md |
tasks/todo.md | .claude-work/tasks/todo-<id>.md |
CONSTRAINTS.md | .claude-work/docs/CONSTRAINTS.md |
docs/ideas/<name>.md | .claude-work/docs/ideas/<name>.md |
docs/intent/<topic>.md | .claude-work/docs/intent/<topic>.md |
docs/decisions/ | 保留。询问(见第 4 步) |
不要触碰 spec/。RSpec 和其他测试布局会使用它。
仅使用 Git 跟踪的文件(git ls-files)。git mv 在其他文件上会失败。列出任何未跟踪或忽略的旧文件并询问用户。
当没有旧文件存在时,告知用户没有需要迁移的内容。停止。
3. 获取 <id>
使用参数。没有参数时,从项目名称建议一个简短的 kebab-case id 并询问用户。当没有 tasks/plan.md 或 tasks/todo.md 时跳过此步。
4. 显示计划并等待批准
显示一个表格:旧路径、新路径。然后列出每个冲突并询问:
- **目标已存在:**团队路径已有一个文件。不要移动该文件。询问如何处理。
- 两个规范:
SPEC.md和docs/SPEC.md都存在。询问哪个是规范。 - **
tasks/中的其他文件:**仅移动plan.md和todo.md。列出其他文件。 - **
docs/decisions/存在:**默认是保留它,因为项目保留自己的 ADR 文件夹。仅在用户要求时才将其移动到.claude-work/docs/adr/。
在用户批准表格之前,不要移动任何内容。
5. 使用 git mv 移动
为每个文件运行 git mv <old> <new>。先创建目标文件夹(mkdir -p)。切勿复制然后删除:git mv 保留历史。如果 tasks/ 现在为空,运行 rmdir tasks。
6. 修复实时引用
在项目中搜索旧路径:git grep -n -E 'SPEC(-[A-Za-z0-9_-]+)?\.md|CAPABILITY-MAP\.md|CONSTRAINTS\.md|tasks/(plan|todo)\.md|docs/(ideas|intent|decisions)/'。
同时搜索裸文件名,因为移动的文件可以在没有文件夹的情况下引用其伙伴:git grep -n -E '(^|[^-/A-Za-z0-9_])(plan|todo)\.md'。例如:计划中的 "detail in todo.md" 变为 "detail in todo-.md"。
实时引用告诉读者或代理文件现在在哪里。更改它:
CLAUDE.md:"SPEC.md: approved spec" 变为 ".claude-work/spec/SPEC.md: approved spec"。README.md:[SPEC.md](SPEC.md)变为[SPEC.md](.claude-work/spec/SPEC.md)。- 移动文件中的相对链接:旧
tasks/plan.md中的../SPEC.md变为.claude-work/tasks/plan-<id>.md中的../spec/SPEC.md。 CLAUDE.md中的约束指针行。- 每个移动文件中的其他相对链接。移动的文件位于新深度,因此指向未移动文件的链接也会失效。例如:根目录
SPEC-foo.md中的[x](src/a.kt)变为.claude-work/spec/SPEC-foo.md中的[x](../../src/a.kt)。
记录描述过去发生的事情。保持原样:
- 已完成的任务条目:"Files: README.md, SPEC.md"。
- 变更日志、审查说明或提交消息。
当不确定时,保留文本并在第 7 步中列出。
7. 显示结果
显示 git status、更改引用的差异以及未更改的旧路径引用列表,并附上每个的原因。
8. 一次提交
git mv 已经暂存了移动。使用 git add -u 暂存已编辑的引用。不要使用 git add -A:它可能添加不相关的文件。使用消息 Move working files to .claude-work 提交。不要推送。
如果钩子拒绝提交,停止并报告。不要使用 --no-verify。
9. 报告下一步
告知用户哪些文件移动了,哪些保留了。如果 .claude-work/docs/VOCABULARY.md 不存在,说明下一个规范阶段会创建它(规则 2)。现在不要创建它。
常见理由
| 理由 | 现实 |
|---|---|
"复制比 git mv 简单。" | 复制会丢失文件历史。审查者和 git log --follow 需要历史。 |
"我会更新每个提到的 SPEC.md。" | 记录描述过去。更改它们会重写历史。 |
| "工作树只是有点脏。" | 未提交的工作最终会进入迁移提交。先询问用户。 |
| "计划很明显,所以我会跳过批准。" | 用户决定 <id> 和每个冲突。等待。 |
红旗
git log --follow显示迁移提交之前没有历史。- 已完成的任务条目或变更日志命名了当时不存在的团队路径。
spec/或docs/decisions/未经用户批准而移动。- 多于一次提交,或一次推送。
验证
- 每个旧文件都在其团队路径。没有旧文件留在根目录,除非用户选择保留。
-
git log --follow <new path>显示旧历史。 - 实时引用指向团队路径。记录未更改。
- 任务复选框未更改。
- 一次提交,"Move working files to .claude-work"。
git status干净。未推送任何内容。