@team-agent/installer 0.5.97 → 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 (62) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/src/cli/adapters.rs +0 -64
  4. package/crates/team-agent/src/cli/diagnose.rs +0 -16
  5. package/crates/team-agent/src/cli/emit.rs +15 -42
  6. package/crates/team-agent/src/cli/mod.rs +130 -31
  7. package/crates/team-agent/src/cli/spec.rs +7 -10
  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/mod.rs +0 -1
  11. package/crates/team-agent/src/cli/tests/run_delegation.rs +0 -3
  12. package/crates/team-agent/src/cli/tests/verb_validate.rs +0 -1
  13. package/crates/team-agent/src/cli/types.rs +0 -14
  14. package/crates/team-agent/src/compiler/tests.rs +5 -8
  15. package/crates/team-agent/src/compiler.rs +6 -14
  16. package/crates/team-agent/src/lifecycle/launch/add_agent.rs +1 -1
  17. package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +1 -1
  18. package/crates/team-agent/src/lifecycle/launch/agent_state.rs +5 -25
  19. package/crates/team-agent/src/lifecycle/launch/identity.rs +2 -18
  20. package/crates/team-agent/src/lifecycle/launch/layout.rs +7 -29
  21. package/crates/team-agent/src/lifecycle/launch/leader_context.rs +1 -1
  22. package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +1 -1
  23. package/crates/team-agent/src/lifecycle/launch/ownership.rs +1 -1
  24. package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +7 -7
  25. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +12 -49
  26. package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +3 -9
  27. package/crates/team-agent/src/lifecycle/launch/readiness.rs +1 -1
  28. package/crates/team-agent/src/lifecycle/launch/spawn.rs +2 -61
  29. package/crates/team-agent/src/lifecycle/launch/spec_state.rs +2 -15
  30. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +3 -7
  31. package/crates/team-agent/src/lifecycle/launch/worker_env.rs +1 -1
  32. package/crates/team-agent/src/lifecycle/launch.rs +3 -4
  33. package/crates/team-agent/src/lifecycle/mod.rs +0 -8
  34. package/crates/team-agent/src/lifecycle/restart/agent.rs +62 -8
  35. package/crates/team-agent/src/lifecycle/restart/common.rs +0 -32
  36. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +0 -9
  37. package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +1 -2
  38. package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +0 -1
  39. package/crates/team-agent/src/lifecycle/tests/core.rs +0 -213
  40. package/crates/team-agent/src/lifecycle/tests/issue238_codex_effort_contract.rs +96 -0
  41. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +1 -0
  42. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +31 -77
  43. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -2
  44. package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +4 -8
  45. package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +7 -7
  46. package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +1 -1
  47. package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +3 -4
  48. package/crates/team-agent/src/lifecycle/tests.rs +1 -2
  49. package/crates/team-agent/src/lifecycle/types.rs +3 -133
  50. package/crates/team-agent/src/model/enums.rs +21 -71
  51. package/crates/team-agent/src/model/spec.rs +5 -20
  52. package/crates/team-agent/src/provider/adapters/codex.rs +2 -2
  53. package/crates/team-agent/src/provider/types.rs +6 -5
  54. package/examples/team.spec.yaml +0 -1
  55. package/package.json +4 -4
  56. package/schemas/team.schema.json +2 -2
  57. package/skills/team-agent/SKILL.md +1 -1
  58. package/skills/team-agent/references/team-agent-operator.md +23 -38
  59. package/crates/team-agent/src/cli/tests/compile.rs +0 -192
  60. package/crates/team-agent/src/lifecycle/display.rs +0 -550
  61. package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +0 -884
  62. 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.97"
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.97"
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());
@@ -269,50 +268,6 @@ fn append_reminder(text: String, reminder: &str) -> String {
269
268
  }
270
269
  }
271
270
 
