@team-agent/installer 0.5.42 → 0.5.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/src/cli/adapters.rs +129 -54
  4. package/crates/team-agent/src/cli/diagnose.rs +1 -2
  5. package/crates/team-agent/src/cli/emit.rs +1 -7
  6. package/crates/team-agent/src/cli/helpers.rs +3 -1
  7. package/crates/team-agent/src/cli/leader.rs +2 -1
  8. package/crates/team-agent/src/cli/mod.rs +126 -16
  9. package/crates/team-agent/src/cli/named_address.rs +14 -5
  10. package/crates/team-agent/src/cli/profile.rs +19 -7
  11. package/crates/team-agent/src/cli/send.rs +9 -3
  12. package/crates/team-agent/src/cli/status.rs +8 -30
  13. package/crates/team-agent/src/cli/status_port.rs +1341 -1272
  14. package/crates/team-agent/src/cli/tests/base.rs +738 -660
  15. package/crates/team-agent/src/cli/tests/compile.rs +45 -18
  16. package/crates/team-agent/src/cli/tests/divergence.rs +462 -444
  17. package/crates/team-agent/src/cli/tests/lane_c.rs +365 -282
  18. package/crates/team-agent/src/cli/tests/leader_watch.rs +356 -329
  19. package/crates/team-agent/src/cli/tests/main_preserved.rs +672 -564
  20. package/crates/team-agent/src/cli/tests/missing_subcommands.rs +284 -224
  21. package/crates/team-agent/src/cli/tests/mod.rs +17 -7
  22. package/crates/team-agent/src/cli/tests/named_address.rs +8 -2
  23. package/crates/team-agent/src/cli/tests/peer_allow.rs +10 -2
  24. package/crates/team-agent/src/cli/tests/run_delegation.rs +314 -273
  25. package/crates/team-agent/src/cli/tests/shutdown_kill_plan.rs +26 -15
  26. package/crates/team-agent/src/cli/tests/status_send.rs +707 -629
  27. package/crates/team-agent/src/cli/tests/verb_install_skill.rs +20 -4
  28. package/crates/team-agent/src/cli/tests/verb_profile.rs +46 -17
  29. package/crates/team-agent/src/cli/tests/verb_validate.rs +15 -3
  30. package/crates/team-agent/src/codex_app_server.rs +2 -5
  31. package/crates/team-agent/src/compiler/tests.rs +139 -33
  32. package/crates/team-agent/src/compiler.rs +55 -22
  33. package/crates/team-agent/src/conpty/backend.rs +23 -33
  34. package/crates/team-agent/src/coordinator/backoff.rs +2 -7
  35. package/crates/team-agent/src/coordinator/conpty_shim.rs +55 -67
  36. package/crates/team-agent/src/coordinator/health.rs +46 -31
  37. package/crates/team-agent/src/coordinator/mod.rs +3 -3
  38. package/crates/team-agent/src/coordinator/orphan.rs +22 -10
  39. package/crates/team-agent/src/coordinator/steps/abnormal.rs +51 -56
  40. package/crates/team-agent/src/coordinator/tests/abnormal.rs +55 -19
  41. package/crates/team-agent/src/coordinator/tests/basics.rs +179 -41
  42. package/crates/team-agent/src/coordinator/tests/daemon.rs +53 -13
  43. package/crates/team-agent/src/coordinator/tests/health_sync.rs +78 -19
  44. package/crates/team-agent/src/coordinator/tests/main_preserved.rs +61 -11
  45. package/crates/team-agent/src/coordinator/tests/mod.rs +33 -39
  46. package/crates/team-agent/src/coordinator/tests/spine.rs +52 -12
  47. package/crates/team-agent/src/coordinator/tests/takeover.rs +73 -15
  48. package/crates/team-agent/src/coordinator/tests/tick_core.rs +50 -15
  49. package/crates/team-agent/src/coordinator/tests/watch.rs +74 -20
  50. package/crates/team-agent/src/db/message_store.rs +138 -30
  51. package/crates/team-agent/src/db/migration.rs +249 -61
  52. package/crates/team-agent/src/db/schema.rs +303 -82
  53. package/crates/team-agent/src/diagnose/comms.rs +9 -2
  54. package/crates/team-agent/src/diagnose/mod.rs +1 -3
  55. package/crates/team-agent/src/diagnose/orphans.rs +79 -61
  56. package/crates/team-agent/src/event_log.rs +70 -16
  57. package/crates/team-agent/src/layout/manager.rs +15 -4
  58. package/crates/team-agent/src/layout/mod.rs +4 -4
  59. package/crates/team-agent/src/layout/overlay.rs +10 -3
  60. package/crates/team-agent/src/layout/placement.rs +5 -1
  61. package/crates/team-agent/src/layout/recovery.rs +4 -2
  62. package/crates/team-agent/src/layout/runtime_sessions.rs +7 -7
  63. package/crates/team-agent/src/layout/sessions.rs +17 -9
  64. package/crates/team-agent/src/layout/tmux_endpoint.rs +1 -1
  65. package/crates/team-agent/src/layout/worker_env.rs +87 -19
  66. package/crates/team-agent/src/leader/helpers.rs +7 -1
  67. package/crates/team-agent/src/leader/lease.rs +199 -89
  68. package/crates/team-agent/src/leader/owner_bind.rs +55 -22
  69. package/crates/team-agent/src/leader/provider_attribution.rs +25 -6
  70. package/crates/team-agent/src/leader/rediscover/tests.rs +88 -24
  71. package/crates/team-agent/src/leader/rediscover.rs +74 -25
  72. package/crates/team-agent/src/leader/registry.rs +1 -1
  73. package/crates/team-agent/src/leader/start.rs +75 -54
  74. package/crates/team-agent/src/leader/takeover.rs +46 -11
  75. package/crates/team-agent/src/leader/tests/basics.rs +320 -167
  76. package/crates/team-agent/src/leader/tests/byte_findings.rs +361 -219
  77. package/crates/team-agent/src/leader/tests/identity.rs +428 -356
  78. package/crates/team-agent/src/leader/tests/idle.rs +285 -254
  79. package/crates/team-agent/src/leader/tests/lease_api.rs +338 -274
  80. package/crates/team-agent/src/leader/tests/lease_claim.rs +643 -593
  81. package/crates/team-agent/src/leader/tests/mod.rs +115 -99
  82. package/crates/team-agent/src/leader/tests/rediscover.rs +74 -22
  83. package/crates/team-agent/src/leader/tests/wake_start_owner.rs +237 -211
  84. package/crates/team-agent/src/lib.rs +4 -4
  85. package/crates/team-agent/src/lifecycle/display.rs +7 -3
  86. package/crates/team-agent/src/lifecycle/launch.rs +55 -15
  87. package/crates/team-agent/src/lifecycle/mod.rs +9 -1
  88. package/crates/team-agent/src/lifecycle/profile_launch.rs +77 -34
  89. package/crates/team-agent/src/lifecycle/profile_smoke.rs +3 -1
  90. package/crates/team-agent/src/lifecycle/restart/agent.rs +1 -6
  91. package/crates/team-agent/src/lifecycle/restart/common.rs +6 -2
  92. package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +1 -4
  93. package/crates/team-agent/src/lifecycle/restart/preflight.rs +6 -5
  94. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +26 -22
  95. package/crates/team-agent/src/lifecycle/restart/remove.rs +45 -35
  96. package/crates/team-agent/src/lifecycle/restart/team_state.rs +63 -17
  97. package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +251 -84
  98. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +198 -48
  99. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +2 -1
  100. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +152 -32
  101. package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +1 -5
  102. package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +3 -0
  103. package/crates/team-agent/src/lifecycle/tests.rs +2 -2
  104. package/crates/team-agent/src/main.rs +4 -4
  105. package/crates/team-agent/src/mcp_server/lifecycle_tools/agent_ops.rs +47 -20
  106. package/crates/team-agent/src/mcp_server/mod.rs +11 -2
  107. package/crates/team-agent/src/mcp_server/types.rs +14 -3
  108. package/crates/team-agent/src/mcp_server/wire.rs +230 -68
  109. package/crates/team-agent/src/messaging/delivery.rs +20 -18
  110. package/crates/team-agent/src/messaging/helpers.rs +25 -4
  111. package/crates/team-agent/src/messaging/leader_receiver.rs +4 -5
  112. package/crates/team-agent/src/messaging/mod.rs +2 -3
  113. package/crates/team-agent/src/messaging/selftest.rs +46 -26
  114. package/crates/team-agent/src/messaging/tests/main_preserved.rs +47 -12
  115. package/crates/team-agent/src/messaging/tests/runtime.rs +57 -22
  116. package/crates/team-agent/src/messaging/tests/spine.rs +154 -40
  117. package/crates/team-agent/src/messaging/tests/wave2.rs +31 -32
  118. package/crates/team-agent/src/messaging/trust.rs +25 -2
  119. package/crates/team-agent/src/messaging/watchers.rs +37 -9
  120. package/crates/team-agent/src/model/enums.rs +65 -16
  121. package/crates/team-agent/src/model/ids.rs +12 -3
  122. package/crates/team-agent/src/model/paths.rs +28 -7
  123. package/crates/team-agent/src/model/permissions.rs +176 -33
  124. package/crates/team-agent/src/model/routing.rs +66 -20
  125. package/crates/team-agent/src/model/spec.rs +365 -69
  126. package/crates/team-agent/src/model/task_graph.rs +36 -9
  127. package/crates/team-agent/src/model/yaml/tests.rs +24 -6
  128. package/crates/team-agent/src/model/yaml.rs +7 -6
  129. package/crates/team-agent/src/packaging/install.rs +23 -9
  130. package/crates/team-agent/src/packaging/migrate.rs +5 -7
  131. package/crates/team-agent/src/packaging/mod.rs +9 -1
  132. package/crates/team-agent/src/packaging/repair.rs +13 -6
  133. package/crates/team-agent/src/packaging/tests.rs +63 -16
  134. package/crates/team-agent/src/packaging/types.rs +22 -7
  135. package/crates/team-agent/src/platform/argv.rs +4 -1
  136. package/crates/team-agent/src/platform/file_lock.rs +22 -8
  137. package/crates/team-agent/src/platform/process.rs +54 -24
  138. package/crates/team-agent/src/provider/adapters/claude.rs +1 -3
  139. package/crates/team-agent/src/provider/approvals/parsing.rs +134 -26
  140. package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +13 -3
  141. package/crates/team-agent/src/provider/classify.rs +127 -42
  142. package/crates/team-agent/src/provider/faults.rs +17 -5
  143. package/crates/team-agent/src/provider/helpers.rs +6 -5
  144. package/crates/team-agent/src/provider/startup_prompt.rs +75 -27
  145. package/crates/team-agent/src/state/persist.rs +28 -0
  146. package/crates/team-agent/src/state/repository.rs +8 -3
  147. package/crates/team-agent/src/tmux_backend/tests.rs +1637 -1398
  148. package/crates/team-agent/src/tmux_backend.rs +80 -44
  149. package/crates/team-agent/src/topology.rs +40 -20
  150. package/crates/team-agent/src/transport/test_support.rs +20 -23
  151. package/crates/team-agent/src/transport/tests/behavior.rs +292 -293
  152. package/crates/team-agent/src/transport/tests/mod.rs +178 -187
  153. package/crates/team-agent/src/transport/tests/wire.rs +561 -525
  154. package/crates/team-agent/src/transport.rs +12 -17
  155. package/crates/team-agent/src/transport_factory.rs +29 -14
  156. package/package.json +4 -4
