huskies: merge 585_bug_bot_not_aware_of_actual_running_port_defaults_to_3001

This commit is contained in:
dave
2026-04-15 23:42:46 +00:00
parent 2663c5f91f
commit 4a1c6b4cfa
3 changed files with 26 additions and 15 deletions
+3 -2
View File
@@ -349,13 +349,14 @@ pub(super) fn tool_dump_crdt(args: &Value) -> Result<String, String> {
.map_err(|e| format!("Serialization error: {e}"))
}
/// MCP tool: return the server version and build hash.
pub(super) fn tool_get_version() -> Result<String, String> {
/// MCP tool: return the server version, build hash, and running port.
pub(super) fn tool_get_version(ctx: &AppContext) -> Result<String, String> {
let build_hash =
std::fs::read_to_string(".huskies/build_hash").unwrap_or_else(|_| "unknown".to_string());
serde_json::to_string_pretty(&json!({
"version": env!("CARGO_PKG_VERSION"),
"build_hash": build_hash.trim(),
"port": ctx.agents.port(),
}))
.map_err(|e| format!("Serialization error: {e}"))
}
+2 -2
View File
@@ -897,7 +897,7 @@ fn handle_tools_list(id: Option<Value>) -> JsonRpcResponse {
},
{
"name": "get_version",
"description": "Return the server version and build hash.",
"description": "Return the server version, build hash, and running port.",
"inputSchema": {
"type": "object",
"properties": {}
@@ -1330,7 +1330,7 @@ async fn handle_tools_call(id: Option<Value>, params: &Value, ctx: &AppContext)
"get_pipeline_status" => story_tools::tool_get_pipeline_status(ctx),
// Diagnostics
"get_server_logs" => diagnostics::tool_get_server_logs(&args),
"get_version" => diagnostics::tool_get_version(),
"get_version" => diagnostics::tool_get_version(ctx),
// Server lifecycle
"rebuild_and_restart" => diagnostics::tool_rebuild_and_restart(ctx).await,
// Permission bridge (Claude Code → frontend dialog)
+21 -11
View File
@@ -37,6 +37,13 @@ pub(crate) async fn ensure_project_root_with_story_kit(
if !path.join(".huskies").is_dir() {
scaffold_story_kit(&path, port)?;
}
// Always update .mcp.json with the current port so the bot connects to
// the right endpoint even when HUSKIES_PORT changes between restarts.
let mcp_content = format!(
"{{\n \"mcpServers\": {{\n \"huskies\": {{\n \"type\": \"http\",\n \"url\": \"http://localhost:{port}/mcp\"\n }}\n }}\n}}\n"
);
fs::write(path.join(".mcp.json"), mcp_content)
.map_err(|e| format!("Failed to write .mcp.json: {}", e))?;
Ok(())
})
.await
@@ -194,16 +201,15 @@ mod tests {
}
#[tokio::test]
async fn open_project_does_not_overwrite_existing_mcp_json() {
// scaffold must NOT overwrite .mcp.json when it already exists — QA
// test servers share the real project root, and re-writing would
// clobber the file with the wrong port.
async fn open_project_updates_mcp_json_with_current_port() {
// .mcp.json must always be updated with the actual running port so the
// bot connects to the right MCP endpoint even when HUSKIES_PORT changes.
let dir = tempdir().unwrap();
let project_dir = dir.path().join("myproject");
fs::create_dir_all(&project_dir).unwrap();
// Pre-write .mcp.json with a different port to simulate an already-configured project.
// Pre-write .mcp.json with a different port to simulate a stale file.
let mcp_path = project_dir.join(".mcp.json");
fs::write(&mcp_path, "{\"existing\": true}").unwrap();
fs::write(&mcp_path, "{\"stale\": true}").unwrap();
let store = make_store(&dir);
let state = SessionState::default();
@@ -211,15 +217,19 @@ mod tests {
project_dir.to_string_lossy().to_string(),
&state,
&store,
3001,
3002,
)
.await
.unwrap();
assert_eq!(
fs::read_to_string(&mcp_path).unwrap(),
"{\"existing\": true}",
"open_project must not overwrite an existing .mcp.json"
let content = fs::read_to_string(&mcp_path).unwrap();
assert!(
content.contains("3002"),
"open_project must update .mcp.json with the actual running port"
);
assert!(
content.contains("localhost"),
"mcp.json must reference localhost"
);
}