@team-agent/installer 0.5.41 → 0.5.43

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 (152) 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 +27 -7
  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 +47 -52
  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/coordinator/tick.rs +19 -1
  51. package/crates/team-agent/src/db/message_store.rs +138 -30
  52. package/crates/team-agent/src/db/migration.rs +249 -61
  53. package/crates/team-agent/src/db/schema.rs +303 -82
  54. package/crates/team-agent/src/diagnose/comms.rs +9 -2
  55. package/crates/team-agent/src/diagnose/mod.rs +1 -3
  56. package/crates/team-agent/src/diagnose/orphans.rs +79 -61
  57. package/crates/team-agent/src/event_log.rs +70 -16
  58. package/crates/team-agent/src/layout/manager.rs +15 -4
  59. package/crates/team-agent/src/layout/mod.rs +4 -4
  60. package/crates/team-agent/src/layout/overlay.rs +10 -3
  61. package/crates/team-agent/src/layout/placement.rs +5 -1
  62. package/crates/team-agent/src/layout/recovery.rs +4 -2
  63. package/crates/team-agent/src/layout/runtime_sessions.rs +7 -7
  64. package/crates/team-agent/src/layout/sessions.rs +17 -9
  65. package/crates/team-agent/src/layout/tmux_endpoint.rs +1 -1
  66. package/crates/team-agent/src/layout/worker_env.rs +52 -19
  67. package/crates/team-agent/src/leader/helpers.rs +7 -1
  68. package/crates/team-agent/src/leader/lease.rs +195 -82
  69. package/crates/team-agent/src/leader/owner_bind.rs +55 -22
  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/start.rs +75 -54
  73. package/crates/team-agent/src/leader/takeover.rs +46 -11
  74. package/crates/team-agent/src/leader/tests/basics.rs +320 -167
  75. package/crates/team-agent/src/leader/tests/byte_findings.rs +361 -219
  76. package/crates/team-agent/src/leader/tests/identity.rs +428 -356
  77. package/crates/team-agent/src/leader/tests/idle.rs +285 -254
  78. package/crates/team-agent/src/leader/tests/lease_api.rs +338 -274
  79. package/crates/team-agent/src/leader/tests/lease_claim.rs +643 -593
  80. package/crates/team-agent/src/leader/tests/mod.rs +115 -99
  81. package/crates/team-agent/src/leader/tests/rediscover.rs +74 -22
  82. package/crates/team-agent/src/leader/tests/wake_start_owner.rs +237 -211
  83. package/crates/team-agent/src/lib.rs +4 -4
  84. package/crates/team-agent/src/lifecycle/display.rs +7 -3
  85. package/crates/team-agent/src/lifecycle/launch.rs +6 -1
  86. package/crates/team-agent/src/lifecycle/mod.rs +9 -1
  87. package/crates/team-agent/src/lifecycle/profile_launch.rs +77 -34
  88. package/crates/team-agent/src/lifecycle/profile_smoke.rs +3 -1
  89. package/crates/team-agent/src/lifecycle/restart/agent.rs +1 -6
  90. package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +1 -4
  91. package/crates/team-agent/src/lifecycle/restart/preflight.rs +6 -5
  92. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +26 -22
  93. package/crates/team-agent/src/lifecycle/restart/remove.rs +45 -35
  94. package/crates/team-agent/src/lifecycle/restart/team_state.rs +63 -17
  95. package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +251 -84
  96. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +198 -48
  97. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +2 -1
  98. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +152 -32
  99. package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +1 -5
  100. package/crates/team-agent/src/lifecycle/tests.rs +2 -2
  101. package/crates/team-agent/src/main.rs +4 -4
  102. package/crates/team-agent/src/mcp_server/lifecycle_tools/agent_ops.rs +47 -20
  103. package/crates/team-agent/src/mcp_server/mod.rs +11 -2
  104. package/crates/team-agent/src/mcp_server/types.rs +14 -3
  105. package/crates/team-agent/src/mcp_server/wire.rs +230 -68
  106. package/crates/team-agent/src/messaging/delivery.rs +20 -18
  107. package/crates/team-agent/src/messaging/helpers.rs +25 -4
  108. package/crates/team-agent/src/messaging/leader_receiver.rs +4 -5
  109. package/crates/team-agent/src/messaging/mod.rs +2 -3
  110. package/crates/team-agent/src/messaging/selftest.rs +46 -26
  111. package/crates/team-agent/src/messaging/tests/main_preserved.rs +47 -12
  112. package/crates/team-agent/src/messaging/tests/runtime.rs +57 -22
  113. package/crates/team-agent/src/messaging/tests/spine.rs +154 -40
  114. package/crates/team-agent/src/messaging/tests/wave2.rs +31 -32
  115. package/crates/team-agent/src/messaging/trust.rs +25 -2
  116. package/crates/team-agent/src/messaging/watchers.rs +37 -9
  117. package/crates/team-agent/src/model/enums.rs +65 -16
  118. package/crates/team-agent/src/model/ids.rs +12 -3
  119. package/crates/team-agent/src/model/paths.rs +28 -7
  120. package/crates/team-agent/src/model/permissions.rs +176 -33
  121. package/crates/team-agent/src/model/routing.rs +66 -20
  122. package/crates/team-agent/src/model/spec.rs +365 -69
  123. package/crates/team-agent/src/model/task_graph.rs +36 -9
  124. package/crates/team-agent/src/model/yaml/tests.rs +24 -6
  125. package/crates/team-agent/src/model/yaml.rs +7 -6
  126. package/crates/team-agent/src/packaging/install.rs +23 -9
  127. package/crates/team-agent/src/packaging/migrate.rs +5 -7
  128. package/crates/team-agent/src/packaging/mod.rs +9 -1
  129. package/crates/team-agent/src/packaging/repair.rs +13 -6
  130. package/crates/team-agent/src/packaging/tests.rs +63 -16
  131. package/crates/team-agent/src/packaging/types.rs +22 -7
  132. package/crates/team-agent/src/platform/argv.rs +4 -1
  133. package/crates/team-agent/src/platform/file_lock.rs +22 -8
  134. package/crates/team-agent/src/platform/process.rs +21 -22
  135. package/crates/team-agent/src/provider/adapters/claude.rs +1 -3
  136. package/crates/team-agent/src/provider/approvals/parsing.rs +134 -26
  137. package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +13 -3
  138. package/crates/team-agent/src/provider/classify.rs +127 -42
  139. package/crates/team-agent/src/provider/faults.rs +17 -5
  140. package/crates/team-agent/src/provider/helpers.rs +6 -5
  141. package/crates/team-agent/src/provider/startup_prompt.rs +75 -27
  142. package/crates/team-agent/src/state/repository.rs +27 -14
  143. package/crates/team-agent/src/tmux_backend/tests.rs +1637 -1398
  144. package/crates/team-agent/src/tmux_backend.rs +80 -44
  145. package/crates/team-agent/src/topology.rs +27 -20
  146. package/crates/team-agent/src/transport/test_support.rs +20 -23
  147. package/crates/team-agent/src/transport/tests/behavior.rs +292 -293
  148. package/crates/team-agent/src/transport/tests/mod.rs +178 -187
  149. package/crates/team-agent/src/transport/tests/wire.rs +561 -525
  150. package/crates/team-agent/src/transport.rs +12 -17
  151. package/crates/team-agent/src/transport_factory.rs +29 -14
  152. package/package.json +4 -4
