fix(claim): 被碼錶擋下時明說停錶不會動到既有的工作樹

議題 #38 的使用者故事第 30 條:使用者常以為停錶等於放棄那顆工作包,於是寧可
不停——工時就記到別顆議題去了。碼錶只管時間、工作樹只管檔案,兩者互不相干,
這件事要在擋下來的當下就講,不能指望使用者自己推論。

領取與起錶會撞到同一個擋路理由,訊息收進 lib 只寫一份。順手收掉 review 指出的
三處:planWorktree 沒用到的 repo 參數、與 path.resolve 同名而誤導的區域函式、
以及只有 lib 自己用得到卻對外 export 的兩支路徑函式。

回滾補上最後一道:git 清不掉時把目錄本身也刪掉。那條路徑在這次執行之前不存在
(不存在正是建立的前提),裡面不可能有使用者的東西,而留著它下一次重跑會直接
撞上 WORKTREE_PATH_TAKEN——一次失敗的建立不該讓人從此開不了工。

議題 #40

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 16:29:12 +08:00
co-authored by Claude Opus 5
parent 4583a5f210
commit 0154cf59d4
9 changed files with 65 additions and 36 deletions
+23 -9
View File
@@ -53,16 +53,13 @@ export function promptsDir() {
}
/**
* tea-sdlc 在使用者家目錄底下的家。工作樹集中放在這裡,清理時只有一個地方要看。
* `TEA_SDLC_HOME` 只是測試與 CI 的覆寫出口,正常使用不必設。
* 所有工作樹的集中處:`~/.tea-sdlc/worktrees`。
* 集中在一個地方,清理時只有一處要看。`TEA_SDLC_HOME` 只是測試與 CI 的覆寫出口,
* 正常使用不必設。
*/
export function teaSdlcHome() {
return process.env.TEA_SDLC_HOME?.trim() || join(homedir(), '.tea-sdlc');
}
/** 所有工作樹的集中處 */
export function worktreesRoot() {
return join(teaSdlcHome(), 'worktrees');
function worktreesRoot() {
const home = process.env.TEA_SDLC_HOME?.trim() || join(homedir(), '.tea-sdlc');
return join(home, 'worktrees');
}
/**
@@ -669,6 +666,23 @@ export async function listStopwatches(login) {
return expectOk(await giteaRequest(login, 'GET', path), `GET ${path}`) ?? [];
}
/**
* 「你的錶正跑在別顆議題上」的擋路錯誤。領取與起錶都會撞到它,訊息只寫一份。
*
* 一定要明說停錶不會動到工作樹:使用者常以為停錶等於放棄那顆工作包,於是寧可不停,
* 而工時就記到別顆議題去了。碼錶只管時間,工作樹只管檔案,兩者互不相干。
* @param {object} watch listStopwatches 裡的一顆錶
* @param {string} 動作 擋在哪件事之前,例如「領取」「起錶」
*/
export function stopwatchElsewhere(watch, 動作) {
return new ScriptError(
'STOPWATCH_ON_OTHER_ISSUE',
`你的碼錶正跑在 ${watch.repo_owner_name}/${watch.repo_name} 的議題 ` +
`#${watch.issue_index} 上,${動作}前請先手動停錶,否則工時會記到那一顆去;` +
'停錶只停計時,不會動到任何既有的工作樹',
);
}
/**
* 這些碼錶裡,跑在指定議題上的那一顆。
* 比對要連 repo 一起看:不同 repo 的同號議題是兩件事。