272
- /// `cmd_compile`(`commands.py:42`)。
273
- pub fn cmd_compile(args: &CompileArgs) -> Result<CmdResult, CliError> {
274
- let spec =
275
- crate::compiler::compile_team(&args.team).map_err(|e| CliError::Runtime(e.to_string()))?;
276
- warn_ignored_owner_team_id(&args.team);
277
- std::fs::write(&args.out, crate::model::yaml::dumps(&spec))?;
278
- Ok(CmdResult::from_json(
279
- json!({
280
- "ok": true,
281
- "team_dir": args.team.to_string_lossy().to_string(),
282
- "out": args.out.to_string_lossy().to_string(),
283
- "agents": compiled_agent_ids_for_cli(&spec),
284
- }),
285
- args.json,
286
- ))
287
- }
288
-
289
- fn warn_ignored_owner_team_id(team_dir: &std::path::Path) {
290
- let Ok(Some(ignored)) = crate::compiler::ignored_owner_team_id_from_team_md(team_dir) else {
291
- return;
292
- };
293
- let workspace = crate::model::paths::team_workspace(team_dir)
294
- .unwrap_or_else(|_| team_dir.parent().unwrap_or(team_dir).to_path_buf());
295
- eprintln!(
296
- "Warning: ignored TEAM.md {}={}",
297
- ignored.field, ignored.value
298
- );
299
- eprintln!("Reason: owner identity is the canonical runtime team key, not TEAM.md front matter");
300
- eprintln!("Action: remove {} from TEAM.md", ignored.field);
301
- let fields = json!({
302
- "field": ignored.field,
303
- "source": team_dir.join("TEAM.md").to_string_lossy().to_string(),
304
- "value": ignored.value,
305
- "warning": "ignored user-set owner_team_id",
306
- "reason": "owner identity is derived from the canonical runtime team key",
307
- "action": "remove owner_team_id from TEAM.md",
308
- });
309
- if let Err(err) =
310
- crate::event_log::EventLog::new(&workspace).write("spec.field_ignored", fields)
311
- {
312
- eprintln!("Warning: spec.field_ignored event write failed: {err}");
313
- }
314
- }
315
-
316
271
  /// `cmd_status`(`commands.py:90`)。CLI status 统一为只读七字段 brief;
317
272
  /// `--json` 与人读路径共享 native tmux/process projection;`--summary`/`--detail` 保留参数兼容性但不暴露诊断。
318
273
  #[cfg(test)]
@@ -915,7 +870,6 @@ communication:
915
870
  mirror_files: ".team/messages"
916
871
  runtime:
917
872
  backend: "tmux"
918
- display_backend: "none"
919
873
  session_name: "team-agent-fake-e2e"
920
874
  auto_launch: true
921
875
  require_user_approval_before_launch: false
@@ -968,19 +922,6 @@ fn sessions_overview(state: &Value, spec: Option<&crate::model::yaml::Value>) ->
968
922
  Value::Array(rows)
969
923
  }
970
924
 
