@team-agent/installer 0.5.98 → 0.5.99

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 (60) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/src/cli/adapters.rs +0 -7
  4. package/crates/team-agent/src/cli/diagnose.rs +0 -16
  5. package/crates/team-agent/src/cli/emit.rs +15 -20
  6. package/crates/team-agent/src/cli/mod.rs +130 -31
  7. package/crates/team-agent/src/cli/spec.rs +7 -7
  8. package/crates/team-agent/src/cli/tests/main_preserved.rs +0 -1
  9. package/crates/team-agent/src/cli/tests/missing_subcommands.rs +0 -1
  10. package/crates/team-agent/src/cli/tests/run_delegation.rs +0 -3
  11. package/crates/team-agent/src/cli/tests/verb_validate.rs +0 -1
  12. package/crates/team-agent/src/cli/types.rs +0 -6
  13. package/crates/team-agent/src/compiler/tests.rs +5 -8
  14. package/crates/team-agent/src/compiler.rs +6 -14
  15. package/crates/team-agent/src/lifecycle/launch/add_agent.rs +1 -1
  16. package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +1 -1
  17. package/crates/team-agent/src/lifecycle/launch/agent_state.rs +5 -25
  18. package/crates/team-agent/src/lifecycle/launch/identity.rs +2 -18
  19. package/crates/team-agent/src/lifecycle/launch/layout.rs +7 -29
  20. package/crates/team-agent/src/lifecycle/launch/leader_context.rs +1 -1
  21. package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +1 -1
  22. package/crates/team-agent/src/lifecycle/launch/ownership.rs +1 -1
  23. package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +7 -7
  24. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +12 -49
  25. package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +3 -9
  26. package/crates/team-agent/src/lifecycle/launch/readiness.rs +1 -1
  27. package/crates/team-agent/src/lifecycle/launch/spawn.rs +2 -61
  28. package/crates/team-agent/src/lifecycle/launch/spec_state.rs +2 -15
  29. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +3 -7
  30. package/crates/team-agent/src/lifecycle/launch/worker_env.rs +1 -1
  31. package/crates/team-agent/src/lifecycle/launch.rs +3 -4
  32. package/crates/team-agent/src/lifecycle/mod.rs +0 -8
  33. package/crates/team-agent/src/lifecycle/restart/agent.rs +62 -8
  34. package/crates/team-agent/src/lifecycle/restart/common.rs +0 -32
  35. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +0 -9
  36. package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +1 -2
  37. package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +0 -1
  38. package/crates/team-agent/src/lifecycle/tests/core.rs +0 -213
  39. package/crates/team-agent/src/lifecycle/tests/issue238_codex_effort_contract.rs +96 -0
  40. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +1 -0
  41. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +31 -77
  42. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -2
  43. package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +4 -8
  44. package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +7 -7
  45. package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +1 -1
  46. package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +3 -4
  47. package/crates/team-agent/src/lifecycle/tests.rs +1 -2
  48. package/crates/team-agent/src/lifecycle/types.rs +3 -133
  49. package/crates/team-agent/src/model/enums.rs +21 -71
  50. package/crates/team-agent/src/model/spec.rs +5 -20
  51. package/crates/team-agent/src/provider/adapters/codex.rs +2 -2
  52. package/crates/team-agent/src/provider/types.rs +6 -5
  53. package/examples/team.spec.yaml +0 -1
  54. package/package.json +4 -4
  55. package/schemas/team.schema.json +2 -2
  56. package/skills/team-agent/SKILL.md +1 -1
  57. package/skills/team-agent/references/team-agent-operator.md +3 -10
  58. package/crates/team-agent/src/lifecycle/display.rs +0 -550
  59. package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +0 -884
  60. package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +0 -481
