story-kit: merge 270_bug_qa_test_server_overwrites_root_mcp_json_with_wrong_port
This commit is contained in:
@@ -1293,11 +1293,6 @@ impl AgentPool {
|
|||||||
.and_then(|jobs| jobs.get(story_id).cloned())
|
.and_then(|jobs| jobs.get(story_id).cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the port this server is running on.
|
|
||||||
pub fn port(&self) -> u16 {
|
|
||||||
self.port
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get project root helper.
|
/// Get project root helper.
|
||||||
pub fn get_project_root(
|
pub fn get_project_root(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ impl ProjectApi {
|
|||||||
payload.0.path,
|
payload.0.path,
|
||||||
&self.ctx.state,
|
&self.ctx.state,
|
||||||
self.ctx.store.as_ref(),
|
self.ctx.store.as_ref(),
|
||||||
self.ctx.agents.port(),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(bad_request)?;
|
.map_err(bad_request)?;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::state::SessionState;
|
use crate::state::SessionState;
|
||||||
use crate::store::StoreOps;
|
use crate::store::StoreOps;
|
||||||
use crate::worktree::write_mcp_json as worktree_write_mcp_json;
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -515,17 +514,12 @@ pub async fn open_project(
|
|||||||
path: String,
|
path: String,
|
||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
store: &dyn StoreOps,
|
store: &dyn StoreOps,
|
||||||
port: u16,
|
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let p = PathBuf::from(&path);
|
let p = PathBuf::from(&path);
|
||||||
|
|
||||||
ensure_project_root_with_story_kit(p.clone()).await?;
|
ensure_project_root_with_story_kit(p.clone()).await?;
|
||||||
validate_project_path(p.clone()).await?;
|
validate_project_path(p.clone()).await?;
|
||||||
|
|
||||||
// Write .mcp.json so that claude-code can connect to the MCP server.
|
|
||||||
// Best-effort: failure should not prevent the project from opening.
|
|
||||||
let _ = worktree_write_mcp_json(&p, port);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// TRACE:MERGE-DEBUG — remove once root cause is found
|
// TRACE:MERGE-DEBUG — remove once root cause is found
|
||||||
crate::slog!("[MERGE-DEBUG] open_project: setting project_root to {:?}", p);
|
crate::slog!("[MERGE-DEBUG] open_project: setting project_root to {:?}", p);
|
||||||
@@ -813,7 +807,6 @@ mod tests {
|
|||||||
project_dir.to_string_lossy().to_string(),
|
project_dir.to_string_lossy().to_string(),
|
||||||
&state,
|
&state,
|
||||||
&store,
|
&store,
|
||||||
3001,
|
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -823,7 +816,11 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn open_project_writes_mcp_json_to_project_root() {
|
async fn open_project_does_not_write_mcp_json() {
|
||||||
|
// open_project must NOT overwrite .mcp.json — test servers started by QA
|
||||||
|
// agents share the real project root, so writing here would clobber the
|
||||||
|
// root .mcp.json with the wrong port. .mcp.json is written once during
|
||||||
|
// worktree creation (worktree.rs) and should not be touched again.
|
||||||
let dir = tempdir().unwrap();
|
let dir = tempdir().unwrap();
|
||||||
let project_dir = dir.path().join("myproject");
|
let project_dir = dir.path().join("myproject");
|
||||||
fs::create_dir_all(&project_dir).unwrap();
|
fs::create_dir_all(&project_dir).unwrap();
|
||||||
@@ -834,17 +831,14 @@ mod tests {
|
|||||||
project_dir.to_string_lossy().to_string(),
|
project_dir.to_string_lossy().to_string(),
|
||||||
&state,
|
&state,
|
||||||
&store,
|
&store,
|
||||||
4242,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mcp_path = project_dir.join(".mcp.json");
|
let mcp_path = project_dir.join(".mcp.json");
|
||||||
assert!(mcp_path.exists(), ".mcp.json should be written to project root");
|
|
||||||
let content = fs::read_to_string(&mcp_path).unwrap();
|
|
||||||
assert!(
|
assert!(
|
||||||
content.contains("http://localhost:4242/mcp"),
|
!mcp_path.exists(),
|
||||||
".mcp.json should contain the correct port"
|
"open_project must not write .mcp.json — that would overwrite the root with the wrong port"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -904,7 +898,6 @@ mod tests {
|
|||||||
project_dir.to_string_lossy().to_string(),
|
project_dir.to_string_lossy().to_string(),
|
||||||
&state,
|
&state,
|
||||||
&store,
|
&store,
|
||||||
3001,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -1365,7 +1358,6 @@ mod tests {
|
|||||||
project_dir.to_string_lossy().to_string(),
|
project_dir.to_string_lossy().to_string(),
|
||||||
&state,
|
&state,
|
||||||
&store,
|
&store,
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -1389,7 +1381,6 @@ mod tests {
|
|||||||
project_dir.to_string_lossy().to_string(),
|
project_dir.to_string_lossy().to_string(),
|
||||||
&state,
|
&state,
|
||||||
&store,
|
&store,
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
explicit_root.to_string_lossy().to_string(),
|
explicit_root.to_string_lossy().to_string(),
|
||||||
&app_state,
|
&app_state,
|
||||||
store.as_ref(),
|
store.as_ref(),
|
||||||
port,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -81,7 +80,6 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
project_root.to_string_lossy().to_string(),
|
project_root.to_string_lossy().to_string(),
|
||||||
&app_state,
|
&app_state,
|
||||||
store.as_ref(),
|
store.as_ref(),
|
||||||
port,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
|
|||||||
Reference in New Issue
Block a user