Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-multi-select-other-deselect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

Fix multi-select "Other" options so they can be deselected after being committed.
6 changes: 6 additions & 0 deletions apps/kimi-code/src/tui/components/dialogs/question-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ export class QuestionDialogComponent extends Container implements Focusable {
this.reviewMessage = undefined;

if (this.isOtherOption(questionIdx, optionIdx)) {
if (question.multi_select && this.multiSelections[questionIdx]?.has(optionIdx)) {
this.multiSelections[questionIdx].delete(optionIdx);
this.lastAnswerMethod = method;
this.updateAnswer(questionIdx);
return;
}
this.enterOtherInput(questionIdx);
return;
}
Expand Down
36 changes: 36 additions & 0 deletions apps/kimi-code/test/tui/components/dialogs/question-dialog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,42 @@ describe('QuestionDialogComponent', () => {
expect(out).toContain('Mushroom');
});

it('multi-select Other can be toggled off after it is committed', () => {
const pending = makePending([
{
question: 'Pick toppings?',
multi_select: true,
options: [{ label: 'Cheese' }, { label: 'Pepperoni' }],
},
]);
const { dialog, collected } = makeDialog(pending);

// Select Other and commit a custom value.
dialog.handleInput('3');
dialog.handleInput('M');
dialog.handleInput('u');
dialog.handleInput('s');
dialog.handleInput('h');
dialog.handleInput('r');
dialog.handleInput('o');
dialog.handleInput('o');
dialog.handleInput('m');
dialog.handleInput('\r');

// Toggle it off using the same key.
dialog.handleInput('3');
// Select a preset option to confirm the answer still builds correctly.
dialog.handleInput('1');
dialog.handleInput('\t');

const review = strip(dialog.render(80).join('\n'));
expect(review).toContain('Cheese');
expect(review).not.toContain('Mushroom');

dialog.handleInput('1');
expect(collected).toEqual([['Cheese']]);
});

it('escape dismisses with empty answers array', () => {
const pending = makePending([
{
Expand Down
Loading