package/Cargo.lock CHANGED
@@ -581,7 +581,7 @@ dependencies = [
581
581
 
582
582
  [[package]]
583
583
  name = "team-agent"
584
- version = "0.5.98"
584
+ version = "0.5.99"
585
585
  dependencies = [
586
586
  "anyhow",
587
587
  "chrono",
package/Cargo.toml CHANGED
@@ -9,7 +9,7 @@ members = ["crates/team-agent", "crates/win-conpty-phase0", "crates/conpty-trans
9
9
 
10
10
  [workspace.package]
11
11
  edition = "2021"
12
- version = "0.5.98"
12
+ version = "0.5.99"
13
13
  license = "AGPL-3.0"
14
14
  rust-version = "1.95"
15
15
 
@@ -108,7 +108,6 @@ pub fn cmd_quick_start(args: &QuickStartArgs) -> Result<CmdResult, CliError> {
108
108
  args.name.as_deref(),
109
109
  args.team_id.as_deref(),
110
110
  args.yes,
111
- !args.no_display,
112
111
  args.backend.as_deref(),
113
112
  )?;
114
113
  append_send_guidance(&mut value, &args.workspace, args.team_id.as_deref());
@@ -871,7 +870,6 @@ communication:
871
870
  mirror_files: ".team/messages"
872
871
  runtime:
873
872
  backend: "tmux"
874
- display_backend: "none"
875
873
  session_name: "team-agent-fake-e2e"
876
874
  auto_launch: true
877
875
  require_user_approval_before_launch: false
@@ -1212,7 +1210,6 @@ pub fn cmd_start_agent(args: &StartAgentArgs) -> Result<CmdResult, CliError> {
1212
1210
  &args.workspace,
1213
1211
  &args.agent,
1214
1212
  args.force,
1215
- !args.no_display,
1216
1213
  args.allow_fresh,
1217
1214
  args.team.as_deref(),
1218
1215
  )?;
@@ -1243,7 +1240,6 @@ pub fn cmd_reset_agent(args: &ResetAgentArgs) -> Result<CmdResult, CliError> {
1243
1240
  &args.workspace,
1244
1241
  &args.agent,
1245
1242
  args.discard_session,
1246
- !args.no_display,
1247
1243
  args.team.as_deref(),
1248
1244
  )?,
1249
1245
  args.json,
@@ -1256,7 +1252,6 @@ pub fn cmd_add_agent(args: &AddAgentArgs) -> Result<CmdResult, CliError> {
1256
1252
  &args.workspace,
1257
1253
  &args.agent,
1258
1254
  &args.role_file,
1259
- !args.no_display,
1260
1255
  args.team.as_deref(),
1261
1256
  args.force,
1262
1257
  )?;
@@ -1280,7 +1275,6 @@ pub fn cmd_fork_agent(args: &ForkAgentArgs) -> Result<CmdResult, CliError> {
1280
1275
  &args.source_agent,
1281
1276
  &args.as_agent,
1282
1277
  args.label.as_deref(),
1283
- !args.no_display,
1284
1278
  args.team.as_deref(),
1285
1279
  )?,
1286
1280
  args.json,
@@ -1294,7 +1288,6 @@ pub fn cmd_clone_agent(args: &CloneAgentArgs) -> Result<CmdResult, CliError> {
1294
1288
  &args.source_agent,
1295
1289
  &args.as_agent,
1296
1290
  args.label.as_deref(),
1297
- !args.no_display,
1298
1291
  args.team.as_deref(),
1299
1292
  )?,
1300
1293
  args.json,
@@ -1319,22 +1319,6 @@ pub(crate) fn build_preflight_report(team: &std::path::Path) -> Result<Value, Cl
1319
1319
  next_actions.push(json!("install tmux or add it to PATH"));
1320
1320
  }
1321
1321
 
1322
- let display_backend = compiled
1323
- .as_ref()
1324
- .and_then(|spec| yaml_path_str(spec, &["runtime", "display_backend"]))
1325
- .unwrap_or("none");
1326
- let ghostty_required = display_backend == "ghostty_window" || display_backend == "ghostty";
1327
- let ghostty_path = command_path("ghostty");
1328
- checks.push(json!({
1329
- "name": "ghostty",
1330
- "ok": !ghostty_required || ghostty_path.is_some(),
1331
- "path": ghostty_path,
1332
- "required": ghostty_required,
1333
- }));
1334
- if ghostty_required && ghostty_path.is_none() {
1335
- next_actions.push(json!("install Ghostty or choose another display_backend"));
1336
- }
1337
-
1338
1322
  let workspace = crate::model::paths::team_workspace(team)
1339
1323
  .map_err(|error| CliError::Runtime(error.to_string()))?;
1340
1324
  let profile_dir_exists = workspace
@@ -158,6 +158,14 @@ pub(crate) fn __test_dispatch(
158
158
  }
159
159
 
160
160
  fn dispatch(command: &str, args: &[String], cwd: &Path) -> Result<ExitCode, CliError> {
161
+ // Keep the removed flag harmless for older scripts and persisted command
162
+ // lines; the default tmux backend is already the only runtime path.
163
+ let filtered_args: Vec<String> = args
164
+ .iter()
165
+ .filter(|arg| arg.as_str() != "--no-display")
166
+ .cloned()
167
+ .collect();
168
+ let args = filtered_args.as_slice();
161
169
  let Some(spec) = command_spec(command) else {
162
170
  return Ok(emit_unknown_subcommand_usage(command));
163
171
  };
@@ -397,7 +405,7 @@ fn command_help(command: Option<&str>) -> String {
397
405
  match command {
398
406
  None => default_help(),
399
407
  Some("init") => compat_hidden_help("init", "usage: team-agent init [--workspace WORKSPACE] [--force] [--json]"),
400
- Some("quick-start") => "usage: team-agent quick-start [TEAMDIR] [--workspace WORKSPACE] [--name NAME] [--team-id TEAM|--team TEAM] [--yes] [--no-display] [--backend tmux|conpty] [--json] [--detail]\n\ndefaults: display_backend=adaptive; set display_backend: none in TEAM.md or pass --no-display to use one worker window per agent.\n\n--backend selects the worker transport (Phase 1d Batch 2): tmux (default on POSIX; unchanged behavior), conpty (Windows-native ConPTY worker transport; requires the shim binary and Windows host).\n\n--detail includes internal receiver/topology diagnostics in JSON output.\n\nAfter a successful start, use the returned `send_commands` (or choose an agent explicitly) with `team-agent send AGENT MESSAGE`.".to_string(),
408
+ Some("quick-start") => "usage: team-agent quick-start [TEAMDIR] [--workspace WORKSPACE] [--name NAME] [--team-id TEAM|--team TEAM] [--yes] [--backend tmux|conpty] [--json] [--detail]\n\n--backend selects the worker transport: tmux (default on POSIX) or conpty (Windows-native ConPTY worker transport; requires the shim binary and Windows host).\n\n--detail includes internal receiver/topology diagnostics in JSON output.\n\nAfter a successful start, use the returned `send_commands` (or choose an agent explicitly) with `team-agent send AGENT MESSAGE`.".to_string(),
401
409
  Some("start") => compat_hidden_help("start", "usage: team-agent start [TEAMDIR] [--yes] [--fresh] [--json]"),
402
410
  Some("send") => concat!(
403
411
  "usage: team-agent send TO MESSAGE... ",
@@ -415,13 +423,13 @@ fn command_help(command: Option<&str>) -> String {
415
423
  Some("stop") => compat_hidden_help("stop", "usage: team-agent stop [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]"),
416
424
  Some("shutdown") => "usage: team-agent shutdown [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]".to_string(),
417
425
  Some("restart") => "usage: team-agent restart [WORKSPACE] [--team TEAM] [--allow-fresh] [--session-converge-deadline SECONDS] [--json] [--detail]".to_string(),
418
- Some("restart-agent") => compat_hidden_help("restart-agent", "usage: team-agent restart-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--no-display] [--json]"),
419
- Some("reset-agent") => "usage: team-agent reset-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--no-display] [--json]".to_string(),
420
- Some("start-agent") => "usage: team-agent start-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--force] [--allow-fresh] [--no-display] [--json]\n\nAfter a successful start, use the returned `send_commands` with `team-agent send AGENT MESSAGE`.".to_string(),
426
+ Some("restart-agent") => compat_hidden_help("restart-agent", "usage: team-agent restart-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--json]"),
427
+ Some("reset-agent") => "usage: team-agent reset-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--json]".to_string(),
428
+ Some("start-agent") => "usage: team-agent start-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--force] [--allow-fresh] [--json]\n\nAfter a successful start, use the returned `send_commands` with `team-agent send AGENT MESSAGE`.".to_string(),
421
429
  Some("stop-agent") => "usage: team-agent stop-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--json]".to_string(),
422
- Some("add-agent") => "usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]\n\nAfter a successful add, use the returned `send_commands` with `team-agent send AGENT MESSAGE`.".to_string(),
423
- Some("clone-agent") => "usage: team-agent clone-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]".to_string(),
424
- Some("fork-agent") => "usage: team-agent fork-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]".to_string(),
430
+ Some("add-agent") => "usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--json]\n\nAfter a successful add, use the returned `send_commands` with `team-agent send AGENT MESSAGE`.".to_string(),
431
+ Some("clone-agent") => "usage: team-agent clone-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--json]".to_string(),
432
+ Some("fork-agent") => "usage: team-agent fork-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--json]".to_string(),
425
433
  Some("remove-agent") => "usage: team-agent remove-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--from-spec] [--confirm] [--force] [--json]".to_string(),
426
434
  // 0.5.26 (§7.6): removed from help; dispatch was never wired.
427
435
  Some("stuck-list") => "usage: team-agent stuck-list [--workspace WORKSPACE] [--team TEAM] [--json]".to_string(),
@@ -824,7 +832,6 @@ struct ParsedArgs {
824
832
  allow_fresh: bool,
825
833
  session_converge_deadline_ms: Option<u64>,
826
834
  force: bool,
827
- no_display: bool,
828
835
  discard_session: bool,
829
836
  role_file: Option<String>,
830
837
  as_agent: Option<String>,
@@ -915,7 +922,6 @@ fn parse_args(args: &[String]) -> ParsedArgs {
915
922
  next_arg(args, &mut i).and_then(|v| parse_seconds_ms(&v));
916
923
  }
917
924
  "--force" => parsed.force = true,
918
- "--no-display" => parsed.no_display = true,
919
925
  "--backend" => parsed.backend = next_arg(args, &mut i),
920
926
  "--discard-session" => parsed.discard_session = true,
921
927
  "--role-file" => parsed.role_file = next_arg(args, &mut i),
@@ -1105,7 +1111,6 @@ fn quick_start_args(args: &[String], cwd: &Path) -> Result<QuickStartArgs, CliEr
1105
1111
  name: parsed.name,
1106
1112
  team_id: parsed.team_id.or(parsed.team),
1107
1113
  yes: parsed.yes,
1108
- no_display: parsed.no_display,
1109
1114
  json: parsed.json,
1110
1115
  detail: parsed.detail,
1111
1116
  backend: parsed.backend,
@@ -1527,7 +1532,6 @@ fn start_agent_args(args: &[String], cwd: &Path) -> Result<StartAgentArgs, CliEr
1527
1532
  team: parsed.team,
1528
1533
  force: parsed.force,
1529
1534
  allow_fresh: parsed.allow_fresh,
1530
- no_display: parsed.no_display,
1531
1535
  json: parsed.json,
1532
1536
  })
1533
1537
  }
@@ -1551,7 +1555,6 @@ fn reset_agent_args(args: &[String], cwd: &Path) -> Result<ResetAgentArgs, CliEr
1551
1555
  workspace,
1552
1556
  team: parsed.team,
1553
1557
  discard_session: parsed.discard_session,
1554
- no_display: parsed.no_display,
1555
1558
  json: parsed.json,
1556
1559
  })
1557
1560
  }
@@ -1566,7 +1569,6 @@ fn add_agent_args(args: &[String], cwd: &Path) -> Result<AddAgentArgs, CliError>
1566
1569
  .role_file
1567
1570
  .ok_or_else(|| CliError::Usage("missing --role-file".to_string()))?,
1568
1571
  force: parsed.force,
1569
- no_display: parsed.no_display,
1570
1572
  json: parsed.json,
1571
1573
  })