@@ -12,8 +12,8 @@ use super::helpers::{json_dumps_default, object_fields};
12
12
  use super::normalize::normalize_result_status;
13
13
  use super::tools::TeamOrchestratorTools;
14
14
  use super::types::{
15
- McpError, McpTool, RpcError, RpcId, RpcMethod, RpcResponse, Scope, SendOutcome, ServerRunReport,
16
- ToolError, ToolErrorReason, ToolOk, ToolResult,
15
+ McpError, McpTool, RpcError, RpcId, RpcMethod, RpcResponse, Scope, SendOutcome,
16
+ ServerRunReport, ToolError, ToolErrorReason, ToolOk, ToolResult,
17
17
  };
18
18
 
19
19
  // ═══════════════════════════════════════════════════════════════════════════
@@ -38,10 +38,7 @@ pub fn tools_contract() -> Vec<Value> {
38
38
  McpTool::StuckList,
39
39
  McpTool::StuckCancel,
40
40
  ];
41
- tools
42
- .into_iter()
43
- .map(tool_contract)
44
- .collect()
41
+ tools.into_iter().map(tool_contract).collect()
45
42
  }
46
43
 
47
44
  // ═══════════════════════════════════════════════════════════════════════════
@@ -58,7 +55,11 @@ pub fn dispatch(tools: &TeamOrchestratorTools, request: &Value) -> ToolResult {
58
55
  let tool_value = request
59
56
  .get("tool")
60
57
  .filter(|v| !v.as_str().is_some_and(str::is_empty))
61
- .or_else(|| request.get("name").filter(|v| !v.as_str().is_some_and(str::is_empty)))
58
+ .or_else(|| {
59
+ request
60
+ .get("name")
61
+ .filter(|v| !v.as_str().is_some_and(str::is_empty))
62
+ })
62
63
  .or_else(|| request.get("method"));
63
64
  let name = tool_value.and_then(Value::as_str);
64
65
  let args = request
@@ -95,7 +96,10 @@ pub fn dispatch(tools: &TeamOrchestratorTools, request: &Value) -> ToolResult {
95
96
  /// frame.
96
97
  ///
97
98
  /// [`ToolCallResult`]: super::ToolCallResult
98
- pub fn handle_mcp(tools: &TeamOrchestratorTools, request: &Value) -> Result<Option<RpcResponse>, McpError> {
99
+ pub fn handle_mcp(
100
+ tools: &TeamOrchestratorTools,
101
+ request: &Value,
102
+ ) -> Result<Option<RpcResponse>, McpError> {
99
103
  let id = rpc_id_from_request(request);
100
104
  let method = request.get("method").and_then(Value::as_str).unwrap_or("");
101
105
  match RpcMethod::classify(method) {
@@ -106,7 +110,10 @@ pub fn handle_mcp(tools: &TeamOrchestratorTools, request: &Value) -> Result<Opti
106
110
  .and_then(Value::as_str)
107
111
  .unwrap_or("2024-11-05");
108
112
  let mut result = serde_json::Map::new();
109
- result.insert("protocolVersion".to_string(), Value::String(protocol.to_string()));
113
+ result.insert(
114
+ "protocolVersion".to_string(),
115
+ Value::String(protocol.to_string()),
116
+ );
110
117
  result.insert("capabilities".to_string(), serde_json::json!({"tools": {}}));
111
118
  result.insert(
112
119
  "serverInfo".to_string(),
@@ -130,7 +137,10 @@ pub fn handle_mcp(tools: &TeamOrchestratorTools, request: &Value) -> Result<Opti
130
137
  let body = match dispatch(tools, params) {
131
138
  Ok(ok) => {
132
139
  let value = Value::Object(ok.fields);
133
- tool_call_result_value(value.get("ok").and_then(Value::as_bool) == Some(false), &value)
140
+ tool_call_result_value(
141
+ value.get("ok").and_then(Value::as_bool) == Some(false),
142
+ &value,
143
+ )
134
144
  }
135
145
  Err(err) => tool_call_result_value(true, &err.to_envelope()),
136
146
  };
@@ -247,7 +257,9 @@ fn handle_stdin_line(
247
257
 
248
258
  fn rpc_id_from_request(request: &Value) -> RpcId {
249
259
  match request.get("id") {
250
- Some(Value::Number(n)) => n.as_i64().map_or_else(|| RpcId::Number(n.clone()), RpcId::Int),
260
+ Some(Value::Number(n)) => n
261
+ .as_i64()
262
+ .map_or_else(|| RpcId::Number(n.clone()), RpcId::Int),
251
263
  Some(Value::String(s)) => RpcId::Str(s.clone()),
252
264
  _ => RpcId::Null,
253
265
  }
@@ -385,56 +397,172 @@ fn tool_properties(tool: McpTool) -> serde_json::Map<String, Value> {
385
397
  let mut properties = serde_json::Map::new();
386
398
  match tool {
387
399
  McpTool::AssignTask => {
388
- insert_property(&mut properties, "task", object_property("Task object to add or update."));
389
- insert_property(&mut properties, "message", string_property("Optional message to deliver with the task."));
400
+ insert_property(
401
+ &mut properties,
402
+ "task",
403
+ object_property("Task object to add or update."),
404
+ );
405
+ insert_property(
406
+ &mut properties,
407
+ "message",
408
+ string_property("Optional message to deliver with the task."),
409
+ );
390
410
  }
391
411
  McpTool::SendMessage => {
392
- insert_property(&mut properties, "to", string_property("Target agent id, 'leader', or '*' for broadcast."));
412
+ insert_property(
413
+ &mut properties,
414
+ "to",
415
+ string_property("Target agent id, 'leader', or '*' for broadcast."),
416
+ );
393
417
  insert_property(&mut properties, "content", string_property("Message body."));
394
- insert_property(&mut properties, "task_id", string_property("Optional task id to associate with the message."));
395
- insert_property(&mut properties, "sender", string_property("Optional sender override."));
396
- insert_property(&mut properties, "requires_ack", boolean_property("Whether the recipient should acknowledge delivery."));
418
+ insert_property(
419
+ &mut properties,
420
+ "task_id",
421
+ string_property("Optional task id to associate with the message."),
422
+ );
423
+ insert_property(
424
+ &mut properties,
425
+ "sender",
426
+ string_property("Optional sender override."),
427
+ );
428
+ insert_property(
429
+ &mut properties,
430
+ "requires_ack",
431
+ boolean_property("Whether the recipient should acknowledge delivery."),
432
+ );
397
433
  }
398
434
  McpTool::ReportResult => {
399
- insert_property(&mut properties, "envelope", object_property("Optional full result envelope."));
400
- insert_property(&mut properties, "summary", string_property("Short result summary."));
435
+ insert_property(
436
+ &mut properties,
437
+ "envelope",
438
+ object_property("Optional full result envelope."),
439
+ );
440
+ insert_property(
441
+ &mut properties,
442
+ "summary",
443
+ string_property("Short result summary."),
444
+ );
401
445
  insert_property(&mut properties, "status", string_property("Result status."));
402
- insert_property(&mut properties, "changes", array_property("Changed files or artifacts."));
403
- insert_property(&mut properties, "tests", array_property("Tests or checks performed."));
404
- insert_property(&mut properties, "risks", array_property("Risks or blockers."));
405
- insert_property(&mut properties, "artifacts", array_property("Artifact references."));
406
- insert_property(&mut properties, "next_actions", array_property("Suggested next actions."));
407
- insert_property(&mut properties, "task_id", string_property("Optional task id override."));
408
- insert_property(&mut properties, "agent_id", string_property("Optional reporting agent id override."));
446
+ insert_property(
447
+ &mut properties,
448
+ "changes",
449
+ array_property("Changed files or artifacts."),
450
+ );
451
+ insert_property(
452
+ &mut properties,
453
+ "tests",
454
+ array_property("Tests or checks performed."),
455
+ );
456
+ insert_property(
457
+ &mut properties,
458
+ "risks",
459
+ array_property("Risks or blockers."),
460
+ );
461
+ insert_property(
462
+ &mut properties,
463
+ "artifacts",
464
+ array_property("Artifact references."),
465
+ );
466
+ insert_property(
467
+ &mut properties,
468
+ "next_actions",
469
+ array_property("Suggested next actions."),
470
+ );
471
+ insert_property(
472
+ &mut properties,
473
+ "task_id",
474
+ string_property("Optional task id override."),
475
+ );
476
+ insert_property(
477
+ &mut properties,
478
+ "agent_id",
479
+ string_property("Optional reporting agent id override."),
480
+ );
409
481
  }
410
482
  McpTool::UpdateState => {
411
- insert_property(&mut properties, "note", string_property("Note to append to team state."));
483
+ insert_property(
484
+ &mut properties,
485
+ "note",
486
+ string_property("Note to append to team state."),
487
+ );
412
488
  }
413
489
  McpTool::GetTeamStatus | McpTool::StuckList => {}
414
490
  McpTool::StopAgent => {
415
- insert_property(&mut properties, "agent_id", string_property("Agent id to stop."));
491
+ insert_property(
492
+ &mut properties,
493
+ "agent_id",
494
+ string_property("Agent id to stop."),
495
+ );
416
496
  }
417
497
  McpTool::ResetAgent => {
418
- insert_property(&mut properties, "agent_id", string_property("Agent id to reset."));
419
- insert_property(&mut properties, "discard_session", boolean_property("Whether to discard the existing provider session."));
498
+ insert_property(
499
+ &mut properties,
500
+ "agent_id",
501
+ string_property("Agent id to reset."),
502
+ );
503
+ insert_property(
504
+ &mut properties,
505
+ "discard_session",
506
+ boolean_property("Whether to discard the existing provider session."),
507
+ );
420
508
  }
421
509
  McpTool::AddAgent => {
422
- insert_property(&mut properties, "new_agent_id", string_property("New agent id."));
423
- insert_property(&mut properties, "role_file_path", string_property("Workspace-relative role file path."));
510
+ insert_property(
511
+ &mut properties,
512
+ "new_agent_id",
513
+ string_property("New agent id."),
514
+ );
515
+ insert_property(
516
+ &mut properties,
517
+ "role_file_path",
518
+ string_property("Workspace-relative role file path."),
519
+ );
424
520
  }
425
521
  McpTool::ForkAgent => {
426
- insert_property(&mut properties, "source_agent_id", string_property("Agent id to fork from."));
427
- insert_property(&mut properties, "as_agent_id", string_property("Agent id for the forked worker."));
428
- insert_property(&mut properties, "label", string_property("Optional display label."));
522
+ insert_property(
523
+ &mut properties,
524
+ "source_agent_id",
525
+ string_property("Agent id to fork from."),
526
+ );
527
+ insert_property(
528
+ &mut properties,
529
+ "as_agent_id",
530
+ string_property("Agent id for the forked worker."),
531
+ );
532
+ insert_property(
533
+ &mut properties,
534
+ "label",
535
+ string_property("Optional display label."),
536
+ );
429
537
  }
430
538
  McpTool::RequestHuman => {
431
- insert_property(&mut properties, "question", string_property("Question to ask the human."));
432
- insert_property(&mut properties, "task_id", string_property("Optional related task id."));
433
- insert_property(&mut properties, "agent_id", string_property("Optional requesting agent id."));
539
+ insert_property(
540
+ &mut properties,
541
+ "question",
542
+ string_property("Question to ask the human."),
543
+ );
544
+ insert_property(
545
+ &mut properties,
546
+ "task_id",
547
+ string_property("Optional related task id."),
548
+ );
549
+ insert_property(
550
+ &mut properties,
551
+ "agent_id",
552
+ string_property("Optional requesting agent id."),
553
+ );
434
554
  }
435
555
  McpTool::StuckCancel => {
436
- insert_property(&mut properties, "agent_id", string_property("Agent id whose stuck alerts should be suppressed."));
437
- insert_property(&mut properties, "alert_type", string_property("Alert type to suppress, or all."));
556
+ insert_property(
557
+ &mut properties,
558
+ "agent_id",
559
+ string_property("Agent id whose stuck alerts should be suppressed."),
560
+ );
561
+ insert_property(
562
+ &mut properties,
563
+ "alert_type",
564
+ string_property("Alert type to suppress, or all."),
565
+ );
438
566
  }
439
567
  }
440
568
  properties
@@ -460,12 +588,19 @@ fn array_property(description: &str) -> Value {
460
588
  serde_json::json!({"type": "array", "description": description, "items": {"type": "object", "additionalProperties": true}})
461
589
  }
462
590
 
463
- pub(crate) fn dispatch_tool(tools: &TeamOrchestratorTools, tool: McpTool, args: &Value) -> ToolResult {
591
+ pub(crate) fn dispatch_tool(
592
+ tools: &TeamOrchestratorTools,
593
+ tool: McpTool,
594
+ args: &Value,
595
+ ) -> ToolResult {
464
596
  if scope_ceiling_tool(tool) {
465
597
  tools.validate_rpc_scope_args(tool.wire_name(), args)?;
466
598
  }
467
599
  match tool {
468
- McpTool::AssignTask => tools.assign_task(args.get("task").unwrap_or(args), args.get("message").and_then(Value::as_str)),
600
+ McpTool::AssignTask => tools.assign_task(
601
+ args.get("task").unwrap_or(args),
602
+ args.get("message").and_then(Value::as_str),
603
+ ),
469
604
  McpTool::SendMessage => {
470
605
  let target = message_target_from_value(args.get("to"));
471
606
  let content = args.get("content").and_then(Value::as_str).unwrap_or("");
@@ -490,36 +625,61 @@ pub(crate) fn dispatch_tool(tools: &TeamOrchestratorTools, tool: McpTool, args:
490
625
  // cr verdict (T3-1 refined): an unknown status literal normalizes to
491
626
  // Partial and is OBSERVABLE at this ingestion boundary, never silent.
492
627
  {
493
- let (status, unknown) = crate::mcp_server::normalize::normalize_result_status_observed(
494
- args.get("status").and_then(Value::as_str),
495
- );
628
+ let (status, unknown) =
629
+ crate::mcp_server::normalize::normalize_result_status_observed(
630
+ args.get("status").and_then(Value::as_str),
631
+ );
496
632
  if let Some(raw) = unknown {
497
633
  tools.note_unknown_result_status(&raw);
498
634
  }
499
635
  status
500
636
  },
501
- args.get("changes").and_then(Value::as_array).map(Vec::as_slice),
502
- args.get("tests").and_then(Value::as_array).map(Vec::as_slice),
503
- args.get("risks").and_then(Value::as_array).map(Vec::as_slice),
504
- args.get("artifacts").and_then(Value::as_array).map(Vec::as_slice),
505
- args.get("next_actions").and_then(Value::as_array).map(Vec::as_slice),
637
+ args.get("changes")
638
+ .and_then(Value::as_array)
639
+ .map(Vec::as_slice),
640
+ args.get("tests")
641
+ .and_then(Value::as_array)
642
+ .map(Vec::as_slice),
643
+ args.get("risks")
644
+ .and_then(Value::as_array)
645
+ .map(Vec::as_slice),
646
+ args.get("artifacts")
647
+ .and_then(Value::as_array)
648
+ .map(Vec::as_slice),
649
+ args.get("next_actions")
650
+ .and_then(Value::as_array)
651
+ .map(Vec::as_slice),
506
652
  args.get("task_id").and_then(Value::as_str),
507
653
  args.get("agent_id").and_then(Value::as_str),
508
654
  ),
509
- McpTool::UpdateState => tools.update_state(args.get("note").and_then(Value::as_str).unwrap_or("")),
655
+ McpTool::UpdateState => {
656
+ tools.update_state(args.get("note").and_then(Value::as_str).unwrap_or(""))
657
+ }
510
658
  McpTool::GetTeamStatus => tools.get_team_status(),
511
- McpTool::StopAgent => tools.stop_agent(args.get("agent_id").and_then(Value::as_str).unwrap_or("")),
659
+ McpTool::StopAgent => {
660
+ tools.stop_agent(args.get("agent_id").and_then(Value::as_str).unwrap_or(""))
661
+ }
512
662
  McpTool::ResetAgent => tools.reset_agent(
513
663
  args.get("agent_id").and_then(Value::as_str).unwrap_or(""),
514
- args.get("discard_session").and_then(Value::as_bool).unwrap_or(false),
664
+ args.get("discard_session")
665
+ .and_then(Value::as_bool)
666
+ .unwrap_or(false),
515
667
  ),
516
668
  McpTool::AddAgent => tools.add_agent(
517
- args.get("new_agent_id").and_then(Value::as_str).unwrap_or(""),
518
- args.get("role_file_path").and_then(Value::as_str).unwrap_or(""),
669
+ args.get("new_agent_id")
670
+ .and_then(Value::as_str)
671
+ .unwrap_or(""),
672
+ args.get("role_file_path")
673
+ .and_then(Value::as_str)
674
+ .unwrap_or(""),
519
675
  ),
520
676
  McpTool::ForkAgent => tools.fork_agent(
521
- args.get("source_agent_id").and_then(Value::as_str).unwrap_or(""),
522
- args.get("as_agent_id").and_then(Value::as_str).unwrap_or(""),
677
+ args.get("source_agent_id")
678
+ .and_then(Value::as_str)
679
+ .unwrap_or(""),
680
+ args.get("as_agent_id")
681
+ .and_then(Value::as_str)
682
+ .unwrap_or(""),
523
683
  args.get("label").and_then(Value::as_str),
524
684
  ),
525
685
  McpTool::RequestHuman => tools.request_human(
@@ -531,7 +691,9 @@ pub(crate) fn dispatch_tool(tools: &TeamOrchestratorTools, tool: McpTool, args:
531
691
  McpTool::StuckCancel => tools.stuck_cancel(
532
692
  args.get("agent_id").and_then(Value::as_str).unwrap_or(""),
533
693
  // tools.py:351 — the MCP default alert_type is "stuck", not "all".
534
- args.get("alert_type").and_then(Value::as_str).unwrap_or("stuck"),
694
+ args.get("alert_type")
695
+ .and_then(Value::as_str)
696
+ .unwrap_or("stuck"),
535
697
  ),
536
698
  }
537
699
  }
@@ -598,7 +760,10 @@ mod e23_lifecycle_marker_tests {
598
760
  assert_eq!(events[0]["event"], serde_json::json!("mcp.server_started"));
599
761
  assert_eq!(events[1]["event"], serde_json::json!("mcp.server_exit"));
600
762
  assert_eq!(events[1]["reason"], serde_json::json!("stdin_eof"));
601
- assert_eq!(events[1]["workspace"], serde_json::json!(ws.display().to_string()));
763
+ assert_eq!(
764
+ events[1]["workspace"],
765
+ serde_json::json!(ws.display().to_string())
766
+ );
602
767
  assert_eq!(events[1]["pid"], serde_json::json!(std::process::id()));
603
768
  assert!(events[1].get("ppid").is_some());
604
769
  let _ = std::fs::remove_dir_all(&ws);
@@ -618,9 +783,8 @@ mod e23_lifecycle_marker_tests {
618
783
  }
619
784
 
620
785
  let ws = marker_ws("fatal");
621
- let input = std::io::Cursor::new(
622
- br#"{"jsonrpc":"2.0","id":1,"method":"initialize"}"#.to_vec(),
623
- );
786
+ let input =
787
+ std::io::Cursor::new(br#"{"jsonrpc":"2.0","id":1,"method":"initialize"}"#.to_vec());
624
788
 
625
789
  let err = run_stdio_loop(&ws, input, FailingWriter).expect_err("writer failure");
626
790
 
@@ -629,12 +793,10 @@ mod e23_lifecycle_marker_tests {
629
793
  assert_eq!(events[0]["event"], serde_json::json!("mcp.server_started"));
630
794
  assert_eq!(events[1]["event"], serde_json::json!("mcp.server_exit"));
631
795
  assert_eq!(events[1]["reason"], serde_json::json!("fatal_error"));
632
- assert!(
633
- events[1]["error"]
634
- .as_str()
635
- .unwrap_or_default()
636
- .contains("simulated stdout failure")
637
- );
796
+ assert!(events[1]["error"]
797
+ .as_str()
798
+ .unwrap_or_default()
799
+ .contains("simulated stdout failure"));
638
800
  let _ = std::fs::remove_dir_all(&ws);
639
801
  }
640
802
  }
@@ -362,7 +362,10 @@ pub fn deliver_pending_message(
362
362
  }
363
363
  let resolved = resolve_inject_target(state, &message.recipient, transport, &live_targets);
364
364
  if let Some(stale) = resolved.stale_binding.as_ref() {
365
- event_log.write("worker_pane_binding_stale", stale.as_event_payload(message_id, &message.recipient))?;
365
+ event_log.write(
366
+ "worker_pane_binding_stale",
367
+ stale.as_event_payload(message_id, &message.recipient),
368
+ )?;
366
369
  }
367
370
  let target = resolved.target.clone();
368
371
  if let Some(outcome) = block_missing_worker_target(
@@ -1232,7 +1235,11 @@ fn resolve_inject_target(
1232
1235
  }) {
1233
1236
  return ResolvedInjectTarget {
1234
1237
  target: Target::Pane(pane),
1235
- metadata: Some(target_metadata(transport, live_pane, "validated_cached_pane")),
1238
+ metadata: Some(target_metadata(
1239
+ transport,
1240
+ live_pane,
1241
+ "validated_cached_pane",
1242
+ )),
1236
1243
  stale_binding: None,
1237
1244
  };
1238
1245
  }
@@ -1259,15 +1266,13 @@ fn live_pane_for_session_window<'a>(
1259
1266
  session: &str,
1260
1267
  window: &str,
1261
1268
  ) -> Option<&'a PaneInfo> {
1262
- targets
1263
- .iter()
1264
- .find(|target| {
1265
- target.session.as_str() == session
1266
- && target
1267
- .window_name
1268
- .as_ref()
1269
- .is_some_and(|name| name.as_str() == window)
1270
- })
1269
+ targets.iter().find(|target| {
1270
+ target.session.as_str() == session
1271
+ && target
1272
+ .window_name
1273
+ .as_ref()
1274
+ .is_some_and(|name| name.as_str() == window)
1275
+ })
1271
1276
  }
1272
1277
 
1273
1278
  fn stale_worker_pane_binding(
@@ -2221,8 +2226,7 @@ fn record_turn_open_if_leader_to_worker_scoped(
2221
2226
  save_scoped_state_reapplying_after_conflict(workspace, &state, owner_team_id, |latest| {
2222
2227
  arm_turn_open(latest, recipient, &delivered.message_id);
2223
2228
  })?;
2224
- let mut event =
2225
- serde_json::json!({"agent_id": recipient, "message_id": delivered.message_id});
2229
+ let mut event = serde_json::json!({"agent_id": recipient, "message_id": delivered.message_id});
2226
2230
  if let Some(metadata) = metadata {
2227
2231
  append_target_metadata(&mut event, metadata);
2228
2232
  }
@@ -2256,11 +2260,9 @@ fn arm_turn_open(state: &mut serde_json::Value, recipient: &str, message_id: &Op
2256
2260
  // (whitelisted for the transition) and `mcp_server/helpers.rs`; other
2257
2261
  // messaging/lifecycle/mcp_server code MUST NOT treat this as
2258
2262
  // authoritative task state.
2259
- let field = message_id
2260
- .as_ref()
2261
- .map_or(serde_json::Value::Null, |id| {
2262
- serde_json::Value::String(id.clone())
2263
- });
2263
+ let field = message_id.as_ref().map_or(serde_json::Value::Null, |id| {
2264
+ serde_json::Value::String(id.clone())
2265
+ });
2264
2266
  agent.insert("current_turn_message_id".to_string(), field);
2265
2267
  }
2266
2268
  }
@@ -122,7 +122,10 @@ pub(crate) fn working_seconds(scrollback: &str) -> Option<u64> {
122
122
  // `❯ Run /review`, `Worked for 8m 34s`, or an empty composer prompt,
123
123
  // there is no LIVE working indicator and we return None — handing off
124
124
  // to the structural latest_prompt_signal / IRON LAW Uncertain path.
125
- let last_non_empty = scrollback.lines().rev().find(|line| !line.trim().is_empty())?;
125
+ let last_non_empty = scrollback
126
+ .lines()
127
+ .rev()
128
+ .find(|line| !line.trim().is_empty())?;
126
129
  let lower = last_non_empty.to_ascii_lowercase();
127
130
  let start = lower.find("working (")?;
128
131
  let rest = last_non_empty.get(start + "Working (".len()..)?;
@@ -193,9 +196,27 @@ pub(crate) fn latest_prompt_signal(scrollback: &str) -> Option<AgentActivity> {
193
196
  // and Claude Code tool-progress verbs. We look for STRUCTURAL
194
197
  // composer/status signals in the active region only.
195
198
  if [
196
- "working (", "thinking", "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦",
197
- "", "⠇", "⠏", "✶", "✢", "✻", "analyzing", "reading", "writing",
198
- "searching", "running", "editing",
199
+ "working (",
200
+ "thinking",
201
+ "",
202
+ "⠙",
203
+ "⠹",
204
+ "⠸",
205
+ "⠼",
206
+ "⠴",
207
+ "⠦",
208
+ "⠧",
209
+ "⠇",
210
+ "⠏",
211
+ "✶",
212
+ "✢",
213
+ "✻",
214
+ "analyzing",
215
+ "reading",
216
+ "writing",
217
+ "searching",
218
+ "running",
219
+ "editing",
199
220
  ]
200
221
  .iter()
201
222
  .any(|needle| lower.contains(needle))
@@ -8,7 +8,9 @@ use serde_json::Value;
8
8
  use crate::event_log::EventLog;
9
9
  use crate::message_store::{MessageStore, NotificationClaimParams};
10
10
  use crate::model::ids::TaskId;
11
- use crate::transport::{InjectPayload, InjectReport, Key, PaneId, Target, Transport, TransportError};
11
+ use crate::transport::{
12
+ InjectPayload, InjectReport, Key, PaneId, Target, Transport, TransportError,
13
+ };
12
14
 
13
15
  use super::helpers::MessageStatusShadow;
14
16
  use super::{DeliveryOutcome, DeliveryRefusal, DeliveryStage, DeliveryStatus, MessagingError};
@@ -405,10 +407,7 @@ pub fn deliver_to_leader_fallback_pane(
405
407
  // Row status is left untouched so status/monitor surfaces the
406
408
  // pending notification until the operator rebinds the leader.
407
409
  let (status, channel) = if socket_bound {
408
- (
409
- DeliveryStatus::Blocked,
410
- "rebind_required".to_string(),
411
- )
410
+ (DeliveryStatus::Blocked, "rebind_required".to_string())
412
411
  } else {
413
412
  (DeliveryStatus::Failed, "fallback_pane".to_string())
414
413
  };
@@ -103,9 +103,8 @@ pub use types::{
103
103
  CheckKind, CheckStatus, ContractSuiteCheck, DeliveryOutcome, DeliveryRefusal, DeliveryStage,
104
104
  DeliveryStatus, IdleEvaluation, LeaderNotificationKey, LeaderReceiver, PaneWidthQuery,
105
105
  ProviderSdkCalls, ReceiverMode, ScheduledKind, SelftestCheck, SelftestReport, SendEventPayload,
106
- TrustRetryPayload, WatcherNotice, WorkerRuntimeState,
107
- RESULT_DELIVERY_MAX_ATTEMPTS, SEND_RETRY_MAX_ATTEMPTS,
108
- TRUST_RETRY_BACKOFF_SECONDS, TRUST_RETRY_MAX_ATTEMPTS,
106
+ TrustRetryPayload, WatcherNotice, WorkerRuntimeState, RESULT_DELIVERY_MAX_ATTEMPTS,
107
+ SEND_RETRY_MAX_ATTEMPTS, TRUST_RETRY_BACKOFF_SECONDS, TRUST_RETRY_MAX_ATTEMPTS,
109
108
  };
110
109
  pub use watchers::{
111
110
  delivered_result_message, format_result_watcher_notification, notify_result_watchers,