Skip to content

Commit 51def64

Browse files
committed
fix: Consolidate agent instructions. (#1340)
The current agent instructions prompt is focused on agent names rather than files, which leaves the door open for people to add coding agents to Vite+'s list as a marketing channel. This PR changes the prompt to focus on the files that are being created, and only mentions a few of the widely known agents.
1 parent 9e35163 commit 51def64

File tree

8 files changed

+115
-39
lines changed

8 files changed

+115
-39
lines changed

packages/cli/snap-tests-global/command-create-help/snap.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Arguments:
1414

1515
Options:
1616
--directory DIR Target directory for the generated project.
17-
--agent NAME Create an agent instructions file for the specified agent.
17+
--agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.
1818
--editor NAME Write editor config files for the specified editor.
1919
--hooks Set up pre-commit hooks (default in non-interactive mode)
2020
--no-hooks Skip pre-commit hooks setup
@@ -70,7 +70,7 @@ Arguments:
7070

7171
Options:
7272
--directory DIR Target directory for the generated project.
73-
--agent NAME Create an agent instructions file for the specified agent.
73+
--agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.
7474
--editor NAME Write editor config files for the specified editor.
7575
--hooks Set up pre-commit hooks (default in non-interactive mode)
7676
--no-hooks Skip pre-commit hooks setup
@@ -126,7 +126,7 @@ Arguments:
126126

127127
Options:
128128
--directory DIR Target directory for the generated project.
129-
--agent NAME Create an agent instructions file for the specified agent.
129+
--agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.
130130
--editor NAME Write editor config files for the specified editor.
131131
--hooks Set up pre-commit hooks (default in non-interactive mode)
132132
--no-hooks Skip pre-commit hooks setup

packages/cli/snap-tests-global/migration-check/snap.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Arguments:
99
PATH Target directory to migrate (default: current directory)
1010

1111
Options:
12-
--agent NAME Write agent instructions file into the project (e.g. chatgpt, claude, opencode).
13-
--no-agent Skip writing agent instructions file
12+
--agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.
13+
--no-agent Skip writing coding agent instructions
1414
--editor NAME Write editor config files into the project.
1515
--no-editor Skip writing editor config files
1616
--hooks Set up pre-commit hooks (default in non-interactive mode)

packages/cli/snap-tests-global/migration-lintstagedrc-json/snap.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Arguments:
99
PATH Target directory to migrate (default: current directory)
1010

1111
Options:
12-
--agent NAME Write agent instructions file into the project (e.g. chatgpt, claude, opencode).
13-
--no-agent Skip writing agent instructions file
12+
--agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.
13+
--no-agent Skip writing coding agent instructions
1414
--editor NAME Write editor config files into the project.
1515
--no-editor Skip writing editor config files
1616
--hooks Set up pre-commit hooks (default in non-interactive mode)

packages/cli/snap-tests-global/new-check/snap.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Arguments:
1414

1515
Options:
1616
--directory DIR Target directory for the generated project.
17-
--agent NAME Create an agent instructions file for the specified agent.
17+
--agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.
1818
--editor NAME Write editor config files for the specified editor.
1919
--hooks Set up pre-commit hooks (default in non-interactive mode)
2020
--no-hooks Skip pre-commit hooks setup

packages/cli/src/create/bin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const helpMessage = renderCliDoc({
8080
{ label: '--directory DIR', description: 'Target directory for the generated project.' },
8181
{
8282
label: '--agent NAME',
83-
description: 'Create an agent instructions file for the specified agent.',
83+
description: 'Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.',
8484
},
8585
{
8686
label: '--editor NAME',

packages/cli/src/migration/bin.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,9 @@ const helpMessage = renderCliDoc({
224224
rows: [
225225
{
226226
label: '--agent NAME',
227-
description:
228-
'Write agent instructions file into the project (e.g. chatgpt, claude, opencode).',
227+
description: 'Write coding agent instructions to AGENTS.md, CLAUDE.md, etc.',
229228
},
230-
{ label: '--no-agent', description: 'Skip writing agent instructions file' },
229+
{ label: '--no-agent', description: 'Skip writing coding agent instructions' },
231230
{
232231
label: '--editor NAME',
233232
description: 'Write editor config files into the project.',

packages/cli/src/utils/__tests__/agent.spec.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
hasExistingAgentInstructions,
1212
replaceMarkedAgentInstructionsSection,
1313
resolveAgentTargetPaths,
14+
selectAgentTargetPaths,
1415
writeAgentInstructions,
1516
} from '../agent.js';
1617
import { pkgRoot } from '../path.js';
@@ -252,13 +253,19 @@ async function createProjectDir() {
252253
}
253254

254255
describe('resolveAgentTargetPaths', () => {
255-
it('resolves comma-separated agent names and deduplicates target paths', () => {
256+
it('resolves legacy agent names and deduplicates target paths', () => {
256257
expect(resolveAgentTargetPaths('claude,amp,opencode,chatgpt')).toEqual([
257258
'CLAUDE.md',
258259
'AGENTS.md',
259260
]);
260261
});
261262

263+
it('resolves file names directly', () => {
264+
expect(
265+
resolveAgentTargetPaths(['AGENTS.md', 'CLAUDE.md', '.github/copilot-instructions.md']),
266+
).toEqual(['AGENTS.md', 'CLAUDE.md', '.github/copilot-instructions.md']);
267+
});
268+
262269
it('resolves repeated --agent values and trims whitespace', () => {
263270
expect(resolveAgentTargetPaths([' claude ', ' amp, opencode ', 'codex'])).toEqual([
264271
'CLAUDE.md',
@@ -272,6 +279,40 @@ describe('resolveAgentTargetPaths', () => {
272279
});
273280
});
274281

282+
describe('selectAgentTargetPaths', () => {
283+
it('prompts with file-based targets and agent hints', async () => {
284+
const multiselectSpy = vi.spyOn(prompts, 'multiselect').mockResolvedValue(['agents', 'claude']);
285+
286+
await expect(
287+
selectAgentTargetPaths({
288+
interactive: true,
289+
onCancel: vi.fn(),
290+
}),
291+
).resolves.toEqual(['AGENTS.md', 'CLAUDE.md']);
292+
293+
expect(multiselectSpy).toHaveBeenCalledWith(
294+
expect.objectContaining({
295+
message: expect.stringContaining(
296+
'Which coding agent instruction files should Vite+ create?',
297+
),
298+
initialValues: ['agents'],
299+
options: expect.arrayContaining([
300+
expect.objectContaining({
301+
label: 'AGENTS.md',
302+
value: 'agents',
303+
hint: expect.stringContaining('Codex'),
304+
}),
305+
expect.objectContaining({
306+
label: 'CLAUDE.md',
307+
value: 'claude',
308+
hint: 'Claude Code',
309+
}),
310+
]),
311+
}),
312+
);
313+
});
314+
});
315+
275316
describe('detectExistingAgentTargetPath', () => {
276317
it('detects all existing regular agent files', async () => {
277318
const dir = await createProjectDir();

packages/cli/src/utils/agent.ts

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -164,37 +164,75 @@ export function detectAgents(root: string): AgentConfig[] {
164164

165165
// --- Backward-compatible exports ---
166166

167-
const AGENT_ALIASES: Record<string, string> = {
168-
chatgpt: 'chatgpt-codex',
169-
codex: 'chatgpt-codex',
170-
};
171-
172167
export const AGENTS = [
173-
{ id: 'chatgpt-codex', label: 'ChatGPT (Codex)', targetPath: 'AGENTS.md' },
174-
{ id: 'claude', label: 'Claude Code', targetPath: 'CLAUDE.md' },
175-
{ id: 'gemini', label: 'Gemini CLI', targetPath: 'GEMINI.md' },
168+
{
169+
id: 'agents',
170+
label: 'AGENTS.md',
171+
targetPath: 'AGENTS.md',
172+
hint: 'Codex, Amp, OpenCode, and similar agents',
173+
aliases: [
174+
'agents.md',
175+
'chatgpt',
176+
'chatgpt-codex',
177+
'codex',
178+
'amp',
179+
'kilo',
180+
'kilo-code',
181+
'kiro',
182+
'kiro-cli',
183+
'opencode',
184+
'other',
185+
],
186+
},
187+
{
188+
id: 'claude',
189+
label: 'CLAUDE.md',
190+
targetPath: 'CLAUDE.md',
191+
hint: 'Claude Code',
192+
aliases: ['claude.md', 'claude-code'],
193+
},
194+
{
195+
id: 'gemini',
196+
label: 'GEMINI.md',
197+
targetPath: 'GEMINI.md',
198+
hint: 'Gemini CLI',
199+
aliases: ['gemini.md', 'gemini-cli'],
200+
},
176201
{
177202
id: 'copilot',
178-
label: 'GitHub Copilot',
203+
label: '.github/copilot-instructions.md',
179204
targetPath: '.github/copilot-instructions.md',
205+
hint: 'GitHub Copilot',
206+
aliases: ['github-copilot', 'copilot-instructions.md'],
207+
},
208+
{
209+
id: 'cursor',
210+
label: '.cursor/rules/viteplus.mdc',
211+
targetPath: '.cursor/rules/viteplus.mdc',
212+
hint: 'Cursor',
213+
aliases: ['viteplus.mdc'],
180214
},
181-
{ id: 'cursor', label: 'Cursor', targetPath: '.cursor/rules/viteplus.mdc' },
182215
{
183216
id: 'jetbrains',
184-
label: 'JetBrains AI Assistant',
217+
label: '.aiassistant/rules/viteplus.md',
185218
targetPath: '.aiassistant/rules/viteplus.md',
219+
hint: 'JetBrains AI Assistant',
220+
aliases: ['jetbrains', 'jetbrains-ai-assistant', 'aiassistant', 'viteplus.md'],
186221
},
187-
{ id: 'amp', label: 'Amp', targetPath: 'AGENTS.md' },
188-
{ id: 'kiro', label: 'Kiro', targetPath: 'AGENTS.md' },
189-
{ id: 'opencode', label: 'OpenCode', targetPath: 'AGENTS.md' },
190-
{ id: 'other', label: 'Other', targetPath: 'AGENTS.md' },
191222
] as const;
192223

193224
type AgentSelection = string | string[] | false;
225+
const AGENT_DEFAULT_ID = 'agents';
194226
const AGENT_STANDARD_PATH = 'AGENTS.md';
195227
const AGENT_INSTRUCTIONS_START_MARKER = '<!--VITE PLUS START-->';
196228
const AGENT_INSTRUCTIONS_END_MARKER = '<!--VITE PLUS END-->';
197229

230+
const AGENT_ALIASES = Object.fromEntries(
231+
AGENTS.flatMap((option) =>
232+
(option.aliases ?? []).map((alias) => [normalizeAgentName(alias), option.id]),
233+
),
234+
) as Record<string, string>;
235+
198236
export async function selectAgentTargetPaths({
199237
interactive,
200238
agent,
@@ -211,18 +249,13 @@ export async function selectAgentTargetPaths({
211249

212250
if (interactive && !agent) {
213251
const selectedAgents = await prompts.multiselect({
214-
message:
215-
'Which agents are you using?\n ' +
216-
styleText(
217-
'gray',
218-
'Writes an instruction file for each selected agent to help it understand `vp` commands and the project workflow.',
219-
),
252+
message: 'Which coding agent instruction files should Vite+ create?',
220253
options: AGENTS.map((option) => ({
221254
label: option.label,
222255
value: option.id,
223-
hint: option.targetPath,
256+
hint: option.hint,
224257
})),
225-
initialValues: ['chatgpt-codex'],
258+
initialValues: [AGENT_DEFAULT_ID],
226259
required: false,
227260
});
228261

@@ -237,7 +270,7 @@ export async function selectAgentTargetPaths({
237270
return resolveAgentTargetPaths(selectedAgents);
238271
}
239272

240-
return resolveAgentTargetPaths(agent ?? 'other');
273+
return resolveAgentTargetPaths(agent ?? AGENT_DEFAULT_ID);
241274
}
242275

243276
export async function selectAgentTargetPath({
@@ -359,9 +392,12 @@ function resolveSingleAgentTargetPath(agent: string) {
359392
const resolved = alias ? normalizeAgentName(alias) : normalized;
360393
const match = AGENTS.find(
361394
(option) =>
362-
normalizeAgentName(option.id) === resolved || normalizeAgentName(option.label) === resolved,
395+
normalizeAgentName(option.id) === resolved ||
396+
normalizeAgentName(option.label) === resolved ||
397+
normalizeAgentName(option.targetPath) === resolved ||
398+
option.aliases?.some((candidate) => normalizeAgentName(candidate) === resolved),
363399
);
364-
return match?.targetPath ?? AGENTS[AGENTS.length - 1].targetPath;
400+
return match?.targetPath ?? AGENT_STANDARD_PATH;
365401
}
366402

367403
export interface AgentConflictInfo {

0 commit comments

Comments
 (0)