971
- fn compiled_agent_ids_for_cli(spec: &crate::model::yaml::Value) -> Vec<String> {
972
- spec.get("agents")
973
- .and_then(crate::model::yaml::Value::as_list)
974
- .map(|agents| {
975
- agents
976
- .iter()
977
- .filter_map(|agent| agent.get("id").and_then(crate::model::yaml::Value::as_str))
978
- .map(str::to_string)
979
- .collect()
980
- })
981
- .unwrap_or_default()
982
- }
983
-
984
925
  fn session_row(
985
926
  state: &Value,
986
927
  spec_agent: &crate::model::yaml::Value,
@@ -1269,7 +1210,6 @@ pub fn cmd_start_agent(args: &StartAgentArgs) -> Result<CmdResult, CliError> {
1269
1210
  &args.workspace,
1270
1211
  &args.agent,
1271
1212
  args.force,
1272
- !args.no_display,
1273
1213
  args.allow_fresh,
1274
1214
  args.team.as_deref(),
1275
1215
  )?;
@@ -1300,7 +1240,6 @@ pub fn cmd_reset_agent(args: &ResetAgentArgs) -> Result<CmdResult, CliError> {
1300
1240
  &args.workspace,
1301
1241
  &args.agent,
1302
1242
  args.discard_session,
1303
- !args.no_display,
1304
1243
  args.team.as_deref(),
1305
1244
  )?,
1306
1245
  args.json,
@@ -1313,7 +1252,6 @@ pub fn cmd_add_agent(args: &AddAgentArgs) -> Result<CmdResult, CliError> {
1313
1252
  &args.workspace,
1314
1253
  &args.agent,
1315
1254
  &args.role_file,
1316
- !args.no_display,
1317
1255
  args.team.as_deref(),
1318
1256
  args.force,
1319
1257
  )?;
@@ -1337,7 +1275,6 @@ pub fn cmd_fork_agent(args: &ForkAgentArgs) -> Result<CmdResult, CliError> {
1337
1275
  &args.source_agent,
1338
1276
  &args.as_agent,
1339
1277
  args.label.as_deref(),
1340
- !args.no_display,
1341
1278
  args.team.as_deref(),
1342
1279
  )?,
1343
1280
  args.json,
@@ -1351,7 +1288,6 @@ pub fn cmd_clone_agent(args: &CloneAgentArgs) -> Result<CmdResult, CliError> {
1351
1288
  &args.source_agent,
1352
1289
  &args.as_agent,
1353
1290
  args.label.as_deref(),
1354
- !args.no_display,
1355
1291
  args.team.as_deref(),
1356
1292
  )?,
1357
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
  };
