huskies: merge 1218 story Remembered/sticky permission approvals so constrained agents stop re-prompting for the same action class
This commit is contained in:
@@ -40,10 +40,23 @@ pub fn worktree_path(project_root: &Path, story_id: &str) -> PathBuf {
|
||||
|
||||
/// Write a `.mcp.json` file in the given directory pointing to the huskies
|
||||
/// HTTP MCP endpoint at the given port.
|
||||
pub fn write_mcp_json(dir: &Path, port: u16) -> Result<(), String> {
|
||||
let content = format!(
|
||||
"{{\n \"mcpServers\": {{\n \"huskies\": {{\n \"type\": \"http\",\n \"url\": \"http://localhost:{port}/mcp\"\n }}\n }}\n}}\n"
|
||||
);
|
||||
///
|
||||
/// Embeds an `X-Huskies-Session` header set to `story_id` so the server can
|
||||
/// scope remembered permission approvals to this worktree's agent session
|
||||
/// (see `http::mcp::session`) without affecting other stories' agents.
|
||||
pub fn write_mcp_json(dir: &Path, port: u16, story_id: &str) -> Result<(), String> {
|
||||
let value = serde_json::json!({
|
||||
"mcpServers": {
|
||||
"huskies": {
|
||||
"type": "http",
|
||||
"url": format!("http://localhost:{port}/mcp"),
|
||||
"headers": { "X-Huskies-Session": story_id }
|
||||
}
|
||||
}
|
||||
});
|
||||
let content = serde_json::to_string_pretty(&value)
|
||||
.map_err(|e| format!("Serialize .mcp.json: {e}"))?
|
||||
+ "\n";
|
||||
std::fs::write(dir.join(".mcp.json"), content).map_err(|e| format!("Write .mcp.json: {e}"))
|
||||
}
|
||||
|
||||
@@ -91,7 +104,7 @@ mod tests {
|
||||
#[test]
|
||||
fn write_mcp_json_uses_given_port() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
write_mcp_json(tmp.path(), 4242).unwrap();
|
||||
write_mcp_json(tmp.path(), 4242, "1218").unwrap();
|
||||
let content = std::fs::read_to_string(tmp.path().join(".mcp.json")).unwrap();
|
||||
assert!(content.contains("http://localhost:4242/mcp"));
|
||||
}
|
||||
@@ -99,11 +112,23 @@ mod tests {
|
||||
#[test]
|
||||
fn write_mcp_json_default_port() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
write_mcp_json(tmp.path(), 3001).unwrap();
|
||||
write_mcp_json(tmp.path(), 3001, "1218").unwrap();
|
||||
let content = std::fs::read_to_string(tmp.path().join(".mcp.json")).unwrap();
|
||||
assert!(content.contains("http://localhost:3001/mcp"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_mcp_json_embeds_session_header_with_story_id() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
write_mcp_json(tmp.path(), 3001, "42_story_test").unwrap();
|
||||
let content = std::fs::read_to_string(tmp.path().join(".mcp.json")).unwrap();
|
||||
let parsed: serde_json::Value = serde_json::from_str(&content).unwrap();
|
||||
assert_eq!(
|
||||
parsed["mcpServers"]["huskies"]["headers"]["X-Huskies-Session"],
|
||||
"42_story_test"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worktree_path_is_inside_project() {
|
||||
let project_root = Path::new("/home/user/my-project");
|
||||
|
||||
Reference in New Issue
Block a user