798
),
799
AvailableCommand::new("permissions", "Show the tool permission policy"),
800
AvailableCommand::new("compact", "Summarize and shrink the conversation history"),
801
+ AvailableCommand::new("init", "Generate or improve the repo's AGENTS.md"),
802
AvailableCommand::new("clear", "Wipe the conversation history"),
803
AvailableCommand::new("status", "Show engine status"),
804
];
1269
return Ok(PromptResponse::new(StopReason::EndTurn));
1270
}
1271
1271
- if let Some(command) = parse_slash(&user_text) {
1272
- return exec_slash_acp(self, cx, session_id, command).await;
1273
- }
1272
+ let user_text = match parse_slash(&user_text) {
1273
+ // `/init` is not a status command: it substitutes the canned
1274
+ // AGENTS.md-generation prompt and runs a normal agent turn, so the
1275
+ // exploration and file write go through the ordinary tools and
1276
+ // permission checks.
1277
+ Some(SlashCommand::Init) => instructions::INIT_PROMPT.to_string(),
1278
+ Some(command) => return exec_slash_acp(self, cx, session_id, command).await,
1279
+ None => user_text,
1280
+ };
1281
1282
log::info!(
1283
"prompt({}): \"{}\"",
2241
Permissions,
2242
/// Summarize-and-shrink the conversation history on demand.
2243
Compact,
2244
+ /// Generate (or improve) the repo's AGENTS.md by running an agent turn
2245
+ /// with [`instructions::INIT_PROMPT`] as the user text.
2246
+ Init,
2247
Exit,
2248
Unknown(String),
2249
}
2272
"/plan" => SlashCommand::Plan(parse_on_off(argument)),
2273
"/permissions" => SlashCommand::Permissions,
2274
"/compact" => SlashCommand::Compact,
2275
+ "/init" => SlashCommand::Init,
2276
"/exit" | "/quit" | "/q" => SlashCommand::Exit,
2277
other => SlashCommand::Unknown(other.to_string()),
2278
})
2384
/plan [on|off] - plan mode: research only, no edits or commands\n\
2385
/permissions - show the tool permission policy\n\
2386
/compact - summarize and shrink conversation history\n\
2387
+ /init - generate or improve the repo's AGENTS.md\n\
2388
/clear - wipe conversation history\n\
2389
/status - show engine status\n\
2390
/exit - end this turn",
2654
)
2655
.ok();
2656
}
2657
+ SlashCommand::Init => {
2658
+ // Handled in the prompt path (it runs a real turn); reaching this
2659
+ // arm means a caller forgot that special case.
2660
+ agent
2661
+ .send_assistant_message(cx, session_id, "Send /init as a prompt to run it.")
2662
+ .ok();
2663
+ }
2664
SlashCommand::Unknown(command) => {
2665
agent
2666
.send_assistant_message(cx, session_id, format!("unknown command: {command}"))
3242
);
3243
}
3244
3245
+ #[test]
3246
+ fn parse_slash_maps_init() {
3247
+ assert!(matches!(parse_slash("/init"), Some(SlashCommand::Init)));
3248
+ // Trailing whitespace comes from editors that submit the raw line.
3249
+ assert!(matches!(parse_slash(" /init "), Some(SlashCommand::Init)));
3250
+ }
3251
+
3252
#[test]
3253
fn ascii_safe_replaces_multibyte_chars() {
3254
// The exact label that crashed Zed: the cloud tier name plus the old