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:
@@ -145,6 +145,7 @@ test('自己碼錶跑在本議題時擋下,要求先手動停錶', async (t) =
|
||||
assert.equal(code, 1);
|
||||
assert.equal(json.error.code, 'STOPWATCH_ON_THIS_ISSUE');
|
||||
assert.match(json.error.message, /停/, '要說清楚下一步是手動停錶');
|
||||
assert.match(json.error.message, /工作樹/, '要明說停錶不會動到既有的工作樹');
|
||||
assert.deepEqual(writes(stub), []);
|
||||
});
|
||||
|
||||
@@ -159,6 +160,11 @@ test('自己碼錶跑在別的議題時擋下,並指出是哪一顆', async (t
|
||||
assert.equal(code, 1);
|
||||
assert.equal(json.error.code, 'STOPWATCH_ON_OTHER_ISSUE');
|
||||
assert.match(json.error.message, /#7/, '忘了停掉的是哪一顆,要指名');
|
||||
assert.match(
|
||||
json.error.message,
|
||||
/停錶只停計時,不會動到任何既有的工作樹/,
|
||||
'以為停錶等於放棄那顆工作包的人會寧可不停,工時就記到別顆去了',
|
||||
);
|
||||
assert.deepEqual(writes(stub), []);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/**
|
||||
* 這一支是唯一直接 import lib 的測試,其餘一律走子行程的 CLI 邊界。
|
||||
* 直接 import lib 的兩支測試之一(另一支是 worktree-path),其餘一律走子行程的 CLI 邊界。
|
||||
*
|
||||
* 理由:冪等查重與 git 執行點是 lib 對「其他腳本」公開的契約,但本工作包只交付
|
||||
* labels-list(讀取型、不碰 git、不需查重),CLI 邊界上還沒有消費者。等 #4 的
|
||||
* issue-create 與 #10 的 branch-prep 落地後,它們的 CLI 測試才是這兩件事的主場,
|
||||
* 屆時這支可以縮小或移除。在那之前直接測 export,好過讓契約完全沒有測試。
|
||||
* 理由:冪等查重與 git 執行點是 lib 對「其他腳本」公開的契約,而 issue-create 與
|
||||
* branch-prep 落地之後,它們的 CLI 測試才是這兩件事的主場——這一支已經是備位的,
|
||||
* 留著是因為直接測 export 仍比讓契約完全沒有測試好。
|
||||
*/
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
@@ -83,6 +83,11 @@ test('兩種擋下來的情境各自寫明處置,且都不替使用者決定',
|
||||
assert.match(phase1, /不要自己刪/, '路徑上的東西可能還沒保存,不該由 agent 決定刪掉');
|
||||
});
|
||||
|
||||
test('被碼錶擋下時要說明停錶不會動到工作樹', () => {
|
||||
assert.match(phase1, /停錶不會動到既有的工作樹/);
|
||||
assert.match(phase1, /以為停錶等於放棄那顆工作包/, '要說明不講清楚的後果');
|
||||
});
|
||||
|
||||
test('碼錶只由使用者自己停,並說明為什麼不代勞', () => {
|
||||
assert.match(phase1, /由使用者自己停/);
|
||||
assert.match(phase1, /工時記錯地方/);
|
||||
|
||||
@@ -96,6 +96,11 @@ test('不代替使用者停錶:訊息要說清楚下一步是他自己去停',
|
||||
const { json } = await run([], stub);
|
||||
|
||||
assert.match(json.error.message, /停/);
|
||||
assert.match(
|
||||
json.error.message,
|
||||
/不會動到任何既有的工作樹/,
|
||||
'碼錶只管時間、工作樹只管檔案;不講清楚,使用者會以為停錶等於放棄那顆工作包',
|
||||
);
|
||||
});
|
||||
|
||||
test('議題不存在時回可區分的錯誤碼', async (t) => {
|
||||
|
||||
Reference in New Issue
Block a user