Skip to content

Commit 3cf3d07

Browse files
authored
🤖 feat: add /init slash command for AGENTS.md bootstrap (#1190)
Add `/init` command that populates the chat input with a pre-written prompt to generate an AGENTS.md file for a project. - Works in both creation and workspace variants - Populates input for user review before sending - Added parser tests --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `medium`_
1 parent 5aac858 commit 3cf3d07

File tree

6 files changed

+130
-1
lines changed

6 files changed

+130
-1
lines changed

src/browser/assets/initMessage.txt

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<system>
2+
Use your tools to write an AGENTS.md file in the root of the workspace which will serve as a contribution guide for AI agents.
3+
Inspect the workspace layout, code, documentation and git history to ensure correctness and accuracy.
4+
5+
Insert the following preamble at the top of the file before any other sections. Do not include the surrounding code fence backticks; only include the text.
6+
```md
7+
You are an experienced, pragmatic software engineering AI agent. Do not over-engineer a solution when a simple one is possible. Keep edits minimal. If you want an exception to ANY rule, you MUST stop and get permission first.
8+
```
9+
10+
Recommended sections:
11+
- Project Overview (mandatory)
12+
- Basic details about the project (e.g., high-level overview and goals).
13+
- Technology choices (e.g., languages, databases, frameworks, libraries, build tools).
14+
- Reference (mandatory)
15+
- List important code files.
16+
- List important directories and basic code structure tips.
17+
- Project architecture.
18+
- Essential commands (mandatory)
19+
- build
20+
- format
21+
- lint
22+
- test
23+
- clean
24+
- development server
25+
- other *important* scripts (use `find -type f -name '*.sh'` or similar)
26+
- Patterns (optional)
27+
- List any important or uncommon patterns (compared to other similar codebases), with examples (e.g., how to authorize an HTTP request).
28+
- List any important workflows and their steps (e.g., how to make a database migration).
29+
- Testing patterns.
30+
- Anti-patterns (optional)
31+
- Search git history and comments to find recurring mistakes or forbidden patterns.
32+
- List each pattern and its reason.
33+
- Code style (optional)
34+
- Style guide to follow (with link).
35+
- Commit and Pull Request Guidelines (mandatory)
36+
- Required steps for validating changes before committing.
37+
- Commit message conventions (read `git log`, or use `type: message` by default).
38+
- Pull request description requirements.
39+
40+
You can add other sections if they are necessary.
41+
If the information required for mandatory sections isn't available due to the workspace being empty or sparse, add TODO text in its place.
42+
Optional sections should be scrapped if the information is too thin.
43+
44+
Some investigation tips:
45+
- Read existing lint configs, tsconfig, and CI workflows to find any style or layout rules.
46+
- Search for "TODO", "HACK", "FIXME", "don't", "never", "always" in comments.
47+
- Examine test files for patterns.
48+
- Read PR templates and issue templates if they exist.
49+
- Check for existing CONTRIBUTING.md, CODE_OF_CONDUCT.md, or similar documentation files.
50+
51+
Some writing tips:
52+
- Each "do X" should have a corresponding "don't Y" where applicable.
53+
- Commands should be easily copy-pastable and tested.
54+
- Terms or phrases specific to this project should be explained on first use.
55+
- Anything that is against the norm should be explicitly highlighted and called out.
56+
57+
Above all things:
58+
- The document must be clear and concise. Simple projects should need less than 400 words, but larger and more mature codebases will likely need 700+. Prioritize completeness over brevity.
59+
- Don't include useless fluff.
60+
- The document must be in Markdown format and use headings for structure.
61+
- Give examples where necessary or helpful (commands, directory paths, naming patterns).
62+
- Explanations and examples must be correct and specific to this codebase.
63+
- Maintain a professional, instructional tone.
64+
65+
If the workspace is empty or sparse, ask the user for more information. Avoid hallucinating important decisions. You can provide suggestions to the user for language/technology/tool choices, but always respect the user's decision.
66+
- Project description and goals.
67+
- Language(s).
68+
- Technologies (database?), frameworks, libraries.
69+
- Tools.
70+
- Any other questions as you deem necessary.
71+
72+
For empty or sparse workspaces ONLY, when finished writing AGENTS.md, ask the user if they would like you to do the following:
73+
- initialize git IF it's not already set up (e.g., `git init`, `git remote add`, etc.)
74+
- write a concise README.md file
75+
- generate the bare minimum project scaffolding (e.g., initializing the package manager, writing a minimal build tool config)
76+
</system>

src/browser/components/ChatInput/index.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
} from "./draftImagesStorage";
9494
import { RecordingOverlay } from "./RecordingOverlay";
9595
import { ReviewBlockFromData } from "../shared/ReviewBlock";
96+
import initMessage from "@/browser/assets/initMessage.txt?raw";
9697