@@ -80,14 +80,15 @@ pub fn leader_start_plan(
80
80
  if !in_tmux {
81
81
  ensure_tmux_installed()?;
82
82
  }
83
- let existing_session = if external_path && !in_tmux && !attach_existing && attach_session.is_none() {
84
- match session_name.as_ref() {
85
- Some(session) => tmux_session_exists(workspace, session)?,
86
- None => false,
87
- }
88
- } else {
89
- false
90
- };
83
+ let existing_session =
84
+ if external_path && !in_tmux && !attach_existing && attach_session.is_none() {
85
+ match session_name.as_ref() {
86
+ Some(session) => tmux_session_exists(workspace, session)?,
87
+ None => false,
88
+ }
89
+ } else {
90
+ false
91
+ };
91
92
  let mode = if !external_path && in_tmux {
92
93
  LeaderStartMode::ExecProvider
93
94
  } else if !external_path {
@@ -342,7 +343,9 @@ fn start_argv(
342
343
  }
343
344
  LeaderStartMode::ManagedTmuxClient => {
344
345
  let Some(session) = session_name else {
345
- return Err(LeaderError::Start("managed leader session missing".to_string()));
346
+ return Err(LeaderError::Start(
347
+ "managed leader session missing".to_string(),
348
+ ));
346
349
  };
347
350
  managed_client_argv(workspace, session, provider)
348
351
  }
@@ -402,7 +405,9 @@ fn provider_command_argv(provider: Provider, provider_args: &[String]) -> Vec<St
402
405
  fn normalized_provider_args(provider_args: &[String]) -> impl Iterator<Item = String> + '_ {
403
406
  provider_args
404
407
  .iter()
405
- .skip(usize::from(provider_args.first().is_some_and(|arg| arg == "--")))
408
+ .skip(usize::from(
409
+ provider_args.first().is_some_and(|arg| arg == "--"),
410
+ ))
406
411
  .cloned()
407
412
  }
408
413
 
@@ -444,10 +449,14 @@ fn execute_managed_leader_plan(
444
449
  workspace: &Path,
445
450
  ) -> Result<LeaderLaunchOutcome, LeaderError> {
446
451
  let Some(session) = plan.session_name.as_ref() else {
447
- return Err(LeaderError::Start("managed leader session missing".to_string()));
452
+ return Err(LeaderError::Start(
453
+ "managed leader session missing".to_string(),
454
+ ));
448
455
  };
449
456
  let Some(window) = plan.leader_window.as_ref() else {
450
- return Err(LeaderError::Start("managed leader window missing".to_string()));
457
+ return Err(LeaderError::Start(
458
+ "managed leader window missing".to_string(),
459
+ ));
451
460
  };
452
461
  // 0.5.x Phase 1d Batch 6: use the factory tmux channel helper
453
462
  // (thin wrapper over `TmuxBackend::for_workspace`) for
@@ -854,9 +863,15 @@ fn persist_exec_provider_leader_binding(
854
863
  });
855
864
  if let Some(target) = target.as_ref() {
856
865
  if let Some(obj) = receiver.as_object_mut() {
857
- obj.insert("session_name".to_string(), serde_json::json!(target.session.as_str()));
866
+ obj.insert(
867
+ "session_name".to_string(),
868
+ serde_json::json!(target.session.as_str()),
869
+ );
858
870
  if let Some(window_name) = target.window_name.as_ref() {
859
- obj.insert("window_name".to_string(), serde_json::json!(window_name.as_str()));
871
+ obj.insert(
872
+ "window_name".to_string(),
873
+ serde_json::json!(window_name.as_str()),
874
+ );
860
875
  }
861
876
  }
862
877
  }
@@ -881,7 +896,10 @@ fn persist_exec_provider_leader_binding(
881
896
  serde_json::json!(identity.team_id.as_str()),
882
897
  );
883
898
  if let Some(target) = target.as_ref() {
884
- obj.insert("session_name".to_string(), serde_json::json!(target.session.as_str()));
899
+ obj.insert(
900
+ "session_name".to_string(),
901
+ serde_json::json!(target.session.as_str()),
902
+ );
885
903
  }
886
904
  if let Some(socket) = socket.as_ref() {
887
905
  obj.insert("tmux_endpoint".to_string(), serde_json::json!(socket));
@@ -1006,10 +1024,9 @@ fn refresh_managed_leader_provider_binding(
1006
1024
  plan: &LeaderStartPlan,
1007
1025
  workspace: &Path,
1008
1026
  ) -> Result<(), LeaderError> {
1009
- let identity = plan
1010
- .identity
1011
- .as_ref()
1012
- .ok_or_else(|| LeaderError::Start("managed leader re-entry identity missing".to_string()))?;
1027
+ let identity = plan.identity.as_ref().ok_or_else(|| {
1028
+ LeaderError::Start("managed leader re-entry identity missing".to_string())
1029
+ })?;
1013
1030
  let pane = std::env::var("TMUX_PANE")
1014
1031
  .ok()
1015
1032
  .filter(|value| !value.trim().is_empty())
@@ -1029,8 +1046,16 @@ fn refresh_managed_leader_provider_binding(
1029
1046
  let existing_epoch = state
1030
1047
  .pointer(&format!("/teams/{team_key}/owner_epoch"))
1031
1048
  .and_then(serde_json::Value::as_u64)
1032
- .or_else(|| existing_owner.get("owner_epoch").and_then(serde_json::Value::as_u64))
1033
- .or_else(|| existing_receiver.get("owner_epoch").and_then(serde_json::Value::as_u64))
1049
+ .or_else(|| {
1050
+ existing_owner
1051
+ .get("owner_epoch")
1052
+ .and_then(serde_json::Value::as_u64)
1053
+ })
1054
+ .or_else(|| {
1055
+ existing_receiver
1056
+ .get("owner_epoch")
1057
+ .and_then(serde_json::Value::as_u64)
1058
+ })
1034
1059
  .unwrap_or(0);
1035
1060
  let now = chrono::Utc::now().to_rfc3339();
1036
1061
  let provider = serde_json::to_value(plan.provider)?;
@@ -1050,9 +1075,15 @@ fn refresh_managed_leader_provider_binding(
1050
1075
  obj.entry("leader_session_uuid".to_string())
1051
1076
  .or_insert_with(|| serde_json::json!(identity.leader_session_uuid.as_str()));
1052
1077
  if let Some(target) = target.as_ref() {
1053
- obj.insert("session_name".to_string(), serde_json::json!(target.session.as_str()));
1078
+ obj.insert(
1079
+ "session_name".to_string(),
1080
+ serde_json::json!(target.session.as_str()),
1081
+ );
1054
1082
  if let Some(window_name) = target.window_name.as_ref() {
1055
- obj.insert("window_name".to_string(), serde_json::json!(window_name.as_str()));
1083
+ obj.insert(
1084
+ "window_name".to_string(),
1085
+ serde_json::json!(window_name.as_str()),
1086
+ );
1056
1087
  }
1057
1088
  if let Some(pane_pid) = target.pane_pid {
1058
1089
  obj.insert("pane_pid".to_string(), serde_json::json!(pane_pid));
@@ -1117,7 +1148,9 @@ fn persist_external_leader_topology_marker(
1117
1148
  .unwrap_or_else(|_| serde_json::json!({}));
1118
1149
  if let Some(obj) = state.as_object_mut() {
1119
1150
  obj.entry("workspace".to_string()).or_insert_with(|| {
1120
- serde_json::json!(resolve_workspace_for_hash(workspace).to_string_lossy().to_string())
1151
+ serde_json::json!(resolve_workspace_for_hash(workspace)
1152
+ .to_string_lossy()
1153
+ .to_string())
1121
1154
  });
1122
1155
  obj.entry("active_team_key".to_string())
1123
1156
  .or_insert_with(|| serde_json::json!(identity.team_id.as_str()));
@@ -1231,12 +1264,7 @@ fn spawn_managed_provider_startup_prompt_handler(
1231
1264
  // grep-visibility. Semantics unchanged.
1232
1265
  let transport = crate::transport_factory::tmux_workspace_transport(&workspace);
1233
1266
  let _ = handle_exec_provider_startup_prompts(
1234
- provider,
1235
- &workspace,
1236
- &pane_id,
1237
- &transport,
1238
- 30,
1239
- 0.5,
1267
+ provider, &workspace, &pane_id, &transport, 30, 0.5,
1240
1268
  );
1241
1269
  });
1242
1270
  }
@@ -1671,10 +1699,8 @@ mod tests {
1671
1699
 
1672
1700
  #[test]
1673
1701
  fn external_exec_provider_persists_topology_before_provider_exec() {
1674
- let workspace = std::env::temp_dir().join(format!(
1675
- "ta-external-pre-exec-{}",
1676
- std::process::id()
1677
- ));
1702
+ let workspace =
1703
+ std::env::temp_dir().join(format!("ta-external-pre-exec-{}", std::process::id()));
1678
1704
  std::fs::create_dir_all(&workspace).unwrap();
1679
1705
  let state_path = crate::state::persist::runtime_state_path(&workspace);
1680
1706
  let command = format!(
@@ -1716,17 +1742,18 @@ mod tests {
1716
1742
  assert_eq!(outcome.status, crate::leader::LeaderLaunchStatus::Exited);
1717
1743
  let state = crate::state::persist::load_runtime_state(&workspace).unwrap();
1718
1744
  assert_eq!(state["is_external_leader"], serde_json::json!(true));
1719
- assert_eq!(state["teams"]["current"]["is_external_leader"], serde_json::json!(true));
1745
+ assert_eq!(
1746
+ state["teams"]["current"]["is_external_leader"],
1747
+ serde_json::json!(true)
1748
+ );
1720
1749
  let _ = std::fs::remove_dir_all(&workspace);
1721
1750
  }
1722
1751
 
1723
1752
  #[test]
1724
1753
  #[serial_test::serial(env)]
1725
1754
  fn default_exec_provider_persists_current_pane_binding_before_provider_exec() {
1726
- let workspace = std::env::temp_dir().join(format!(
1727
- "ta-current-pane-pre-exec-{}",
1728
- std::process::id()
1729
- ));
1755
+ let workspace =
1756
+ std::env::temp_dir().join(format!("ta-current-pane-pre-exec-{}", std::process::id()));
1730
1757
  std::fs::create_dir_all(&workspace).unwrap();
1731
1758
  let state_path = crate::state::persist::runtime_state_path(&workspace);
1732
1759
  let command = format!(
@@ -1834,14 +1861,13 @@ mod tests {
1834
1861
  // managed path must still match LEADER_SESSION_PREFIX so the
1835
1862
  // shutdown / cli/mod.rs prefix matchers still classify it as a
1836
1863
  // leader session.
1837
- let workspace = std::env::temp_dir().join(format!(
1838
- "ta_rs_mgr_prefix_{}",
1839
- std::process::id()
1840
- ));
1864
+ let workspace =
1865
+ std::env::temp_dir().join(format!("ta_rs_mgr_prefix_{}", std::process::id()));
1841
1866
  let _ = std::fs::create_dir_all(&workspace);
1842
1867
  let name = super::managed_leader_session_name(Provider::ClaudeCode, &workspace);
1843
1868
  assert!(
1844
- name.as_str().starts_with(super::super::LEADER_SESSION_PREFIX),
1869
+ name.as_str()
1870
+ .starts_with(super::super::LEADER_SESSION_PREFIX),
1845
1871
  "managed session name must carry LEADER_SESSION_PREFIX (`{}`); \
1846
1872
  got `{}`",
1847
1873
  super::super::LEADER_SESSION_PREFIX,
@@ -1859,10 +1885,8 @@ mod tests {
1859
1885
  fn managed_leader_session_name_is_unique_per_call() {
1860
1886
  // Two consecutive calls must return DIFFERENT names — the
1861
1887
  // per-launch nonce defeats the mirror-session bug.
1862
- let workspace = std::env::temp_dir().join(format!(
1863
- "ta_rs_mgr_unique_{}",
1864
- std::process::id()
1865
- ));
1888
+ let workspace =
1889
+ std::env::temp_dir().join(format!("ta_rs_mgr_unique_{}", std::process::id()));
1866
1890
  let _ = std::fs::create_dir_all(&workspace);
1867
1891
  let a = super::managed_leader_session_name(Provider::ClaudeCode, &workspace);
1868
1892
  // Sleep > 1ns to ensure epoch_nanos advances even on coarse clocks.
@@ -1885,10 +1909,8 @@ mod tests {
1885
1909
  // External / attach paths must keep the stable workspace-keyed
1886
1910
  // name — `--attach-session <name>` reattach would break if the
1887
1911
  // name varied per call.
1888
- let workspace = std::env::temp_dir().join(format!(
1889
- "ta_rs_lsn_stable_{}",
1890
- std::process::id()
1891
- ));
1912
+ let workspace =
1913
+ std::env::temp_dir().join(format!("ta_rs_lsn_stable_{}", std::process::id()));
1892
1914
  let _ = std::fs::create_dir_all(&workspace);
1893
1915
  let a = super::leader_session_name(Provider::ClaudeCode, &workspace);
1894
1916
  let b = super::leader_session_name(Provider::ClaudeCode, &workspace);
@@ -1911,8 +1933,7 @@ mod tests {
1911
1933
  fn managed_path_uses_nonce_session_name_grep_guard() {
1912
1934
  let manifest = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
1913
1935
  let start_rs = manifest.join("src").join("leader").join("start.rs");
1914
- let contents =
1915
- std::fs::read_to_string(&start_rs).expect("read leader/start.rs");
1936
+ let contents = std::fs::read_to_string(&start_rs).expect("read leader/start.rs");
1916
1937
  // leader_start_plan must dispatch to managed_leader_session_name
1917
1938
  // on the managed path.
1918
1939
  let start = contents
@@ -34,7 +34,11 @@ pub fn build_idle_nodes(
34
34
  ) {
35
35
  continue;
36
36
  }
37
- let Some(provider) = agent.get("provider").and_then(Value::as_str).and_then(parse_provider) else {
37
+ let Some(provider) = agent
38
+ .get("provider")
39
+ .and_then(Value::as_str)
40
+ .and_then(parse_provider)
41
+ else {
38
42
  continue;
39
43
  };
40
44
  let rollout_path = agent
@@ -50,7 +54,10 @@ pub fn build_idle_nodes(
50
54
  turn_id: classification.turn_id,
51
55
  annotations: classification.annotations,
52
56
  provider: Some(provider),
53
- auth_mode: agent.get("auth_mode").and_then(Value::as_str).map(str::to_string),
57
+ auth_mode: agent
58
+ .get("auth_mode")
59
+ .and_then(Value::as_str)
60
+ .map(str::to_string),
54
61
  rollout_path,
55
62
  });
56
63
  }
@@ -72,12 +79,20 @@ pub fn leader_node(
72
79
  let provider = leader
73
80
  .and_then(|l| l.get("provider"))
74
81
  .and_then(Value::as_str)
75
- .or_else(|| receiver.and_then(|r| r.get("provider")).and_then(Value::as_str))
82
+ .or_else(|| {
83
+ receiver
84
+ .and_then(|r| r.get("provider"))
85
+ .and_then(Value::as_str)
86
+ })
76
87
  .and_then(parse_provider);
77
88
  let rollout_path = leader
78
89
  .and_then(|l| l.get("rollout_path"))
79
90
  .and_then(Value::as_str)
80
- .or_else(|| receiver.and_then(|r| r.get("rollout_path")).and_then(Value::as_str))
91
+ .or_else(|| {
92
+ receiver
93
+ .and_then(|r| r.get("rollout_path"))
94
+ .and_then(Value::as_str)
95
+ })
81
96
  .map(|p| RolloutPath::new(PathBuf::from(p)));
82
97
  let (Some(provider), Some(rollout_path)) = (provider, rollout_path) else {
83
98
  return Ok(None);
@@ -108,7 +123,10 @@ pub fn classify_provider_turn_state(
108
123
  event_log: Option<&crate::event_log::EventLog>,
109
124
  ) -> Result<TurnClassification, LeaderError> {
110
125
  let classification = classifier.classify(provider, session_log_text)?;
111
- if matches!(classification.state, TurnState::Unknown | TurnState::Abnormal) {
126
+ if matches!(
127
+ classification.state,
128
+ TurnState::Unknown | TurnState::Abnormal
129
+ ) {
112
130
  if let Some(log) = event_log {
113
131
  log.write(
114
132
  LeaderEvent::IdleTakeoverClassify.name(),
@@ -171,7 +189,9 @@ pub fn evaluate_takeover_reminder(
171
189
  .collect();
172
190
  Ok(TakeoverReminderResult {
173
191
  should_ping: true,
174
- message: Some("All active nodes appear idle; leader takeover may be appropriate.".to_string()),
192
+ message: Some(
193
+ "All active nodes appear idle; leader takeover may be appropriate.".to_string(),
194
+ ),
175
195
  interrupted_nodes,
176
196
  reason: Some("all_idle_debounce_elapsed".to_string()),
177
197
  })
@@ -211,19 +231,34 @@ pub fn should_reread(
211
231
  ) -> RereadDecision {
212
232
  let _ = last_mtime;
213
233
  let Some(current) = current_mtime else {
214
- return RereadDecision { reread: false, reason: RereadReason::NoFile };
234
+ return RereadDecision {
235
+ reread: false,
236
+ reason: RereadReason::NoFile,
237
+ };
215
238
  };
216
239
  let Some(classified) = last_classified_mtime else {
217
- return RereadDecision { reread: true, reason: RereadReason::NeverClassified };
240
+ return RereadDecision {
241
+ reread: true,
242
+ reason: RereadReason::NeverClassified,
243
+ };
218
244
  };
219
245
  if current != classified {
220
- return RereadDecision { reread: true, reason: RereadReason::FileChanged };
246
+ return RereadDecision {
247
+ reread: true,
248
+ reason: RereadReason::FileChanged,
249
+ };
221
250
  }
222
251
  let silent_for = (now - current).max(0.0);
223
252
  if silent_for >= debounce_seconds {
224
- RereadDecision { reread: false, reason: RereadReason::QuiescentAlreadyClassified }
253
+ RereadDecision {
254
+ reread: false,
255
+ reason: RereadReason::QuiescentAlreadyClassified,
256
+ }
225
257
  } else {
226
- RereadDecision { reread: false, reason: RereadReason::Unchanged }
258
+ RereadDecision {
259
+ reread: false,
260
+ reason: RereadReason::Unchanged,
261
+ }
227
262
  }
228
263
  }
229
264