1572
1574
  }
@@ -1581,7 +1583,6 @@ fn fork_agent_args(args: &[String], cwd: &Path) -> Result<ForkAgentArgs, CliErro
1581
1583
  .as_agent
1582
1584
  .ok_or_else(|| CliError::Usage("missing --as".to_string()))?,
1583
1585
  label: parsed.label,
1584
- no_display: parsed.no_display,
1585
1586
  json: parsed.json,
1586
1587
  })
1587
1588
  }
@@ -1596,7 +1597,6 @@ fn clone_agent_args(args: &[String], cwd: &Path) -> Result<CloneAgentArgs, CliEr
1596
1597
  .as_agent
1597
1598
  .ok_or_else(|| CliError::Usage("missing --as".to_string()))?,
1598
1599
  label: parsed.label,
1599
- no_display: parsed.no_display,
1600
1600
  json: parsed.json,
1601
1601
  })
1602
1602
  }
@@ -2245,7 +2245,6 @@ mod tests {
2245
2245
  "--team",
2246
2246
  "--force",
2247
2247
  "--allow-fresh",
2248
- "--no-display",
2249
2248
  "--json",
2250
2249
  ][..],
2251
2250
  ),
@@ -2255,7 +2254,6 @@ mod tests {
2255
2254
  "--workspace",
2256
2255
  "--team",
2257
2256
  "--discard-session",
2258
- "--no-display",
2259
2257
  "--json",
2260
2258
  ][..],
