Skip to content

Commit 22a5bc1

Browse files
committed
PR feedback
1 parent 8d8d4fb commit 22a5bc1

5 files changed

Lines changed: 80 additions & 51 deletions

File tree

code/lib/create-storybook/src/commands/FinalizationCommand.test.ts

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ describe('FinalizationCommand', () => {
1818
let command: FinalizationCommand;
1919

2020
beforeEach(() => {
21-
command = new FinalizationCommand(undefined, false, false, false);
21+
command = new FinalizationCommand({
22+
logfile: undefined,
23+
showAgentFollowUp: false,
24+
showAiInstructions: false,
25+
});
2226

2327
vi.mocked(getProjectRoot).mockReturnValue('/test/project');
2428
vi.mocked(logger.step).mockImplementation(() => {});
@@ -109,8 +113,12 @@ describe('FinalizationCommand', () => {
109113
});
110114

111115
describe('agent mode', () => {
112-
it('should show agent-specific message when agent=true and ai prepare is supported', async () => {
113-
const agentCommand = new FinalizationCommand(undefined, true, true, false);
116+
it('should show agent-specific message when showAgentFollowUp=true', async () => {
117+
const agentCommand = new FinalizationCommand({
118+
logfile: undefined,
119+
showAgentFollowUp: true,
120+
showAiInstructions: false,
121+
});
114122
vi.mocked(find.up).mockReturnValue(undefined);
115123

116124
await agentCommand.execute({});
@@ -120,8 +128,13 @@ describe('FinalizationCommand', () => {
120128
);
121129
expect(logger.step).toHaveBeenCalledWith(expect.stringContaining('npx storybook ai prepare'));
122130
});
123-
it('should show standard success message when agent=true and ai prepare is NOT supported', async () => {
124-
const agentCommand = new FinalizationCommand(undefined, true, false, true);
131+
132+
it('should show standard success message when showAgentFollowUp=false with AI instructions', async () => {
133+
const agentCommand = new FinalizationCommand({
134+
logfile: undefined,
135+
showAgentFollowUp: false,
136+
showAiInstructions: true,
137+
});
125138
vi.mocked(find.up).mockReturnValue(undefined);
126139

127140
await agentCommand.execute({});
@@ -134,8 +147,12 @@ describe('FinalizationCommand', () => {
134147
expect(stepCalls.some((msg) => msg.includes('is not entirely set up yet'))).toBe(false);
135148
});
136149

137-
it('should show standard success message when agent=false', async () => {
138-
const nonAgentCommand = new FinalizationCommand(undefined, false, false, false);
150+
it('should show standard success message when showAgentFollowUp=false', async () => {
151+
const nonAgentCommand = new FinalizationCommand({
152+
logfile: undefined,
153+
showAgentFollowUp: false,
154+
showAiInstructions: false,
155+
});
139156
vi.mocked(find.up).mockReturnValue(undefined);
140157

141158
await nonAgentCommand.execute({});
@@ -151,7 +168,11 @@ describe('FinalizationCommand', () => {
151168

152169
describe('AI instructions', () => {
153170
it('should show AI instructions when showAiInstructions=true', async () => {
154-
const aiCommand = new FinalizationCommand(undefined, false, true, true);
171+
const aiCommand = new FinalizationCommand({
172+
logfile: undefined,
173+
showAgentFollowUp: false,
174+
showAiInstructions: true,
175+
});
155176
vi.mocked(find.up).mockReturnValue(undefined);
156177

157178
await aiCommand.execute({});
@@ -163,7 +184,11 @@ describe('FinalizationCommand', () => {
163184
});
164185

165186
it('should NOT show AI instructions when showAiInstructions=false', async () => {
166-
const noAiCommand = new FinalizationCommand(undefined, false, false, false);
187+
const noAiCommand = new FinalizationCommand({
188+
logfile: undefined,
189+
showAgentFollowUp: false,
190+
showAiInstructions: false,
191+
});
167192
vi.mocked(find.up).mockReturnValue(undefined);
168193

169194
await noAiCommand.execute({});
@@ -173,7 +198,11 @@ describe('FinalizationCommand', () => {
173198
});
174199

175200
it('should show both agent message and AI instructions when both are true', async () => {
176-
const bothCommand = new FinalizationCommand(undefined, true, true, true);
201+
const bothCommand = new FinalizationCommand({
202+
logfile: undefined,
203+
showAgentFollowUp: true,
204+
showAiInstructions: true,
205+
});
177206
vi.mocked(find.up).mockReturnValue(undefined);
178207

179208
await bothCommand.execute({});
@@ -189,7 +218,11 @@ describe('FinalizationCommand', () => {
189218

190219
describe('storybookCommand message', () => {
191220
it('should print "To run Storybook, run" with the command', async () => {
192-
const cmd = new FinalizationCommand(undefined, false, false, false);
221+
const cmd = new FinalizationCommand({
222+
logfile: undefined,
223+
showAgentFollowUp: false,
224+
showAiInstructions: false,
225+
});
193226
vi.mocked(find.up).mockReturnValue(undefined);
194227

195228
await cmd.execute({ storybookCommand: 'npm run storybook' });
@@ -199,7 +232,11 @@ describe('FinalizationCommand', () => {
199232
});
200233

201234
it('should not print storybook command message when storybookCommand is null', async () => {
202-
const cmd = new FinalizationCommand(undefined, false, false, false);
235+
const cmd = new FinalizationCommand({
236+
logfile: undefined,
237+
showAgentFollowUp: false,
238+
showAiInstructions: false,
239+
});
203240
vi.mocked(find.up).mockReturnValue(undefined);
204241

205242
await cmd.execute({ storybookCommand: null });
@@ -210,13 +247,12 @@ describe('FinalizationCommand', () => {
210247
});
211248

212249
describe('executeFinalization helper', () => {
213-
it('should pass agent and showAiInstructions to FinalizationCommand', async () => {
250+
it('should show agent follow-up when showAgentFollowUp=true', async () => {
214251
vi.mocked(find.up).mockReturnValue(undefined);
215252

216253
await executeFinalization({
217-
agent: true,
254+
showAgentFollowUp: true,
218255
showAiInstructions: false,
219-
isAiPrepareAvailable: true,
220256
logfile: undefined,
221257
});
222258

@@ -230,9 +266,8 @@ describe('FinalizationCommand', () => {
230266
vi.mocked(find.up).mockReturnValue(undefined);
231267

232268
await executeFinalization({
233-
agent: false,
269+
showAgentFollowUp: false,
234270
showAiInstructions: true,
235-
isAiPrepareAvailable: false,
236271
logfile: undefined,
237272
});
238273

@@ -245,9 +280,8 @@ describe('FinalizationCommand', () => {
245280
vi.mocked(find.up).mockReturnValue(undefined);
246281

247282
await executeFinalization({
248-
agent: false,
283+
showAgentFollowUp: false,
249284
showAiInstructions: false,
250-
isAiPrepareAvailable: false,
251285
logfile: undefined,
252286
storybookCommand: 'yarn storybook',
253287
});

code/lib/create-storybook/src/commands/FinalizationCommand.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import { ErrorCollector } from 'storybook/internal/telemetry';
77
import * as find from 'empathic/find';
88
import { dedent } from 'ts-dedent';
99

10+
export type FinalizationCommandOptions = {
11+
logfile: string | boolean | undefined;
12+
/** When true, show the agent follow-up message ("run npx storybook ai prepare") instead of the normal success message */
13+
showAgentFollowUp: boolean;
14+
/** When true, show the "paste this prompt to your AI agent" instructions */
15+
showAiInstructions: boolean;
16+
};
17+
1018
type ExecuteFinalizationParams = {
1119
storybookCommand?: string | null;
1220
};
@@ -22,12 +30,8 @@ type ExecuteFinalizationParams = {
2230
* - Show next steps
2331
*/
2432
export class FinalizationCommand {
25-
constructor(
26-
private logfile: string | boolean | undefined,
27-
private agent: boolean,
28-
private isAiPrepareAvailable: boolean,
29-
private showAiInstructions: boolean
30-
) {}
33+
constructor(private options: FinalizationCommandOptions) {}
34+
3135
/** Execute finalization steps */
3236
async execute({ storybookCommand }: ExecuteFinalizationParams): Promise<void> {
3337
// Update .gitignore
@@ -74,14 +78,14 @@ export class FinalizationCommand {
7478
this.printNextSteps(storybookCommand);
7579

7680
try {
77-
const logFile = await logTracker.writeToFile(this.logfile);
81+
const logFile = await logTracker.writeToFile(this.options.logfile);
7882
logger.warn(`Debug logs are written to: ${logFile}`);
7983
} catch {}
8084
}
8185

8286
/** Print success message with feature summary */
8387
private printSuccessMessage(storybookCommand?: string | null): void {
84-
if (this.agent && this.isAiPrepareAvailable) {
88+
if (this.options.showAgentFollowUp) {
8589
logger.step(
8690
CLI_COLORS.storybook(
8791
dedent`Storybook is installed but is not entirely set up yet.
@@ -104,27 +108,22 @@ export class FinalizationCommand {
104108
Having trouble or want to chat? ${CLI_COLORS.cta('https://discord.gg/storybook/')}
105109
`);
106110

107-
if (this.showAiInstructions) {
111+
if (this.options.showAiInstructions) {
108112
logger.step(dedent`To finalize setting up with AI, paste this prompt to your AI agent:
109113
110114
${CLI_COLORS.storybook(`Run \`npx storybook ai prepare\` and follow its instructions precisely.`)}
111115
`);
112116
}
113117
}
114118
}
119+
115120
export const executeFinalization = ({
116-
agent,
117121
logfile,
118-
isAiPrepareAvailable,
122+
showAgentFollowUp,
119123
showAiInstructions,
120124
...params
121-
}: ExecuteFinalizationParams & {
122-
agent: boolean;
123-
showAiInstructions: boolean;
124-
isAiPrepareAvailable: boolean;
125-
logfile: string | boolean | undefined;
126-
}) => {
127-
return new FinalizationCommand(logfile, agent, isAiPrepareAvailable, showAiInstructions).execute(
125+
}: ExecuteFinalizationParams & FinalizationCommandOptions) => {
126+
return new FinalizationCommand({ logfile, showAgentFollowUp, showAiInstructions }).execute(
128127
params
129128
);
130129
};

code/lib/create-storybook/src/commands/UserPreferencesCommand.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ describe('UserPreferencesCommand', () => {
231231
expect(prompt.confirm).toHaveBeenCalledWith(
232232
expect.objectContaining({
233233
message: expect.stringContaining(
234-
'Would you like to improve your Storybook setup with AI?'
234+
'Would you like to install AI features (MCP addon, skills and prompt suggestions)?'
235235
),
236236
})
237237
);

code/lib/create-storybook/src/commands/UserPreferencesCommand.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,12 @@ export class UserPreferencesCommand {
220220

221221
/** Prompt user about AI-assisted Storybook setup */
222222
private async promptAiSetup(skipPrompt: boolean): Promise<boolean> {
223-
let useAi: boolean;
224-
225-
if (skipPrompt) {
226-
useAi = true;
227-
} else {
228-
useAi = await prompt.confirm({
229-
message: dedent`Would you like to improve your Storybook setup with AI?
230-
We will install dependencies and give you a prompt to set up a Storybook that follows best practices, with content tailored to your project.`,
231-
});
232-
}
223+
const useAi = skipPrompt
224+
? true
225+
: await prompt.confirm({
226+
message:
227+
'Would you like to install AI features (MCP addon, skills and prompt suggestions)?',
228+
});
233229

234230
if (useAi) {
235231
await this.telemetryService.trackAiPromptNudge({ skipPrompt });

code/lib/create-storybook/src/initiate.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ export async function doInitiate(options: CommandOptions): Promise<
147147
});
148148

149149
// Step 8: Print final summary
150+
const hasAiFeature = selectedFeatures.has(Feature.AI);
150151
await executeFinalization({
151-
agent: !!options.agent,
152-
isAiPrepareAvailable,
153-
showAiInstructions: selectedFeatures.has(Feature.AI),
152+
showAgentFollowUp: !!options.agent && hasAiFeature,
153+
showAiInstructions: hasAiFeature,
154154
logfile: options.logfile,
155155
storybookCommand,
156156
});

0 commit comments

Comments
 (0)