@@ -174,7 +182,6 @@ fn dispatch(command: &str, args: &[String], cwd: &Path) -> Result<ExitCode, CliE
174
182
  match command {
175
183
  "init" => cmd_init(&init_args(args, cwd)).map(emit_result),
176
184
  "quick-start" => cmd_quick_start(&quick_start_args(args, cwd)?).map(emit_result),
177
- "compile" => cmd_compile(&compile_args(args, cwd)?).map(emit_result),
178
185
  "send" => cmd_send(&send_args(args, cwd)?).map(emit_result),
179
186
  "allow-peer-talk" => {
180
187
  cmd_allow_peer_talk(&allow_peer_talk_args(args, cwd)?).map(emit_result)
@@ -239,7 +246,6 @@ fn dispatch(command: &str, args: &[String], cwd: &Path) -> Result<ExitCode, CliE
239
246
  const DISPATCH_COMMANDS: &[&str] = &[
240
247
  "init",
241
248
  "quick-start",
242
- "compile",
243
249
  "send",
244
250
  "allow-peer-talk",
245
251
  "status",
@@ -399,9 +405,8 @@ fn command_help(command: Option<&str>) -> String {
399
405
  match command {
400
406
  None => default_help(),
401
407
  Some("init") => compat_hidden_help("init", "usage: team-agent init [--workspace WORKSPACE] [--force] [--json]"),
402
- 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(),
403
409
  Some("start") => compat_hidden_help("start", "usage: team-agent start [TEAMDIR] [--yes] [--fresh] [--json]"),
404
- Some("compile") => "usage: team-agent compile --team TEAM [--out FILE] [--json]".to_string(),
405
410
  Some("send") => concat!(
406
411
  "usage: team-agent send TO MESSAGE... ",
407
412
  "[--workspace WORKSPACE] [--team TEAM] ",
@@ -418,13 +423,13 @@ fn command_help(command: Option<&str>) -> String {
418
423
  Some("stop") => compat_hidden_help("stop", "usage: team-agent stop [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]"),
419
424
  Some("shutdown") => "usage: team-agent shutdown [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]".to_string(),
420
425
  Some("restart") => "usage: team-agent restart [WORKSPACE] [--team TEAM] [--allow-fresh] [--session-converge-deadline SECONDS] [--json] [--detail]".to_string(),
421
- Some("restart-agent") => compat_hidden_help("restart-agent", "usage: team-agent restart-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--no-display] [--json]"),
422
- Some("reset-agent") => "usage: team-agent reset-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--no-display] [--json]".to_string(),
423
- 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(),
424
429
  Some("stop-agent") => "usage: team-agent stop-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--json]".to_string(),
425
- 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(),
426
- Some("clone-agent") => "usage: team-agent clone-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]".to_string(),
427
- 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(),
428
433
  Some("remove-agent") => "usage: team-agent remove-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--from-spec] [--confirm] [--force] [--json]".to_string(),
429
434
  // 0.5.26 (§7.6): removed from help; dispatch was never wired.
430
435
  Some("stuck-list") => "usage: team-agent stuck-list [--workspace WORKSPACE] [--team TEAM] [--json]".to_string(),
@@ -827,7 +832,6 @@ struct ParsedArgs {
827
832
  allow_fresh: bool,
828
833
  session_converge_deadline_ms: Option<u64>,
829
834
  force: bool,
830
- no_display: bool,
831
835
  discard_session: bool,
832
836
  role_file: Option<String>,
833
837
  as_agent: Option<String>,
@@ -853,7 +857,6 @@ struct ParsedArgs {
853
857
  result: Option<String>,
854
858
  real: bool,
855
859
  assignee: Option<String>,
856
- out: Option<PathBuf>,
857
860
  auth_mode: Option<String>,
858
861
  proxy_mode: Option<String>,
859
862
  pane: Option<String>,
@@ -919,7 +922,6 @@ fn parse_args(args: &[String]) -> ParsedArgs {
919
922
  next_arg(args, &mut i).and_then(|v| parse_seconds_ms(&v));
920
923
  }
921
924
  "--force" => parsed.force = true,
922
- "--no-display" => parsed.no_display = true,
923
925
  "--backend" => parsed.backend = next_arg(args, &mut i),
924
926
  "--discard-session" => parsed.discard_session = true,
925
927
  "--role-file" => parsed.role_file = next_arg(args, &mut i),
@@ -950,7 +952,6 @@ fn parse_args(args: &[String]) -> ParsedArgs {
950
952
  "--result" => parsed.result = next_arg(args, &mut i),
951
953
  "--real" => parsed.real = true,
952
954
  "--assignee" => parsed.assignee = next_arg(args, &mut i),
953
- "--out" => parsed.out = next_arg(args, &mut i).map(PathBuf::from),
954
955
  "--auth-mode" => parsed.auth_mode = next_arg(args, &mut i),
955
956
  "--proxy-mode" => parsed.proxy_mode = next_arg(args, &mut i),
956
957
  "--pane" => parsed.pane = next_arg(args, &mut i),
@@ -1110,7 +1111,6 @@ fn quick_start_args(args: &[String], cwd: &Path) -> Result<QuickStartArgs, CliEr
1110
1111
  name: parsed.name,
1111
1112
  team_id: parsed.team_id.or(parsed.team),
1112
1113
  yes: parsed.yes,
1113
- no_display: parsed.no_display,
1114
1114
  json: parsed.json,
1115
1115
  detail: parsed.detail,
1116
1116
  backend: parsed.backend,
@@ -1145,23 +1145,6 @@ fn init_args(args: &[String], cwd: &Path) -> InitArgs {
1145
1145
  }
1146
1146
  }
1147
1147
 
1148
- fn compile_args(args: &[String], cwd: &Path) -> Result<CompileArgs, CliError> {
1149
- let parsed = parse_args(args);
1150
- let team = parsed
1151
- .team
1152
- .as_deref()
1153
- .map(PathBuf::from)
1154
- .ok_or_else(|| CliError::Usage("missing --team".to_string()))?;
1155
- let out = parsed
1156
- .out
1157
- .unwrap_or_else(|| PathBuf::from("team.spec.yaml"));
1158
- Ok(CompileArgs {
1159
- team: resolve_cli_path(cwd, &team),
1160
- out: resolve_cli_path(cwd, &out),
1161
- json: parsed.json,
1162
- })
1163
- }
1164
-
1165
1148
  fn resolve_cli_path(cwd: &Path, path: &Path) -> PathBuf {
1166
1149
  if path.is_absolute() {
1167
1150
  path.to_path_buf()
@@ -1549,7 +1532,6 @@ fn start_agent_args(args: &[String], cwd: &Path) -> Result<StartAgentArgs, CliEr
1549
1532
  team: parsed.team,
1550
1533
  force: parsed.force,
1551
1534
  allow_fresh: parsed.allow_fresh,
1552
- no_display: parsed.no_display,
1553
1535
  json: parsed.json,
1554
1536
  })
1555
1537
  }
@@ -1573,7 +1555,6 @@ fn reset_agent_args(args: &[String], cwd: &Path) -> Result<ResetAgentArgs, CliEr
1573
1555
  workspace,
1574
1556
  team: parsed.team,
1575
1557
  discard_session: parsed.discard_session,
1576
- no_display: parsed.no_display,
1577
1558
  json: parsed.json,
1578
1559
  })
1579
1560
  }
@@ -1588,7 +1569,6 @@ fn add_agent_args(args: &[String], cwd: &Path) -> Result<AddAgentArgs, CliError>
1588
1569
  .role_file
1589
1570
  .ok_or_else(|| CliError::Usage("missing --role-file".to_string()))?,
1590
1571
  force: parsed.force,
1591
- no_display: parsed.no_display,
1592
1572
  json: parsed.json,
1593
1573
  })
1594
1574
  }
@@ -1603,7 +1583,6 @@ fn fork_agent_args(args: &[String], cwd: &Path) -> Result<ForkAgentArgs, CliErro
1603
1583
  .as_agent
1604
1584
  .ok_or_else(|| CliError::Usage("missing --as".to_string()))?,
1605
1585
  label: parsed.label,
1606
- no_display: parsed.no_display,
1607
1586
  json: parsed.json,
1608
1587
  })
