feat/sdlc-fix-worktree/main #53

Merged
admin merged 4 commits from feat/sdlc-fix-worktree/main into master 2026-09-17 09:35:41 +00:00
Member

摘要

處理 PR 留言時不必先手動 cd 到正確的目錄:流程自己從工作包推導出工作樹路徑,
不在就重建,而且會先確認這顆 PR 還值得動手。

需求議題

#38 — 以 worktree 隔離平行工作包的實作與修正

工作包議題

#42 — 以 sdlc-fix 定位工作包的工作樹

變更內容

  • scripts/worktree-ensure.js:新增。由 owner/repo/分支名 推導工作樹路徑,
    不在就重建;分支兩邊都不存在時 BRANCH_NOT_FOUND,路徑被別的東西佔住時
    WORKTREE_PATH_TAKEN。
  • scripts/lib.js:planWorktree/createWorktree 由 branch-prep 搬進來,
    建立與重建共用同一份;planWorktree 多接受「不給來源分支」的用法。
    另補上 requireOrigin,兩支腳本的 origin 檢查只留一份。
  • scripts/branch-prep.js:改用 lib 的那一份,行為不變。
  • prompts/sdlc-fix.md:新增第 1 步「看 PR 現況,並定位工作樹」,原有五步往後移一號。
  • 測試:test/worktree-ensure.test.js 新增 11 條,test/sdlc-fix-assets.test.js 補 8 條,
    test/branch-prep.test.js 的回滾那條補一句「目錄也不該留下來」。

commit 一覽:

  • 96ed46f refactor(branch-prep):建立工作樹的「算」與「做」收進 lib
  • ee5e80b feat(worktree-ensure):定位工作包的工作樹,不在就重建
  • 6b3cb05 docs(sdlc-fix):第一步先看 PR 現況,再定位工作樹
  • f09b729 fix(lib):補回搬家時掉了的 rmSync,並讓 origin 檢查只有一份

設計重點

「不在就重建」是常態,不是防禦性程式設計。 進度完全不寫在本機——換一台機器或換一個
agent 接手時,工作樹本來就不存在,而重建的成本就是一次 git worktree add。

重建不另寫一套。 這是 #42 明文要求的,理由是:兩邊各寫一份,遲早會在「起點取自
哪裡」「要不要設 upstream」這種地方分岔,而那種分岔要等到有人的進度不見了才會被發現。
所以把 planWorktree/createWorktree 搬進 lib,branch-prep 與 worktree-ensure
共用同一份;「不給來源分支」就是重建模式,沒有「從來源長一支新的」那條路——在定位的
時候憑空開一支新分支,等於把 PR 的進度扔掉。

查現況那一行帶 --dry-run。 pr-watch 在 PR 已終止時會順手清掉工作樹,而
/sdlc-fix 的第一步只是要知道現況:清不清理是使用者的決定,不該由「我想看一下留言」
這個動作順便做掉。

PR 已終止就停下來。 在一棵該被清掉的工作樹上改東西是白做工,而且那些改動不會進到
任何 PR 裡。正本把 suggestedAction 三個值的意思列成表,讓 agent 照著講而不是自由發揮。

review 抓到的一個沉默失效(f09b729)。 把 rollback 從 branch-prep 搬進 lib 時,
rmSync 的 import 留在了原處。那一行落在自己的 try/catch 裡,所以 ReferenceError
被吞掉——註解承諾的「git 清不乾淨時把目錄本身也清掉」從來沒發生過,而且測試全綠。
下一次重跑會撞上 WORKTREE_PATH_TAKEN,使用者看到的是一句與真正原因無關的錯誤。

解決的問題

