fix(web): démarre le serveur MCP custom CLI via idea-serve au lieu de node — #224

This commit is contained in:
2026-08-20 12:49:00 +02:00
parent b25c17c095
commit 9a3ca51f6b
9 changed files with 600 additions and 56 deletions

View File

@ -2594,6 +2594,80 @@ async fn launch_opencode_writes_isolated_config_and_env() {
);
}
#[tokio::test]
async fn launch_opencode_chat_with_runtime_uses_idea_bridge_without_pty_or_node() {
let profile = opencode_profile(pid(9));
let (launch, agent, fs, pty, _bus, _sessions, tr, _session) = launch_fixture_with_profile(
profile,
Some(ContextInjectionPlan::File {
target: "AGENTS.md".to_owned(),
}),
);
let factory = FakeStructuredFactory::new(Arc::clone(&tr), sid(888));
let structured = Arc::new(StructuredSessions::new());
let launch = launch
.with_structured_routing_mode(StructuredRoutingMode::HumanPtyFallback)
.with_structured(Arc::new(factory.clone()), Arc::clone(&structured));
let runtime = application::McpRuntime {
exe: "/opt/idea/idea-serve".to_owned(),
endpoint: "/run/user/1000/idea-mcp/proj.sock".to_owned(),
project_id: "0123456789abcdef0123456789abcdef".to_owned(),
requester: agent.id.to_string(),
};
let mut input = launch_input_with_runtime(agent.id, runtime);
input.require_structured = true;
input.node_id = Some(nid(224));
let out = launch.execute(input).await.unwrap();
assert_eq!(factory.starts(), vec![pid(9)]);
assert!(
pty.spawns().is_empty(),
"web custom chat must stay structured"
);
assert!(
out.structured.is_some(),
"backend returns a chat descriptor"
);
assert_eq!(
structured.node_for_agent_in_project(project().id, &agent.id),
Some(nid(224))
);
let run_dir = format!("/home/me/proj/.ideai/run/{}", agent.id);
let opencode = writes_ending_with(&fs, "/opencode.json");
assert_eq!(opencode.len(), 1, "one OpenCode config is written");
let body: serde_json::Value = serde_json::from_slice(&opencode[0].1).unwrap();
let command = body["mcp"]["idea"]["command"]
.as_array()
.expect("OpenCode local command is an argv array")
.iter()
.filter_map(serde_json::Value::as_str)
.collect::<Vec<_>>();
assert_eq!(command[0], "/opt/idea/idea-serve");
assert_ne!(command[0], "node");
assert_eq!(command[1], "mcp-server");
assert!(command.contains(&"--endpoint"));
assert!(command.contains(&"/run/user/1000/idea-mcp/proj.sock"));
assert!(command.contains(&"--project"));
assert!(command.contains(&"0123456789abcdef0123456789abcdef"));
assert!(command.contains(&"--requester"));
let requester = agent.id.to_string();
assert!(command.contains(&requester.as_str()));
let env: std::collections::HashMap<_, _> = factory
.envs()
.into_iter()
.next()
.expect("structured start receives env")
.into_iter()
.collect();
assert_eq!(
env.get("OPENCODE_CONFIG").map(String::as_str),
Some(format!("{run_dir}/opencode.json").as_str())
);
}
#[tokio::test]
async fn launch_mcp_flag_appends_flag_and_path_to_args() {
// Test 5 — Flag { flag: "--mcp-config" } ⇒ spec.args carries the flag followed