| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
mod common; |
| 7 |
|
| 8 |
use common::{run, setup, text, Serving}; |
| 9 |
use serde_json::{json, Value}; |
| 10 |
use spectra_core::keys::KeyPair; |
| 11 |
use spectra_mcp::client::{rpc_result, Client}; |
| 12 |
|
| 13 |
async fn call(c: &Client, name: &str, args: Value) -> Value { |
| 14 |
let req = json!({ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": name, "arguments": args } }); |
| 15 |
rpc_result(&c.mcp("2025-11-25", &req).await.unwrap()).unwrap()["result"].clone() |
| 16 |
} |
| 17 |
|
| 18 |
#[tokio::test] |
| 19 |
async fn a_unique_part_of_a_name_is_a_mention() { |
| 20 |
let dir = setup(); |
| 21 |
let d = dir.path(); |
| 22 |
for p in ["book", "web"] { |
| 23 |
assert!(run(d, &["project", "add", p]).status.success()); |
| 24 |
} |
| 25 |
let mut keys = std::collections::HashMap::new(); |
| 26 |
for (n, kind, p) in [("kimi-book", "kimi-code", "book"), ("claude-book", "claude-code", "book"), ("claude-web", "claude-code", "web")] { |
| 27 |
let home = d.join("agents").join(n); |
| 28 |
let o = run(d, &["agent", "add", n, "--kind", kind, "--project", p, "--home", home.to_str().unwrap(), "--yes"]); |
| 29 |
assert!(o.status.success(), "{}", text(&o)); |
| 30 |
keys.insert(n, KeyPair::load_home(&home).unwrap()); |
| 31 |
} |
| 32 |
let srv = Serving::start(d); |
| 33 |
let c = |n: &str| Client::new(&srv.socket, Some(keys[n].clone())); |
| 34 |
|
| 35 |
call(&c("claude-web"), "say", json!({ "body": "@Kimi and @WEB, and @book: hello", "channel": "general" })).await; |
| 36 |
let unread = |r: Value| r["structuredContent"]["items"].as_array().map(|a| a.len()).unwrap_or(0); |
| 37 |
assert_eq!(unread(call(&c("kimi-book"), "inbox", json!({})).await), 1, "@Kimi reaches kimi-book"); |
| 38 |
assert_eq!(unread(call(&c("claude-book"), "inbox", json!({})).await), 0, "@book is two agents: nobody"); |
| 39 |
|
| 40 |
|
| 41 |
assert!(run(d, &["agent", "allow", "claude-web", "--channel", "book"]).status.success()); |
| 42 |
call(&c("claude-web"), "say", json!({ "body": "@channel the index moved", "channel": "book" })).await; |
| 43 |
assert_eq!(unread(call(&c("claude-book"), "inbox", json!({})).await), 1, "@channel in #book reaches claude-book"); |
| 44 |
assert_eq!(unread(call(&c("kimi-book"), "inbox", json!({})).await), 2, "and kimi-book"); |
| 45 |
call(&c("kimi-book"), "say", json!({ "body": "@all heads up", "channel": "general" })).await; |
| 46 |
assert_eq!(unread(call(&c("claude-web"), "inbox", json!({})).await), 1, "@all reaches claude-web too"); |
| 47 |
srv.stop(); |
| 48 |
} |