1609
1588
  }
@@ -1618,7 +1597,6 @@ fn clone_agent_args(args: &[String], cwd: &Path) -> Result<CloneAgentArgs, CliEr
1618
1597
  .as_agent
1619
1598
  .ok_or_else(|| CliError::Usage("missing --as".to_string()))?,
1620
1599
  label: parsed.label,
1621
- no_display: parsed.no_display,
1622
1600
  json: parsed.json,
1623
1601
  })
1624
1602
  }
@@ -2267,7 +2245,6 @@ mod tests {
2267
2245
  "--team",
2268
2246
  "--force",
2269
2247
  "--allow-fresh",
2270
- "--no-display",
2271
2248
  "--json",
2272
2249
  ][..],
2273
2250
  ),
@@ -2277,7 +2254,6 @@ mod tests {
2277
2254
  "--workspace",
2278
2255
  "--team",
2279
2256
  "--discard-session",
2280
- "--no-display",
2281
2257
  "--json",
2282
2258
  ][..],
2283
2259
  ),
@@ -2287,7 +2263,6 @@ mod tests {
2287
2263
  "--role-file",
2288
2264
  "--workspace",
2289
2265
  "--team",
2290
- "--no-display",
2291
2266
  "--json",
2292
2267
  ][..],
2293
2268
  ),
@@ -2298,7 +2273,6 @@ mod tests {
2298
2273
  "--label",
2299
2274
  "--workspace",
2300
2275
  "--team",
2301
- "--no-display",
2302
2276
  "--json",
2303
2277
  ][..],
2304
2278
  ),
@@ -2738,6 +2712,5 @@ mod tests {
2738
2712
  assert_eq!(args.workspace, ws);
2739
2713
  // No `fresh` field anymore — the struct must compile and round-trip
2740
2714
  // without it.
2741
- let _ = args.no_display;
2742
2715
  }
2743
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
  });