huskies: merge 1137 story First-run project init flow — walk through config instead of leaving defaults silently
This commit is contained in:
@@ -217,8 +217,15 @@ pub(in crate::chat::transport::matrix::bot) async fn on_room_message(
|
||||
// endpoint. Only a small set of gateway-local commands are handled here.
|
||||
if ctx.is_gateway() {
|
||||
// Commands that are meaningful on the gateway itself (no project state needed).
|
||||
const GATEWAY_LOCAL_COMMANDS: &[&str] =
|
||||
&["help", "ambient", "reset", "switch", "all_status", "new"];
|
||||
const GATEWAY_LOCAL_COMMANDS: &[&str] = &[
|
||||
"help",
|
||||
"ambient",
|
||||
"reset",
|
||||
"switch",
|
||||
"all_status",
|
||||
"new",
|
||||
"config",
|
||||
];
|
||||
|
||||
let stripped = crate::chat::util::strip_bot_mention(
|
||||
&user_message,
|
||||
@@ -293,6 +300,63 @@ pub(in crate::chat::transport::matrix::bot) async fn on_room_message(
|
||||
return;
|
||||
}
|
||||
|
||||
// `config <project> <key>=<value>` — override an agent or project setting.
|
||||
if cmd == "config" {
|
||||
let response = if let Some(ref store) = ctx.gateway_projects_store {
|
||||
// Parse: "<project> <key>=<value>"
|
||||
let mut parts = args.splitn(2, char::is_whitespace);
|
||||
let project = parts.next().unwrap_or("").trim();
|
||||
let setting = parts.next().unwrap_or("").trim();
|
||||
if project.is_empty() || setting.is_empty() {
|
||||
"Usage: `config <project> <key>=<value>`\n\
|
||||
Examples:\n\
|
||||
- `config myapp coder.model=opus`\n\
|
||||
- `config myapp default_qa=human`"
|
||||
.to_string()
|
||||
} else {
|
||||
match setting.split_once('=') {
|
||||
None => {
|
||||
"Usage: setting must be in `key=value` form, e.g. `coder.model=opus`"
|
||||
.to_string()
|
||||
}
|
||||
Some((key, value)) => {
|
||||
let host_path_opt = {
|
||||
let projects = store.read().await;
|
||||
projects.get(project).and_then(|e| e.host_path.clone())
|
||||
};
|
||||
match host_path_opt {
|
||||
None => format!(
|
||||
"Project `{project}` not found or has no host path configured."
|
||||
),
|
||||
Some(path) => {
|
||||
match super::super::super::new_project::apply_project_config(
|
||||
std::path::Path::new(&path),
|
||||
key.trim(),
|
||||
value.trim(),
|
||||
) {
|
||||
Ok(msg) => msg,
|
||||
Err(e) => format!("Config error: {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
"Gateway projects store unavailable.".to_string()
|
||||
};
|
||||
let html = markdown_to_html(&response);
|
||||
if let Ok(msg_id) = ctx
|
||||
.transport
|
||||
.send_message(&room_id_str, &response, &html)
|
||||
.await
|
||||
&& let Ok(event_id) = msg_id.parse()
|
||||
{
|
||||
ctx.bot_sent_event_ids.lock().await.insert(event_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Gateway-local commands and freeform text fall through to normal handling below.
|
||||
}
|
||||
|
||||
@@ -320,6 +384,7 @@ pub(in crate::chat::transport::matrix::bot) async fn on_room_message(
|
||||
cmd.git_token.as_deref(),
|
||||
cmd.host_path.as_deref(),
|
||||
cmd.adopt_path.as_deref(),
|
||||
cmd.skip_config,
|
||||
store,
|
||||
&ctx.services.project_root,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user