2261
2259
  ),
@@ -2265,7 +2263,6 @@ mod tests {
2265
2263
  "--role-file",
2266
2264
  "--workspace",
2267
2265
  "--team",
2268
- "--no-display",
2269
2266
  "--json",
2270
2267
  ][..],
2271
2268
  ),
@@ -2276,7 +2273,6 @@ mod tests {
2276
2273
  "--label",
2277
2274
  "--workspace",
2278
2275
  "--team",
2279
- "--no-display",
2280
2276
  "--json",
2281
2277
  ][..],
2282
2278
  ),
@@ -2716,6 +2712,5 @@ mod tests {
2716
2712
  assert_eq!(args.workspace, ws);
2717
2713
  // No `fresh` field anymore — the struct must compile and round-trip
2718
2714
  // without it.
2719
- let _ = args.no_display;
2720
2715
  }
2721
2716
  }
@@ -49,7 +49,7 @@ use crate::messaging::{self, AlertType, MessageTarget, SendOptions, TrustedSende
49
49
  use crate::model::ids::{TaskId, TeamKey};
50
50
 
51
51
  pub(crate) const COMMS_BOUNDARY_TEXT: &str = "validates live pane binding consistency and zero-token comms contracts. Does NOT perform live runtime message round-trip. (zero token, zero pollution)";
52
- pub(crate) const QUICK_START_REMINDER: &str = "Reminder: Do not inspect raw worker terminal output during normal operation. Use team-agent status / inbox / collect instead. Wait for report_result.";
52
+ pub(crate) const QUICK_START_REMINDER: &str = "Reminder: Do not inspect raw worker pane output during normal operation. Use team-agent status / inbox / collect instead. Wait for report_result.";
53
53
  pub(crate) const SEND_REMINDER: &str = "Message delivered. Wait for the worker to report_result. Do not poll the worker terminal with capture-pane.";
54
54
  pub(crate) const STATUS_REMINDER: &str = "Results are finalized automatically; use --watch-result or team-agent inbox AGENT -n 3 for transport fallback. Do not capture-pane worker terminals.";
55
55
 
@@ -133,16 +133,14 @@ pub mod lifecycle_port {
133
133
  name: Option<&str>,
134
134
  team_id: Option<&str>,
135
135
  yes: bool,
136
- open_display: bool,
137
136
  backend: Option<&str>,
138
137
  ) -> Result<Value, CliError> {
139
- match crate::lifecycle::quick_start_in_workspace_with_display_and_backend(
138
+ match crate::lifecycle::quick_start_in_workspace_with_backend(
140
139
  workspace,
141
140
  agents_dir,
142
141
  name,
143
142
  yes,
144
143
  team_id,
145
- open_display,
146
144
  backend,
147
145
  ) {
148
146
  Ok(report) => Ok(quick_start_value(report)),
@@ -1155,10 +1153,7 @@ pub mod lifecycle_port {
1155
1153
  }
1156
1154
  }
1157
1155
  }
1158
- let _ = crate::lifecycle::display::close_team_display_backends(
1159
- &run_workspace,
1160
- session,
1161
- );
1156
+ cleanup_owned_team_windows(&run_workspace, transport, &state, session);
1162
1157
  } else {
1163
1158
  let targets = vec![session.as_str().to_string()];
1164
1159
  let event_log = crate::event_log::EventLog::new(&run_workspace);
@@ -1185,10 +1180,7 @@ pub mod lifecycle_port {
1185
1180
  } else {
1186
1181
  push_unique_session(&mut killed_sessions, session.clone());
1187
1182
  }
1188
- let _ = crate::lifecycle::display::close_team_display_backends(
1189
- &run_workspace,
1190
- session,
1191
- );
1183
+ cleanup_owned_team_windows(&run_workspace, transport, &state, session);
1192
1184
  }
1193
1185
  }
1194
1186
  }
@@ -1473,6 +1465,127 @@ pub mod lifecycle_port {
1473
1465
  Ok(response)
1474
1466
  }
1475
1467
 