/sdlc-fix 原本預設在當前目錄處理留言(#14 沒有工作樹的概念)。在多工作包的情境下,
當前目錄多半停在別顆工作包的分支上,改出來的東西會落到錯的分支去——而 agent 不會察覺。

另外兩種情境現在有明確的出口:換機器接手時工作樹不存在(自動重建,分支上的進度跟著
回來);PR 已經合併或關閉時(停下來並提示清理,不在該被清掉的工作樹上白做工)。

影響的功能

/sdlc-fix 多一步,原有五步的內容一字未改,只是編號往後移一號;#14 的七條驗收標準
全部仍然成立。branch-prep 行為不變(實作搬家,既有 38 條測試原封通過)。
lib 新增四個匯出(planWorktree/createWorktree/requireOrigin,以及既有的
worktree 家族),沒有既有簽章被改。

測試結果

npm test
ℹ tests 789
ℹ pass 789
ℹ fail 0

(已 rebase 到含 #52 的 master 之上再跑。)

另外對真實環境驗過一次:把先前刪掉的工作樹重建回同一條路徑,再清掉——

node scripts/worktree-ensure.js --repo plugins/tea-sdlc --path /root/plugins/tea-sdlc \
  --branch feat/pr-watch-and-cleanup/main
→ {"worktree":"/root/.tea-sdlc/worktrees/bd457620184e","動作":"接上本地既有","重建":true}

🤖 Generated with Claude Code

## 摘要 處理 PR 留言時不必先手動 `cd` 到正確的目錄:流程自己從工作包推導出工作樹路徑, 不在就重建,而且會先確認這顆 PR 還值得動手。 ## 需求議題 #38 — 以 worktree 隔離平行工作包的實作與修正 ## 工作包議題 #42 — 以 sdlc-fix 定位工作包的工作樹 ## 變更內容 - `scripts/worktree-ensure.js`:新增。由 `owner/repo/分支名` 推導工作樹路徑, 不在就重建;分支兩邊都不存在時 `BRANCH_NOT_FOUND`,路徑被別的東西佔住時 `WORKTREE_PATH_TAKEN`。 - `scripts/lib.js`:`planWorktree`/`createWorktree` 由 `branch-prep` 搬進來, 建立與重建共用同一份;`planWorktree` 多接受「不給來源分支」的用法。 另補上 `requireOrigin`,兩支腳本的 origin 檢查只留一份。 - `scripts/branch-prep.js`:改用 lib 的那一份,行為不變。 - `prompts/sdlc-fix.md`:新增第 1 步「看 PR 現況,並定位工作樹」,原有五步往後移一號。 - 測試:`test/worktree-ensure.test.js` 新增 11 條,`test/sdlc-fix-assets.test.js` 補 8 條, `test/branch-prep.test.js` 的回滾那條補一句「目錄也不該留下來」。 commit 一覽: - `96ed46f` refactor(branch-prep):建立工作樹的「算」與「做」收進 lib - `ee5e80b` feat(worktree-ensure):定位工作包的工作樹,不在就重建 - `6b3cb05` docs(sdlc-fix):第一步先看 PR 現況,再定位工作樹 - `f09b729` fix(lib):補回搬家時掉了的 `rmSync`,並讓 origin 檢查只有一份 ## 設計重點 **「不在就重建」是常態,不是防禦性程式設計。** 進度完全不寫在本機——換一台機器或換一個 agent 接手時,工作樹本來就不存在,而重建的成本就是一次 `git worktree add`。 **重建不另寫一套。** 這是 #42 明文要求的,理由是:兩邊各寫一份,遲早會在「起點取自 哪裡」「要不要設 upstream」這種地方分岔,而那種分岔要等到有人的進度不見了才會被發現。 所以把 `planWorktree`/`createWorktree` 搬進 lib,`branch-prep` 與 `worktree-ensure` 共用同一份;「不給來源分支」就是重建模式,沒有「從來源長一支新的」那條路——在定位的 時候憑空開一支新分支,等於把 PR 的進度扔掉。 **查現況那一行帶 `--dry-run`。** `pr-watch` 在 PR 已終止時會順手清掉工作樹,而 `/sdlc-fix` 的第一步只是要知道現況:清不清理是使用者的決定,不該由「我想看一下留言」 這個動作順便做掉。 **PR 已終止就停下來。** 在一棵該被清掉的工作樹上改東西是白做工,而且那些改動不會進到 任何 PR 裡。正本把 `suggestedAction` 三個值的意思列成表,讓 agent 照著講而不是自由發揮。 **review 抓到的一個沉默失效(`f09b729`)。** 把 `rollback` 從 `branch-prep` 搬進 lib 時, `rmSync` 的 import 留在了原處。那一行落在自己的 `try/catch` 裡,所以 `ReferenceError` 被吞掉——註解承諾的「git 清不乾淨時把目錄本身也清掉」從來沒發生過,而且測試全綠。 下一次重跑會撞上 `WORKTREE_PATH_TAKEN`,使用者看到的是一句與真正原因無關的錯誤。 ## 解決的問題 `/sdlc-fix` 原本預設在當前目錄處理留言(#14 沒有工作樹的概念)。在多工作包的情境下, 當前目錄多半停在別顆工作包的分支上,改出來的東西會落到錯的分支去——而 agent 不會察覺。 另外兩種情境現在有明確的出口:換機器接手時工作樹不存在(自動重建,分支上的進度跟著 回來);PR 已經合併或關閉時(停下來並提示清理,不在該被清掉的工作樹上白做工)。 ## 影響的功能 `/sdlc-fix` 多一步,原有五步的內容一字未改,只是編號往後移一號;#14 的七條驗收標準 全部仍然成立。`branch-prep` 行為不變(實作搬家,既有 38 條測試原封通過)。 `lib` 新增四個匯出(`planWorktree`/`createWorktree`/`requireOrigin`,以及既有的 worktree 家族),沒有既有簽章被改。 ## 測試結果 ``` npm test ℹ tests 789 ℹ pass 789 ℹ fail 0 ``` (已 rebase 到含 #52 的 master 之上再跑。) 另外對真實環境驗過一次:把先前刪掉的工作樹重建回同一條路徑,再清掉—— ``` node scripts/worktree-ensure.js --repo plugins/tea-sdlc --path /root/plugins/tea-sdlc \ --branch feat/pr-watch-and-cleanup/main → {"worktree":"/root/.tea-sdlc/worktrees/bd457620184e","動作":"接上本地既有","重建":true} ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jiantw83 added 4 commits 2026-09-17 09:34:43 +00:00
重建工作樹(下一個 commit 的 worktree-ensure)要走的是與開工時完全同一套:一樣先
git fetch 更新遠端引用,一樣不設 upstream,分支已經存在就接上去而不是長一棵空的。
兩邊各寫一份,遲早會在「起點取自哪裡」這種地方分岔——而那種分岔要等到有人的進度
不見了才會被發現。

planWorktree 多接受一種用法:不給來源分支就是「重建既有分支的工作樹」,沒有「從來源
長一支新的」那條路,走到那裡就是 BRANCH_NOT_FOUND。branch-prep 的行為完全不變。

議題 #42

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
處理 PR 留言的人不必先手動 cd 到正確的目錄:路徑由 owner/repo/分支名 純函式推導,
問這一支就知道該在哪裡動手。

「不在就重建」是常態不是防禦性程式設計。進度完全不寫在本機——換一台機器或換一個
agent 接手時,工作樹本來就不存在,而重建的成本就是一次 git worktree add。

兩種情況明確中止而不是硬幹:分支在本機與遠端都不見時報 BRANCH_NOT_FOUND(憑空長一棵
空的工作樹只會讓人以為進度還在),推導出的路徑上是別的東西時報 WORKTREE_PATH_TAKEN。

議題 #42

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
補上 #14 沒有的工作樹概念:它預設在當前目錄處理留言,而留言要改的程式碼在那顆工作包
自己的工作樹裡。新的第一步先問 pr-watch 現況——PR 已經合併或關閉就停下來,在一棵該被
清掉的工作樹上處理留言是白做工——再用 worktree-ensure 定位,不在就重建。

邊界同時擋住兩件事:不回主工作區處理留言(它可能停在別的分支上),以及推導路徑上有
別的東西時不自己刪。原有的五個步驟整體往後移一號,內容不變。

議題 #42

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
review 抓到一個沉默的失效:rollback 最後那一手「git 清不乾淨時把目錄本身也清掉」呼叫
rmSync,但把這段從 branch-prep 搬進 lib 時,import 留在了原處。那一行落在自己的
try/catch 裡,所以 ReferenceError 被吞掉——註解承諾的事從來沒發生過,而且測試全綠。
下一次重跑會撞上 WORKTREE_PATH_TAKEN,人看到的是一句與真正原因無關的錯誤。

順手收掉兩支腳本各寫一次的 origin 檢查(只有「為什麼需要它」那一句不同,由呼叫端給),
並把 lib 檔頭「負責六件事」改成七件——工作樹的一生現在整個住在這裡。

正本三處跟著改:
- 查現況那一行補上 --dry-run。pr-watch 在 PR 已終止時會順手清掉工作樹,而「我想看一下
  留言」不該把清理順便做掉——清不清理是使用者的決定。
- 拿掉「使用者堅持要繼續就繼續」:它與同一份正本的邊界(已合併或關閉時不繼續處理留言)
  直接矛盾,而在一棵該被清掉的工作樹上改東西,那些改動不會進到任何 PR 裡。
- worktree-ensure 的指令補上 --path:目標專案多半不是當前目錄,而「不必先手動 cd」
  正是這一步要解決的問題。

議題 #42

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
admin approved these changes 2026-09-17 09:35:38 +00:00
admin merged commit 1c678d311a into master 2026-09-17 09:35:41 +00:00
admin deleted branch feat/sdlc-fix-worktree/main 2026-09-17 09:35:41 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/tea-sdlc#53