Skip to content

Commit 2d2f74a

Browse files
committed
fix: show model save scope selector only on confirmation page
1 parent faeb475 commit 2d2f74a

4 files changed

Lines changed: 32 additions & 14 deletions

File tree

‎packages/cli/src/tests/models-dropdown.test.ts‎

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ test("model dropdown offers all reasoning effort levels", () => {
6464
assert.equal(getThinkingOptionIndex({ thinkingEnabled: true, reasoningEffort: "low" }), 2);
6565
});
6666

67-
test("model scope selector is gray, retains the model cursor and carries the destination to thinking confirmation", async (t) => {
67+
test("model scope selector is only active on thinking confirmation and retains the thinking cursor", async (t) => {
6868
const inkRequire = createRequire(createRequire(import.meta.url).resolve("ink"));
6969
const { default: chalk } = await import(pathToFileURL(inkRequire.resolve("chalk")).href);
7070
const level = chalk.level;
@@ -73,29 +73,38 @@ test("model scope selector is gray, retains the model cursor and carries the des
7373
chalk.level = level;
7474
});
7575
const h = await editor(t, true);
76+
assert.doesNotMatch(h.frame(), /Remember this choice|All Projects|This Project/);
77+
await h.send(DOWN);
78+
await h.send(LEFT); // Scope cannot change while hidden.
79+
assert.match(h.frame(), /> ○ deepseek-v4-pro/);
80+
assert.deepEqual(h.saves, []);
81+
await h.send(ENTER);
82+
assert.match(h.frame(), /Select Thinking Mode/);
7683
assert.match(h.frame(), /All Projects +\[This Project\]/);
7784
assert.match(h.rawFrame(), /\u001b\[90mRemember this choice for {2}\(←→ to switch\)/);
78-
assert.ok(h.frame().indexOf("Remember this choice") < h.frame().indexOf("Space/Enter select model"));
85+
assert.ok(h.frame().indexOf("Remember this choice") < h.frame().indexOf("Space/Enter apply"));
7986
await h.send(DOWN);
8087
await h.send(LEFT);
8188
assert.match(h.frame(), /\[All Projects\] +This Project/);
82-
assert.match(h.frame(), /> ○ deepseek-v4-pro/);
89+
assert.match(h.frame(), /> ○ Thinking mode \[low\]/);
90+
await h.send(RIGHT);
91+
assert.match(h.frame(), /All Projects +\[This Project\]/);
92+
assert.match(h.frame(), /> ○ Thinking mode \[low\]/);
93+
await h.send(LEFT);
8394
await h.send(LEFT);
8495
assert.match(h.frame(), /\[All Projects\]/);
8596
assert.deepEqual(h.saves, []);
8697
await h.send(ENTER);
87-
assert.match(h.frame(), /Select Thinking Mode/);
88-
assert.doesNotMatch(h.frame(), /Remember this choice/);
89-
await h.send(RIGHT); // Scope cannot change while hidden.
90-
await h.send(DOWN);
91-
await h.send(ENTER);
9298
assert.deepEqual(h.saves, [
9399
{ selection: { model: "deepseek-v4-pro", thinkingEnabled: true, reasoningEffort: "low" }, target: "user" },
94100
]);
95101
});
96102

97103
test("missing project settings default to all projects and cancellation saves nothing", async (t) => {
98104
const h = await editor(t, false, 36);
105+
assert.doesNotMatch(h.frame(), /Remember this choice|All Projects|This Project/);
106+
await h.send(RIGHT); // Scope cannot change while hidden.
107+
await h.send(ENTER);
99108
assert.match(h.frame(), /\[All Projects\] +This Project/);
100109
// The shared scope control must fit inside the narrow dialog.
101110
const scopeLines = h
@@ -112,8 +121,8 @@ test("missing project settings default to all projects and cancellation saves no
112121

113122
test("reopening recomputes the default destination and thinking cancellation does not save", async (t) => {
114123
const h = await editor(t);
115-
await h.send(RIGHT);
116124
await h.send(ENTER);
125+
await h.send(RIGHT);
117126
await h.send(ESC);
118127
assert.deepEqual(h.saves, []);
119128
h.rerender(React.createElement(Text, null, "closed"));
@@ -122,8 +131,9 @@ test("reopening recomputes the default destination and thinking cancellation doe
122131
fs.writeFileSync(h.projectFile, "{}");
123132
h.rerender(React.createElement(h.Probe));
124133
await h.send("");
125-
assert.match(h.frame(), /All Projects +\[This Project\]/);
134+
assert.doesNotMatch(h.frame(), /Remember this choice|All Projects|This Project/);
126135
await h.send(ENTER);
136+
assert.match(h.frame(), /All Projects +\[This Project\]/);
127137
await h.send(ENTER);
128138
assert.deepEqual(h.saves, [{ selection: current, target: "project" }]);
129139
});

‎packages/cli/src/tests/permissions-dropdown.test.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,17 @@ test("default mode returns home with a draft and saves only from home", async (t
6969
assert.match(h.frame(), /> defaultMode +askAll/);
7070
assert.match(h.frame(), /scopes +│/);
7171
assert.match(h.frame(), /Save +│/);
72+
assert.match(h.frame(), /Remember this choice/);
7273
assert.doesNotMatch(h.frame(), /Tab/);
7374
await h.send(ENTER);
75+
assert.doesNotMatch(h.frame(), /Remember this choice/);
7476
assert.match(h.frame(), /> ● askAll/);
7577
assert.match(h.frame(), /askAll +│/);
7678
assert.match(h.frame(), /allowAll +│/);
7779
await h.send(DOWN);
7880
await h.send(" ");
7981
assert.match(h.frame(), /Permissions · User/);
82+
assert.match(h.frame(), /Remember this choice/);
8083
assert.match(h.frame(), /> defaultMode +allowAll/);
8184
assert.deepEqual(h.saves, []);
8285
assert.equal(h.closed(), 0);
@@ -95,7 +98,9 @@ test("scope edits accumulate, preserve list position and save only after Save",
9598
await h.send(DOWN);
9699
await h.send(ENTER);
97100
assert.doesNotMatch(h.frame(), /Save/);
101+
assert.doesNotMatch(h.frame(), /Remember this choice/);
98102
await h.send(ENTER);
103+
assert.doesNotMatch(h.frame(), /Remember this choice/);
99104
assert.match(h.frame(), /> ● default/);
100105
await h.send(DOWN); // wrap from default to allow
101106
await h.send(ENTER);
@@ -108,6 +113,7 @@ test("scope edits accumulate, preserve list position and save only after Save",
108113
assert.match(h.frame(), /> read-in-tmp/);
109114
assert.deepEqual(h.saves, []);
110115
await h.send(ESC); // home retains the draft
116+
assert.match(h.frame(), /Remember this choice/);
111117
await h.send(DOWN);
112118
assert.match(h.frame(), /> Save/);
113119
await h.send(ENTER);
@@ -448,10 +454,11 @@ test("slash command opens the editor, persists settings, and isolates menu keys
448454
assert.equal(planModeChanges, 0);
449455
await h.send("/model");
450456
await h.send(ENTER);
457+
assert.doesNotMatch(h.frame(), /Remember this choice|All Projects|This Project/);
458+
await h.send(ENTER);
451459
assert.match(h.frame(), /All Projects +\[This Project\]/);
452460
await h.send(LEFT);
453461
await h.send(ENTER);
454-
await h.send(ENTER);
455462
assert.deepEqual(modelSaves, [
456463
{ selection: { model: "deepseek-flash", thinkingEnabled: false, reasoningEffort: "high" }, target: "user" },
457464
]);

‎packages/cli/src/tests/settings-file.test.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ for (const hasProject of [true, false]) {
5959
assert.match(h.frame(), /deepseek-v4-pro/);
6060
await h.send("/model");
6161
await h.send("\r");
62-
assert.match(h.frame(), hasProject ? /All Projects +\[This Project\]/ : /\[All Projects\] +This Project/);
62+
assert.doesNotMatch(h.frame(), /Remember this choice|All Projects|This Project/);
6363
await h.send("\u001b[A"); // Select the preceding model (deepseek-flash).
6464
await h.send("\r");
65+
assert.match(h.frame(), hasProject ? /All Projects +\[This Project\]/ : /\[All Projects\] +This Project/);
6566
await h.send("\r");
6667
const targetFile = hasProject ? projectFile : userFile;
6768
assert.equal(JSON.parse(fs.readFileSync(targetFile, "utf8")).model, "deepseek-flash");

‎packages/cli/src/ui/components/ModelsDropdown/index.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ const ModelsDropdown: React.FC<Props> = ({
126126

127127
const optionCount = step === "model" ? MODEL_COMMAND_MODELS.length : MODEL_COMMAND_THINKING_OPTIONS.length;
128128

129-
if (step === "model" && !key.ctrl && !key.meta && !key.shift && (key.leftArrow || key.rightArrow)) {
129+
if (step === "thinking" && !key.ctrl && !key.meta && !key.shift && (key.leftArrow || key.rightArrow)) {
130130
setTarget(key.leftArrow ? "user" : "project");
131131
return;
132132
}
@@ -178,7 +178,7 @@ const ModelsDropdown: React.FC<Props> = ({
178178
activeIndex={activeIndex}
179179
activeColor="#229ac3"
180180
maxVisible={6}
181-
footer={step === "model" ? <SaveScopeSelector target={target} /> : undefined}
181+
footer={step === "thinking" ? <SaveScopeSelector target={target} /> : undefined}
182182
/>
183183
);
184184
};

0 commit comments

Comments
 (0)