1468
+ /// Remove legacy adaptive display windows without reopening a display backend.
1469
+ /// Every target is scoped to the selected transport and passes the same
1470
+ /// ownership/protection audit as the rest of shutdown. Unknown or protected
1471
+ /// targets are intentionally left in place.
1472
+ fn cleanup_owned_team_windows(
1473
+ workspace: &Path,
1474
+ transport: &dyn crate::transport::Transport,
1475
+ state: &Value,
1476
+ session: &crate::transport::SessionName,
1477
+ ) {
1478
+ let Some(agents) = state.get("agents").and_then(Value::as_object) else {
1479
+ return;
1480
+ };
1481
+ let leader_session = state
1482
+ .get("leader_receiver")
1483
+ .and_then(|receiver| receiver.get("session_name"))
1484
+ .and_then(Value::as_str)
1485
+ .filter(|value| !value.is_empty())
1486
+ .unwrap_or_else(|| session.as_str());
1487
+ let leader_panes = collect_state_leader_anchor_pane_ids(
1488
+ state,
1489
+ transport.tmux_endpoint().as_deref(),
1490
+ );
1491
+ let event_log = crate::event_log::EventLog::new(workspace);
1492
+ let team_key = state.get("team_key").and_then(Value::as_str);
1493
+ let generation = state_generation(state);
1494
+ let overview_prefix = format!("team-agent:{}:overview", session.as_str());
1495
+ let mut windows = std::collections::BTreeSet::new();
1496
+ let mut panes = std::collections::BTreeSet::new();
1497
+ for (_agent_id, agent) in agents {
1498
+ let Some(display) = agent.get("display").and_then(Value::as_object) else {
1499
+ continue;
1500
+ };
1501
+ if display.get("backend").and_then(Value::as_str) != Some("adaptive") {
1502
+ continue;
1503
+ }
1504
+ if display.get("status").and_then(Value::as_str) == Some("stopped") {
1505
+ continue;
1506
+ }
1507
+ if let Some(window) = display
1508
+ .get("workspace_window")
1509
+ .or_else(|| display.get("window"))
1510
+ .or_else(|| agent.get("window"))
1511
+ .and_then(Value::as_str)
1512
+ .filter(|value| !value.is_empty())
1513
+ {
1514
+ if window == overview_prefix || window.starts_with(&format!("{overview_prefix}-")) {
1515
+ windows.insert(format!("{leader_session}:{window}"));
1516
+ }
1517
+ }
1518
+ if let Some(pane) = display.get("pane_id").and_then(Value::as_str) {
1519
+ if pane.starts_with('%') && !leader_panes.contains(pane) {
1520
+ panes.insert(pane.to_string());
1521
+ }
1522
+ }
1523
+ }
1524
+ if let Ok(live_windows) = transport.list_windows(&crate::transport::SessionName::new(
1525
+ leader_session.to_string(),
1526
+ )) {
1527
+ for window in live_windows {
1528
+ let name = window.as_str();
1529
+ if name == overview_prefix || name.starts_with(&format!("{overview_prefix}-")) {
1530
+ windows.insert(format!("{leader_session}:{name}"));
1531
+ }
1532
+ }
1533
+ }
1534
+ let live_targets = transport.list_targets().unwrap_or_default();
1535
+ for target in &live_targets {
1536
+ if leader_panes.contains(target.pane_id.as_str()) {
1537
+ continue;
1538
+ }
1539
+ if let Some(window) = target.window_name.as_ref() {
1540
+ if windows.contains(&format!("{}:{}", target.session.as_str(), window.as_str())) {
1541
+ panes.remove(target.pane_id.as_str());
1542
+ }
1543
+ }
1544
+ }
1545
+ for target in windows {
1546
+ let Some((target_session, target_window)) = target.split_once(':') else {
1547
+ continue;
1548
+ };
1549
+ let target = crate::transport::Target::SessionWindow {
1550
+ session: crate::transport::SessionName::new(target_session.to_string()),
1551
+ window: crate::transport::WindowName::new(target_window.to_string()),
1552
+ };
1553
+ let target_text = format!("{target_session}:{target_window}");
1554
+ let audit = crate::kill_audit::pre_kill_audit_scoped(
1555
+ &event_log,
1556
+ transport,
1557
+ "shutdown.legacy_display_window",
1558
+ "kill-window",
1559
+ std::slice::from_ref(&target_text),
1560
+ workspace,
1561
+ team_key,
1562
+ generation,
1563
+ "session_marker+state_display_window+team_tag",
1564
+ "positive workspace/team ownership",
1565
+ );
1566
+ if audit.is_ok() {
1567
+ let _ = transport.kill_window(&target);
1568
+ }
1569
+ }
1570
+ for pane in panes {
1571
+ let audit = crate::kill_audit::pre_kill_audit_scoped(
1572
+ &event_log,
1573
+ transport,
1574
+ "shutdown.legacy_display_pane",
1575
+ "kill-pane",
1576
+ std::slice::from_ref(&pane),
1577
+ workspace,
1578
+ team_key,
1579
+ generation,
1580
+ "state_display_pane+team_session",
1581
+ "positive workspace/team ownership",
1582
+ );
1583
+ if audit.is_ok() {
1584
+ let _ = transport.kill_pane(&crate::transport::PaneId::new(pane));
1585
+ }
1586
+ }
1587
+ }
1588
+
1476
1589
  /// 0.5.x Windows portability Batch 6 Option A: locate and
1477
1590
  /// terminate the ConPTY shim if `state.transport.shim.pid` is
1478
1591
  /// recorded. Returns a JSON blob for the shutdown response so
