fix(code): make plan approval primary option match user's prior mode#1909
Conversation
|
| expect(options[0]).toMatchObject({ | ||
| optionId: "default", | ||
| name: "Yes, continue manually approving edits", | ||
| }); | ||
| expect(options[options.length - 1].optionId).toBe("reject_with_feedback"); | ||
| }); | ||
|
|
||
| it("relabels the auto option when it is the previous mode", () => { | ||
| const options = buildExitPlanModePermissionOptions("auto"); | ||
| expect(options[0]).toMatchObject({ | ||
| optionId: "auto", | ||
| name: 'Yes, continue in "auto" mode', | ||
| }); | ||
| }); | ||
|
|
||
| it("relabels the acceptEdits option when it is the previous mode", () => { | ||
| const options = buildExitPlanModePermissionOptions("acceptEdits"); | ||
| expect(options[0]).toMatchObject({ | ||
| optionId: "acceptEdits", | ||
| name: "Yes, continue auto-accepting edits", | ||
| }); | ||
| }); | ||
|
|
||
| it("ignores an unknown previous mode", () => { | ||
| const options = buildExitPlanModePermissionOptions("plan"); | ||
| expect(options[0].name).toMatch(/^Yes, /); | ||
| expect(options[0].name).not.toMatch(/^Yes, continue/); | ||
| expect(options[options.length - 1].optionId).toBe("reject_with_feedback"); | ||
| }); |
There was a problem hiding this comment.
Prefer a parameterised test for mode relabeling cases
The three tests for default, auto, and acceptEdits are structurally identical — call with a previousMode, assert options[0] has the expected optionId and name. Per the team's rule of always preferring parameterised tests, these should be collapsed into one table-driven test:
it.each([
["default", "default", "Yes, continue manually approving edits"],
["auto", "auto", 'Yes, continue in "auto" mode'],
["acceptEdits", "acceptEdits", "Yes, continue auto-accepting edits"],
])(
"promotes %s to the first position with the correct continue label",
(previousMode, expectedId, expectedName) => {
const options = buildExitPlanModePermissionOptions(previousMode);
expect(options[0]).toMatchObject({ optionId: expectedId, name: expectedName });
expect(options[options.length - 1].optionId).toBe("reject_with_feedback");
},
);This also folds in the "reject option is always last" assertion, making the coverage obvious at a glance.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/agent/src/adapters/claude/permissions/permission-options.test.ts
Line: 15-43
Comment:
**Prefer a parameterised test for mode relabeling cases**
The three tests for `default`, `auto`, and `acceptEdits` are structurally identical — call with a `previousMode`, assert `options[0]` has the expected `optionId` and `name`. Per the team's rule of always preferring parameterised tests, these should be collapsed into one table-driven test:
```typescript
it.each([
["default", "default", "Yes, continue manually approving edits"],
["auto", "auto", 'Yes, continue in "auto" mode'],
["acceptEdits", "acceptEdits", "Yes, continue auto-accepting edits"],
])(
"promotes %s to the first position with the correct continue label",
(previousMode, expectedId, expectedName) => {
const options = buildExitPlanModePermissionOptions(previousMode);
expect(options[0]).toMatchObject({ optionId: expectedId, name: expectedName });
expect(options[options.length - 1].optionId).toBe("reject_with_feedback");
},
);
```
This also folds in the "reject option is always last" assertion, making the coverage obvious at a glance.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
adboio
left a comment
There was a problem hiding this comment.
approving to unblock but i do have a "strong opinion, loosely held" here that i think it's a better UX to have the options always sorted the same way instead of re-sorting every time one is chosen
personally i flip back and forth between the options pretty regularly and this would be mildly frustrating for me
can we check some data to see if that's common, or if users do typically just stick with one option all the time to assess the impact (i.e. would we be getting a net reduction of user inputs)?
| expect(options[0]).toMatchObject({ | ||
| optionId: "default", | ||
| name: "Yes, continue manually approving edits", | ||
| }); | ||
| expect(options[options.length - 1].optionId).toBe("reject_with_feedback"); | ||
| }); | ||
|
|
||
| it("relabels the auto option when it is the previous mode", () => { | ||
| const options = buildExitPlanModePermissionOptions("auto"); | ||
| expect(options[0]).toMatchObject({ | ||
| optionId: "auto", | ||
| name: 'Yes, continue in "auto" mode', | ||
| }); | ||
| }); | ||
|
|
||
| it("relabels the acceptEdits option when it is the previous mode", () => { | ||
| const options = buildExitPlanModePermissionOptions("acceptEdits"); | ||
| expect(options[0]).toMatchObject({ | ||
| optionId: "acceptEdits", | ||
| name: "Yes, continue auto-accepting edits", | ||
| }); | ||
| }); | ||
|
|
||
| it("ignores an unknown previous mode", () => { | ||
| const options = buildExitPlanModePermissionOptions("plan"); | ||
| expect(options[0].name).toMatch(/^Yes, /); | ||
| expect(options[0].name).not.toMatch(/^Yes, continue/); | ||
| expect(options[options.length - 1].optionId).toBe("reject_with_feedback"); | ||
| }); |
c67bb56 to
271ba9c
Compare
f004c1c to
fb0d5fe
Compare
Merge activity
|
fb0d5fe to
c904c1b
Compare
271ba9c to
1640b9e
Compare
When the agent exits plan mode, the dialog now promotes the mode the user was in before plan mode to the top of the option list and labels it "Yes, continue ..." so the natural choice is to resume the prior mode rather than picking from a flat list. Generated-By: PostHog Code Task-Id: 8845a96b-6bc0-42f8-9a9f-c9d572a7b29d
1640b9e to
a0d41ef
Compare

Problem
Changes
How did you test this?