9798
// localStorage quotas are environment-dependent and relatively small.
9899
// Be conservative here so we can warn the user before writes start failing.
@@ -855,6 +856,16 @@ const ChatInputInner: React.FC<ChatInputProps> = (props) => {
855856

856857
// Route to creation handler for creation variant
857858
if (variant === "creation") {
859+
// Handle /init command in creation variant - populate input with init message
860+
if (messageText.startsWith("/")) {
861+
const parsed = parseCommand(messageText);
862+
if (parsed?.type === "init") {
863+
setInput(initMessage);
864+
focusMessageInput();
865+
return;
866+
}
867+
}
868+
858869
// Creation variant: simple message send + workspace creation
859870
const creationImageParts = imageAttachmentsToImageParts(imageAttachments);
860871
const ok = await creationState.handleSend(
@@ -952,7 +963,12 @@ const ChatInputInner: React.FC<ChatInputProps> = (props) => {
952963
return;
953964
}
954965

955-
// Handle /vim command
966+
// Handle /init command - populate input with init message
967+
if (parsed.type === "init") {
968+
setInput(initMessage);
969+
focusMessageInput();
970+
return;
971+
}
956972

957973
// Handle other non-API commands (help, invalid args, etc)
958974
const commandToast = createCommandToast(parsed);

src/browser/utils/slashCommands/parser.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,17 @@ describe("plan commands", () => {
226226
});
227227
});
228228
});
229+
230+
describe("init command", () => {
231+
it("should parse /init", () => {
232+
expectParse("/init", { type: "init" });
233+
});
234+
235+
it("should reject /init with arguments", () => {
236+
expectParse("/init extra", {
237+
type: "unknown-command",
238+
command: "init",
239+
subcommand: "extra",
240+
});
241+
});
242+
});

src/browser/utils/slashCommands/registry.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,23 @@ const vimCommandDefinition: SlashCommandDefinition = {
456456
},
457457
};
458458

459+
const initCommandDefinition: SlashCommandDefinition = {
460+
key: "init",
461+
description: "Bootstrap an AGENTS.md file in a new or existing project",
462+
appendSpace: false,
463+
handler: ({ cleanRemainingTokens }): ParsedCommand => {
464+
if (cleanRemainingTokens.length > 0) {
465+
return {
466+
type: "unknown-command",
467+
command: "init",
468+
subcommand: cleanRemainingTokens[0],
469+
};
470+
}
471+
472+
return { type: "init" };
473+
},
474+
};
475+
459476
const planOpenCommandDefinition: SlashCommandDefinition = {
460477
key: "open",
461478
description: "Open plan in external editor",
@@ -700,6 +717,7 @@ export const SLASH_COMMAND_DEFINITIONS: readonly SlashCommandDefinition[] = [
700717
vimCommandDefinition,
701718
mcpCommandDefinition,
702719
idleCommandDefinition,
720+
initCommandDefinition,
703721
];
704722

705723
export const SLASH_COMMAND_DEFINITION_MAP = new Map(

src/browser/utils/slashCommands/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export type ParsedCommand =
3535
| { type: "mcp-open" }
3636
| { type: "plan-show" }
3737
| { type: "plan-open" }
38+
| { type: "init" }
3839
| { type: "unknown-command"; command: string; subcommand?: string }
3940
| { type: "idle-compaction"; hours: number | null }
4041
| null;

src/types/txt.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module "*.txt?raw" {
2+
const content: string;
3+
export default content;
4+
}

0 commit comments

Comments
 (0)