@@ -2635,7 +2748,6 @@ pub mod lifecycle_port {
2635
2748
  workspace: &Path,
2636
2749
  agent: &str,
2637
2750
  force: bool,
2638
- open_display: bool,
2639
2751
  allow_fresh: bool,
2640
2752
  team: Option<&str>,
2641
2753
  ) -> Result<Value, CliError> {
@@ -2644,7 +2756,7 @@ pub mod lifecycle_port {
2644
2756
  workspace,
2645
2757
  &agent_id,
2646
2758
  force,
2647
- open_display,
2759
+ true,
2648
2760
  allow_fresh,
2649
2761
  team,
2650
2762
  ) {
@@ -2712,7 +2824,6 @@ pub mod lifecycle_port {
2712
2824
  workspace: &Path,
2713
2825
  agent: &str,
2714
2826
  discard_session: bool,
2715
- open_display: bool,
2716
2827
  team: Option<&str>,
2717
2828
  ) -> Result<Value, CliError> {
2718
2829
  let agent_id = crate::model::ids::AgentId::new(agent);
@@ -2720,7 +2831,7 @@ pub mod lifecycle_port {
2720
2831
  workspace,
2721
2832
  &agent_id,
2722
2833
  discard_session,
2723
- open_display,
2834
+ true,
2724
2835
  team,
2725
2836
  ) {
2726
2837
  Ok(crate::lifecycle::ResetAgentOutcome::Reset {
@@ -2763,7 +2874,6 @@ pub mod lifecycle_port {
2763
2874
  workspace: &Path,
2764
2875
  agent: &str,
2765
2876
  role_file: &str,
2766
- open_display: bool,
2767
2877
  team: Option<&str>,
2768
2878
  force: bool,
2769
2879
  ) -> Result<Value, CliError> {
@@ -2772,7 +2882,7 @@ pub mod lifecycle_port {
2772
2882
  workspace,
2773
2883
  &agent_id,
2774
2884
  Path::new(role_file),
2775
- open_display,
2885
+ true,
2776
2886
  team,
2777
2887
  force,
2778
2888
  ) {
@@ -2811,12 +2921,11 @@ pub mod lifecycle_port {
2811
2921
  source_agent: &str,
2812
2922
  as_agent_id: &str,
2813
2923
  label: Option<&str>,
2814
- open_display: bool,
2815
2924
  team: Option<&str>,
2816
2925
  ) -> Result<Value, CliError> {
2817
2926
  let source = crate::model::ids::AgentId::new(source_agent);
2818
2927
  let dest = crate::model::ids::AgentId::new(as_agent_id);
2819
- match crate::lifecycle::fork_agent(workspace, &source, &dest, label, open_display, team) {
2928
+ match crate::lifecycle::fork_agent(workspace, &source, &dest, label, true, team) {
2820
2929
  Ok(report) => Ok(json!({
2821
2930
  "ok": true,
2822
2931
  "source_agent_id": report.source_agent_id.as_str(),
@@ -2833,12 +2942,11 @@ pub mod lifecycle_port {
2833
2942
  source_agent: &str,
2834
2943
  as_agent_id: &str,
2835
2944
  label: Option<&str>,
2836
- open_display: bool,
2837
2945
  team: Option<&str>,
2838
2946
  ) -> Result<Value, CliError> {
2839
2947
  let source = crate::model::ids::AgentId::new(source_agent);
2840
2948
  let dest = crate::model::ids::AgentId::new(as_agent_id);
2841
- match crate::lifecycle::clone_agent(workspace, &source, &dest, label, open_display, team) {
2949
+ match crate::lifecycle::clone_agent(workspace, &source, &dest, label, true, team) {
2842
2950
  Ok(report) => Ok(json!({
2843
2951
  "ok": true,
2844
2952
  "status": "cloned",
@@ -3362,7 +3470,6 @@ pub mod lifecycle_port {
3362
3470
  launch,
3363
3471
  next_actions,
3364
3472
  attach_commands,
3365
- display_backend,
3366
3473
  worker_readiness,
3367
3474
  team,
3368
3475
  } => {
@@ -3502,7 +3609,6 @@ pub mod lifecycle_port {
3502
3609
  "team": team,
3503
3610
  "agent_ids": launch.started.iter().map(|agent| agent.agent_id.as_str()).collect::<Vec<_>>(),
3504
3611
  "dry_run": launch.dry_run,
3505
- "display_backend": display_backend,
3506
3612
  "next_actions": next_actions,
3507
3613
  "attach_commands": attach_commands,
3508
3614
  "reminder": crate::cli::QUICK_START_REMINDER,
@@ -3638,12 +3744,6 @@ pub mod lifecycle_port {
3638
3744
  claude_config_dir: None,
3639
3745
  provider_projects_root: None,
3640
3746
  managed_mcp_config: false,
3641
- layout_window: None,
3642
- layout_index: None,
3643
- pane_index: None,
3644
- display: crate::lifecycle::WorkerDisplay::Blocked {
3645
- reason: crate::lifecycle::AdaptiveBlockReason::AggregatorRebuildFailed,
3646
- },
3647
3747
  }],
3648
3748
  dry_run: false,
3649
3749
  tmux_endpoint: None,
@@ -3655,7 +3755,6 @@ pub mod lifecycle_port {
3655
3755
  }),
3656
3756
  next_actions: Vec::new(),
3657
3757
  attach_commands: Vec::new(),
3658
- display_backend: "none".to_string(),
3659
3758
  worker_readiness: crate::lifecycle::QuickStartReadiness::PendingToolLoad,
3660
3759
  team: "team-demo".to_string(),
3661
3760
  });
@@ -162,7 +162,7 @@ pub(crate) struct CommandSpec {
162
162
  /// numeric slack threshold.
163
163
  #[rustfmt::skip]
164
164
  pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
165
- CommandSpec { name: "quick-start", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::Dispatch(DispatchKind::QuickStart), summary: "start or attach a team from TEAM.md", usage: "usage: team-agent quick-start [TEAMDIR] [--workspace WORKSPACE] [--name NAME] [--team-id TEAM|--team TEAM] [--yes] [--no-display] [--backend tmux|conpty] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
165
+ CommandSpec { name: "quick-start", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::Dispatch(DispatchKind::QuickStart), summary: "start or attach a team from TEAM.md", usage: "usage: team-agent quick-start [TEAMDIR] [--workspace WORKSPACE] [--name NAME] [--team-id TEAM|--team TEAM] [--yes] [--backend tmux|conpty] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
166
166
  CommandSpec { name: "send", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Send), summary: "persist a message for an in-team short name or fully-qualified logical recipient", usage: "usage: team-agent send TO MESSAGE... [--workspace WORKSPACE] [--team TEAM] [--mailbox] [--json]\nTO forms are co-equal: an in-team short name (for example `team-agent send reviewer \"Review\"`) or `<workspace>::<team>/<agent>`.", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: Some("next compatibility release"), action: Some("use positional logical TO and the returned message id"), governance: None },
167
167
  CommandSpec { name: "status", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Status), summary: "show current team status", usage: "usage: team-agent status [AGENT] [--workspace WORKSPACE] [--team TEAM] [--summary|--json] [--detail]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
168
168
  CommandSpec { name: "models", tier: CommandTier::Core, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Models), summary: "list exact provider model ids", usage: "usage: team-agent models [--provider pi|cursor_agent] [QUERY|--search TEXT] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
@@ -170,10 +170,10 @@ pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
170
170
  CommandSpec { name: "wait", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Wait), summary: "block until a task result is stored", usage: "usage: team-agent wait --task TASK [--workspace WORKSPACE] [--json]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
171
171
  CommandSpec { name: "restart", tier: CommandTier::Core, category: CommandCategory::TeamLifecycle, kind: CommandKind::Dispatch(DispatchKind::Restart), summary: "restart the selected team", usage: "usage: team-agent restart [WORKSPACE] [--team TEAM] [--allow-fresh] [--session-converge-deadline SECONDS] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
172
172
  CommandSpec { name: "shutdown", tier: CommandTier::Core, category: CommandCategory::TeamLifecycle, kind: CommandKind::Dispatch(DispatchKind::Shutdown), summary: "stop the selected team", usage: "usage: team-agent shutdown [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
173
- CommandSpec { name: "add-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::AddAgent), summary: "add or force-recreate a worker", usage: "usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
174
- CommandSpec { name: "start-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::StartAgent), summary: "start an existing worker", usage: "usage: team-agent start-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--force] [--allow-fresh] [--no-display] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
173
+ CommandSpec { name: "add-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::AddAgent), summary: "add or force-recreate a worker", usage: "usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
174
+ CommandSpec { name: "start-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::StartAgent), summary: "start an existing worker", usage: "usage: team-agent start-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--force] [--allow-fresh] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
175
175
  CommandSpec { name: "stop-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::StopAgent), summary: "stop a worker", usage: "usage: team-agent stop-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
176
- CommandSpec { name: "reset-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ResetAgent), summary: "reset a worker session", usage: "usage: team-agent reset-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--no-display] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
176
+ CommandSpec { name: "reset-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ResetAgent), summary: "reset a worker session", usage: "usage: team-agent reset-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
177
177
  CommandSpec { name: "diagnose", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::Diagnose), summary: "compatibility alias for doctor", usage: "usage: team-agent doctor [SPEC] [--workspace WORKSPACE] [--team TEAM] [--gate orphans|comms] [--comms] [--fix] [--fix-schema] [--cleanup-orphans] [--confirm] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: Some("doctor"), sunset: None, action: None, governance: None },
178
178
  CommandSpec { name: "claim-leader", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::ClaimLeader), summary: "bind this pane when diagnose reports rebind_required", usage: "usage: team-agent claim-leader [--workspace WORKSPACE] [--team TEAM] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
179
179
  CommandSpec { name: "takeover", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::Takeover), summary: "replace a live leader binding with explicit consent", usage: "usage: team-agent takeover [--workspace WORKSPACE] [--team TEAM] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
@@ -189,7 +189,7 @@ pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
189
189
  CommandSpec { name: "init", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::Init), summary: "legacy bootstrap command", usage: "usage: team-agent init [--workspace WORKSPACE] [--force] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: Some("quick-start"), sunset: Some("C2"), action: Some("use `team-agent quick-start`"), governance: None },
190
190
  CommandSpec { name: "start", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::SpecOnlyAlias { alias_of: "quick-start" }, summary: "legacy start alias", usage: "usage: team-agent start [TEAMDIR] [--yes] [--fresh] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: Some("quick-start"), sunset: Some("C2"), action: Some("use `team-agent quick-start` or `team-agent restart`"), governance: None },
191
191
  CommandSpec { name: "stop", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::Stop), summary: "legacy shutdown alias", usage: "usage: team-agent stop [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: Some("shutdown"), sunset: Some("C2"), action: Some("use `team-agent shutdown`"), governance: None },
192
- CommandSpec { name: "restart-agent", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::RestartAgent), summary: "legacy reset-agent alias", usage: "usage: team-agent restart-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--no-display] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: Some("reset-agent"), sunset: Some("C2"), action: Some("use `team-agent reset-agent`"), governance: None },
192
+ CommandSpec { name: "restart-agent", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::RestartAgent), summary: "legacy reset-agent alias", usage: "usage: team-agent restart-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: Some("reset-agent"), sunset: Some("C2"), action: Some("use `team-agent reset-agent`"), governance: None },
193
193
  CommandSpec { name: "stuck-list", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::StuckList), summary: "legacy stuck alert listing", usage: "usage: team-agent stuck-list [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: Some("C2"), action: Some("use `team-agent diagnose`"), governance: None },
194
194
  CommandSpec { name: "stuck-cancel", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::StuckCancel), summary: "legacy stuck alert suppression", usage: "usage: team-agent stuck-cancel AGENT [--workspace WORKSPACE] [--alert-type stuck|idle_fallback|cross_worker_deadlock|all] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: Some("C2"), action: Some("use the concrete notification action or `team-agent diagnose`"), governance: None },
195
195
  CommandSpec { name: "acknowledge-idle", tier: CommandTier::CompatHidden, category: CommandCategory::Compat, kind: CommandKind::Dispatch(DispatchKind::AcknowledgeIdle), summary: "legacy idle acknowledgement", usage: "usage: team-agent acknowledge-idle [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: Some("C2"), action: Some("use the concrete idle notification action or `team-agent diagnose`"), governance: None },
@@ -197,8 +197,8 @@ pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
197
197
  CommandSpec { name: "doctor", tier: CommandTier::Core, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Doctor), summary: "inspect environment and Team runtime health", usage: "usage: team-agent doctor [SPEC] [--workspace WORKSPACE] [--team TEAM] [--gate orphans|comms] [--comms] [--fix] [--fix-schema] [--cleanup-orphans] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
198
198
  CommandSpec { name: "attach-app-server-leader", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::AttachAppServerLeader), summary: "bind an app-server leader receiver", usage: "usage: team-agent attach-app-server-leader [--workspace WORKSPACE] [--team TEAM] --socket unix:///path.sock --thread-id THREAD_ID [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
199
199
  CommandSpec { name: "remove-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::RemoveAgent), summary: "remove a worker", usage: "usage: team-agent remove-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--from-spec] [--confirm] [--force] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
200
- CommandSpec { name: "fork-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ForkAgent), summary: "fork a worker", usage: "usage: team-agent fork-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
201
- CommandSpec { name: "clone-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::CloneAgent), summary: "clone a worker role into a fresh session", usage: "usage: team-agent clone-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
200
+ CommandSpec { name: "fork-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ForkAgent), summary: "fork a worker", usage: "usage: team-agent fork-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
201
+ CommandSpec { name: "clone-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::CloneAgent), summary: "clone a worker role into a fresh session", usage: "usage: team-agent clone-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
202
202
  CommandSpec { name: "allow-peer-talk", tier: CommandTier::Secondary, category: CommandCategory::Setup, kind: CommandKind::Dispatch(DispatchKind::AllowPeerTalk), summary: "allow direct worker peer talk", usage: "usage: team-agent allow-peer-talk A B [--workspace WORKSPACE] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "capability/config surface" }) },
203
203
  CommandSpec { name: "approvals", tier: CommandTier::Secondary, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Approvals), summary: "inspect provider approval state", usage: "usage: team-agent approvals [AGENT] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "approval diagnostics" }) },
204
204
  CommandSpec { name: "profile", tier: CommandTier::Secondary, category: CommandCategory::Setup, kind: CommandKind::Dispatch(DispatchKind::Profile), summary: "manage provider profiles", usage: "usage: team-agent profile COMMAND NAME [--workspace WORKSPACE] [--team TEAM] [--auth-mode MODE] [--proxy-mode direct|inherit] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "provider/profile setup" }) },
@@ -71,7 +71,6 @@ communication:
71
71
  mirror_files: ".team/messages"
72
72
  runtime:
73
73
  backend: "tmux"
74
- display_backend: "none"
75
74
  session_name: "team-agent-fake-e2e"
76
75
  auto_launch: true
77
76
  require_user_approval_before_launch: false
@@ -239,7 +239,6 @@ communication:
239
239
  mirror_files: ".team/messages"
240
240
  runtime:
241
241
  backend: "tmux"
242
- display_backend: "none"
243
242
  session_name: "team-agent-fake-e2e"
244
243
  auto_launch: true
245
244
  require_user_approval_before_launch: false
@@ -222,7 +222,6 @@ fn cli_quick_start_invokes_real_lifecycle_compiles_spec() {
222
222
  name: None,
223
223
  team_id: None,
224
224
  yes: true,
225
- no_display: false,
226
225
  backend: None,
227
226
  json: true,
228
227
  detail: false,
@@ -258,7 +257,6 @@ fn cli_quick_start_invalid_spec_surfaces_real_compile_error() {
258
257
  name: None,
259
258
  team_id: None,
260
259
  yes: false,
261
- no_display: false,
262
260
  backend: None,
263
261
  json: true,
264
262
  detail: false,
@@ -324,7 +322,6 @@ fn cli_add_agent_duplicate_id_surfaces_real_error() {
324
322
  team: None,
325
323
  role_file: dup_role.to_string_lossy().to_string(),
326
324
  force: false,
327
- no_display: false,
328
325
  json: true,
329
326
  };
330
327
  let text = outcome_text(cmd_add_agent(&args));