@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
@@ -67,7 +67,6 @@ communication:
67
67
  mirror_files: ".team/messages"
68
68
  runtime:
69
69
  backend: "tmux"
70
- display_backend: "none"
71
70
  session_name: "team-agent-fake-e2e"
72
71
  auto_launch: true
73
72
  require_user_approval_before_launch: false
@@ -295,7 +295,6 @@ pub struct QuickStartArgs {
295
295
  pub name: Option<String>,
296
296
  pub team_id: Option<String>,
297
297
  pub yes: bool,
298
- pub no_display: bool,
299
298
  pub json: bool,
300
299
  /// Include internal receiver/topology diagnostics in the response.
301
300
  pub detail: bool,
@@ -489,7 +488,6 @@ pub struct StartAgentArgs {
489
488
  pub team: Option<String>,
490
489
  pub force: bool,
491
490
  pub allow_fresh: bool,
492
- pub no_display: bool,
493
491
  pub json: bool,
494
492
  }
495
493
 
@@ -509,7 +507,6 @@ pub struct ResetAgentArgs {
509
507
  pub workspace: PathBuf,
510
508
  pub team: Option<String>,
511
509
  pub discard_session: bool,
512
- pub no_display: bool,
513
510
  pub json: bool,
514
511
  }
515
512
 
@@ -521,7 +518,6 @@ pub struct AddAgentArgs {
521
518
  pub team: Option<String>,
522
519
  pub role_file: String,
523
520
  pub force: bool,
524
- pub no_display: bool,
525
521
  pub json: bool,
526
522
  }
527
523
 
@@ -533,7 +529,6 @@ pub struct ForkAgentArgs {
533
529
  pub team: Option<String>,
534
530
  pub as_agent: String,
535
531
  pub label: Option<String>,
536
- pub no_display: bool,
537
532
  pub json: bool,
538
533
  }
539
534
 
@@ -544,7 +539,6 @@ pub struct CloneAgentArgs {
544
539
  pub team: Option<String>,
545
540
  pub as_agent: String,
546
541
  pub label: Option<String>,
547
- pub no_display: bool,
548
542
  pub json: bool,
549
543
  }
550
544
 
@@ -190,7 +190,7 @@ fn front_matter_non_object_errors() {
190
190
  // separators=(",",":"))` with the workspace path templated to __WS__.
191
191
  // (team-agent-public v0.2.11, /tmp/probe_compiler.py.)
192
192
 
193
- const BASE_NOPROFILE_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks and report result_envelope_v1.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","display_backend":"adaptive","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
193
+ const BASE_NOPROFILE_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks and report result_envelope_v1.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
194
194
 
195
195
  #[test]
196
196
  fn compile_base_noprofile_matches_python_dict_order_and_values() {
@@ -237,7 +237,6 @@ default_model: gpt-5.4
237
237
  default_auth_mode: subscription
238
238
  dangerous_auto_approve: true
239
239
  fast: true
240
- display_backend: ghostty_window
241
240
  tick_interval_sec: 1
242
241
  push_min_interval_sec: 3
243
242
  stuck_timeout_sec: 5
@@ -261,7 +260,7 @@ dangerously_skip_permissions: false
261
260
  Implement bounded tasks.
262
261
  ";
263
262
 
264
- const RUNTIME_DEFAULTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.4","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","display_backend":"ghostty_window","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":true,"tick_interval_sec":1,"push_min_interval_sec":3,"stuck_timeout_sec":5},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
263
+ const RUNTIME_DEFAULTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.4","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":true,"tick_interval_sec":1,"push_min_interval_sec":3,"stuck_timeout_sec":5},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
265
264
 
266
265
  #[test]
267
266
  fn compile_runtime_front_matter_defaults_match_python() {
@@ -283,7 +282,6 @@ objective: Compile thin role docs.
283
282
  provider_models:
284
283
  claude: claude-sonnet-4-6
285
284
  default_auth_mode: subscription
286
- display_backend: none
287
285
  ---
288
286
 
289
287
  Team config.
@@ -302,7 +300,7 @@ dangerously_skip_permissions: false
302
300
  Edit and defend the argument.
303
301
  ";
304
302
 
305
- const ALIAS_JSON: &str = r#"{"version":1,"team":{"name":"debate-team","mode":"supervisor_worker","objective":"Compile thin role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"editor","role":"Editor and Defender","provider":"claude_code","model":"claude-sonnet-4-6","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Edit and defend the argument.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["editor","Editor and Defender"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"editor","rules":[{"id":"route-editor","match":{"assignee":["editor"]},"assign_to":"editor","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","display_backend":"none","session_name":"team-debate-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["editor"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"editor","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
303
+ const ALIAS_JSON: &str = r#"{"version":1,"team":{"name":"debate-team","mode":"supervisor_worker","objective":"Compile thin role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"editor","role":"Editor and Defender","provider":"claude_code","model":"claude-sonnet-4-6","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Edit and defend the argument.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["editor","Editor and Defender"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"editor","rules":[{"id":"route-editor","match":{"assignee":["editor"]},"assign_to":"editor","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-debate-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["editor"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"editor","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
306
304
 
307
305
  #[test]
308
306
  fn compile_provider_models_claude_code_falls_back_to_claude_alias() {
@@ -316,7 +314,6 @@ const BUILTIN_TEAM: &str = "\
316
314
  ---
317
315
  name: default-model-team
318
316
  objective: Compile role docs without model fields.
319
- display_backend: none
320
317
  ---
321
318
 
322
319
  Team config.
@@ -336,7 +333,7 @@ tools:
336
333
  Implement bounded tasks.
337
334
  ";
338
335
 
339
- const BUILTIN_JSON: &str = r#"{"version":1,"team":{"name":"default-model-team","mode":"supervisor_worker","objective":"Compile role docs without model fields.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","display_backend":"none","session_name":"team-default-model-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
336
+ const BUILTIN_JSON: &str = r#"{"version":1,"team":{"name":"default-model-team","mode":"supervisor_worker","objective":"Compile role docs without model fields.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-default-model-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
340
337
 
341
338
  #[test]
342
339
  fn compile_subscription_without_model_uses_builtin_provider_default() {
@@ -378,7 +375,7 @@ tools:
378
375
  Bravo body.
379
376
  ";
380
377
 
381
- const TWO_AGENTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"alpha","role":"Alpha Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Alpha body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["alpha","Alpha Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}},{"id":"bravo","role":"Bravo Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Bravo body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["bravo","Bravo Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"alpha","rules":[{"id":"route-alpha","match":{"assignee":["alpha"]},"assign_to":"alpha","priority":10},{"id":"route-bravo","match":{"assignee":["bravo"]},"assign_to":"bravo","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","display_backend":"adaptive","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":2,"startup_order":["alpha","bravo"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"alpha","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
378
+ const TWO_AGENTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"alpha","role":"Alpha Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Alpha body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["alpha","Alpha Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}},{"id":"bravo","role":"Bravo Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Bravo body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["bravo","Bravo Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"alpha","rules":[{"id":"route-alpha","match":{"assignee":["alpha"]},"assign_to":"alpha","priority":10},{"id":"route-bravo","match":{"assignee":["bravo"]},"assign_to":"bravo","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":2,"startup_order":["alpha","bravo"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"alpha","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
382
379
 
383
380
  #[test]
384
381
  fn compile_two_agents_sorted_by_filename_with_routing_and_startup_order() {
@@ -203,7 +203,7 @@ pub fn compile_team(team_dir: &Path) -> Result<Value, ModelError> {
203
203
  let value = raw.trim();
204
204
  let parsed = ProviderEffort::parse(value).ok_or_else(|| {
205
205
  ModelError::Validation(format!(
206
- "{}: unknown provider_effort '{value}' (allowed: low|medium|high|xhigh|max)",
206
+ "{}: unknown provider_effort '{value}' (allowed: low|medium|high|xhigh|max|ultra)",
207
207
  team_md.display()
208
208
  ))
209
209
  })?;
@@ -280,13 +280,6 @@ pub fn compile_team(team_dir: &Path) -> Result<Value, ModelError> {
280
280
  "runtime",
281
281
  map(vec![
282
282
  ("backend", Value::Str("tmux".to_string())),
283
- (
284
- "display_backend",
285
- Value::Str(
286
- string_field(&team_meta, "display_backend")
287
- .unwrap_or_else(|| "adaptive".to_string()),
288
- ),
289
- ),
290
283
  (
291
284
  "session_name",
292
285
  Value::Str(session_name(&team_meta, &team_name)),
@@ -565,16 +558,15 @@ fn compile_role_agent_with_mode(
565
558
  if let Some(profile) = string_field(&meta, "profile") {
566
559
  agent_items.push(("profile", Value::Str(profile)));
567
560
  }
568
- // 0.4.x provider effort MVP step 3: resolve effort with role > team > none.
569
- // Validate (unknown literal) AND check provider/effort compatibility
570
- // (max is Claude-only; emit hard error for max + non-Claude here so
571
- // unsupported combinations fail at compile, not at runtime).
561
+ // 0.4.x provider effort MVP step 3: resolve effort with role > team > none
562
+ // (Pi uses only explicit role effort). Validate syntax and provider support
563
+ // here so unsupported combinations fail at compile, not at runtime.
572
564
  let role_effort = match string_field(&meta, "effort") {
573
565
  Some(raw) if !raw.trim().is_empty() => {
574
566
  let value = raw.trim();
575
567
  let parsed = ProviderEffort::parse(value).ok_or_else(|| {
576
568
  ModelError::Validation(format!(
577
- "{}: unknown effort '{value}' (allowed: low|medium|high|xhigh|max)",
569
+ "{}: unknown effort '{value}' (allowed: low|medium|high|xhigh|max|ultra)",
578
570
  role_path.display()
579
571
  ))
580
572
  })?;
@@ -592,7 +584,7 @@ fn compile_role_agent_with_mode(
592
584
  role_effort.or(team_effort)
593
585
  };
594
586
  if let Some(effort) = resolved_effort {
595
- // Reject max + non-Claude at compile time.
587
+ // Apply the shared provider admission policy at compile time.
596
588
  let provider_str = agent_items
597
589
  .iter()
598
590
  .find(|(k, _)| *k == "provider")
@@ -29,7 +29,7 @@ use std::process::Command;
29
29
  use std::time::{SystemTime, UNIX_EPOCH};
30
30
 
31
31
  use crate::lifecycle::*;
32
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
32
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
33
33
  use crate::model::ids::AgentId;
34
34
  use crate::model::yaml::{self, Value};
35
35
  use crate::state::persist::load_runtime_state;
@@ -26,7 +26,7 @@ use std::path::{Path, PathBuf};
26
26
  use std::process::Command;
27
27
 
28
28
  use crate::lifecycle::*;
29
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
29
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
30
30
  use crate::model::ids::AgentId;
31
31
  use crate::model::yaml::{self, Value};
32
32
  use crate::state::persist::load_runtime_state;
@@ -22,11 +22,11 @@ use std::path::{Path, PathBuf};
22
22
  use std::process::Command;
23
23
 
24
24
  use crate::lifecycle::*;
25
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
25
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
26
26
  use crate::model::ids::AgentId;
27
27
  use crate::model::yaml::{self, Value};
28
28
  use crate::state::persist::load_runtime_state;
29
- use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
29
+ use crate::transport::{PaneId, SessionName, Target, Transport};
30
30
 
31
31
  use crate::lifecycle::lock::{acquire_agent_lifecycle_lock, LifecycleLockRequest};
32
32
 
@@ -64,10 +64,9 @@ pub(super) fn running_agent_state(
64
64
  .get("profile")
65
65
  .map(yaml_value_to_json)
66
66
  .unwrap_or(serde_json::Value::Null);
67
- let window = started_agent
68
- .and_then(|started| started.layout_window.as_ref())
69
- .map(WindowName::as_str)
70
- .or_else(|| agent.get("window").and_then(Value::as_str))
67
+ let window = agent
68
+ .get("window")
69
+ .and_then(Value::as_str)
71
70
  .unwrap_or(id);
72
71
  let mcp_config = crate::provider::get_adapter(provider)
73
72
  .mcp_config(auth_mode)
@@ -129,25 +128,6 @@ pub(super) fn running_agent_state(
129
128
  );
130
129
  if let Some(started_agent) = started_agent {
131
130
  persist_started_agent_plan_state(&mut state, started_agent);
132
- if let Some(layout_window) = started_agent.layout_window.as_ref() {
133
- state.insert(
134
- "layout_window".to_string(),
135
- serde_json::json!(layout_window.as_str()),
136
- );
137
- }
138
- if let Some(layout_index) = started_agent.layout_index {
139
- state.insert("layout_index".to_string(), serde_json::json!(layout_index));
140
- }
141
- if let Some(pane_index) = started_agent.pane_index {
142
- state.insert("pane_index".to_string(), serde_json::json!(pane_index));
143
- }
144
- if !matches!(started_agent.display, WorkerDisplay::Blocked { .. }) {
145
- state.insert(
146
- "display".to_string(),
147
- serde_json::to_value(&started_agent.display)
148
- .map_err(|e| LifecycleError::StatePersist(e.to_string()))?,
149
- );
150
- }
151
131
  }
152
132
  state.insert(
153
133
  "spawn_cwd".to_string(),
@@ -1,5 +1,5 @@
1
1
  //! ---
2
- //! purpose: team 与席位的身份取值,团队键、display 后端、auth_mode、effort 与 quick-start 层级判定
2
+ //! purpose: team 与席位的身份取值,团队键、auth_mode、effort 与 quick-start 层级判定
3
3
  //! contract:
4
4
  //! provides:
5
5
  //! - name: spec_team_id
@@ -18,7 +18,6 @@
18
18
  //! - crate::state::projection
19
19
  //! - crate::state::persist
20
20
  //! - crate::state::repository
21
- //! - crate::lifecycle::display
22
21
  //! - crate::provider::wire
23
22
  //! boundary:
24
23
  //! - 只做身份判定与取值,不 spawn、不开显示
@@ -31,7 +30,7 @@ use std::path::{Path, PathBuf};
31
30
  use std::process::Command;
32
31
 
33
32
  use crate::lifecycle::*;
34
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
33
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
35
34
  use crate::model::ids::AgentId;
36
35
  use crate::model::yaml::{self, Value};
37
36
  use crate::state::persist::load_runtime_state;
@@ -99,21 +98,6 @@ pub(super) fn transport_has_session(transport: &dyn Transport, session_name: &Se
99
98
  }
100
99
  }
101
100
 
102
- /// ---
103
- /// purpose: 取 spec 请求的显示后端并交给 display 解析
104
- /// returns: 解析后的后端,spec 未写或写了未知值时为默认 adaptive
105
- /// ---
106
- pub(super) fn spec_display_backend(spec: &Value) -> DisplayBackend {
107
- let requested = spec
108
- .get("runtime")
109
- .and_then(|runtime| runtime.get("display_backend"))
110
- .and_then(Value::as_str)
111
- .and_then(|backend| {
112
- serde_json::from_value::<DisplayBackend>(serde_json::json!(backend)).ok()
113
- });
114
- crate::lifecycle::display::resolve_display_backend(requested, None).backend
115
- }
116
-
117
101
  use crate::provider::wire::parse_provider;
118
102
 
119
103
  /// ---
@@ -23,7 +23,7 @@ use std::path::{Path, PathBuf};
23
23
  use std::process::Command;
24
24
 
25
25
  use crate::lifecycle::*;
26
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
26
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
27
27
  use crate::model::ids::AgentId;
28
28
  use crate::model::yaml::{self, Value};
29
29
  use crate::state::persist::load_runtime_state;
@@ -72,31 +72,10 @@ pub(crate) fn adaptive_layout_plan(
72
72
 
73
73
  pub(crate) const ADAPTIVE_LAYOUT_MAX_PER_WINDOW: usize = 3;
74
74
 
75
- /// ---
76
- /// purpose: 判断该 state 是否在用 adaptive 布局
77
- /// returns: 顶层或 runtime 段的 display_backend 为 adaptive,或任一席位带非空 layout_window 时为 true
78
- /// ---
79
- pub(crate) fn state_uses_adaptive_layout(state: &serde_json::Value) -> bool {
80
- state
81
- .get("display_backend")
82
- .and_then(serde_json::Value::as_str)
83
- .is_some_and(|backend| backend == "adaptive")
84
- || state
85
- .get("runtime")
86
- .and_then(|runtime| runtime.get("display_backend"))
87
- .and_then(serde_json::Value::as_str)
88
- .is_some_and(|backend| backend == "adaptive")
89
- || state
90
- .get("agents")
91
- .and_then(serde_json::Value::as_object)
92
- .is_some_and(|agents| {
93
- agents.values().any(|agent| {
94
- agent
95
- .get("layout_window")
96
- .and_then(serde_json::Value::as_str)
97
- .is_some_and(|window| !window.is_empty())
98
- })
99
- })
75
+ /// Adaptive display layout was removed; existing state is always resumed in
76
+ /// the per-agent window topology.
77
+ pub(crate) fn state_uses_adaptive_layout(_state: &serde_json::Value) -> bool {
78
+ false
100
79
  }
101
80
 
102
81
  /// ---
@@ -204,9 +183,8 @@ pub(crate) fn adaptive_placement_for_agent(
204
183
  });
205
184
  }
206
185
  }
207
- // E45 (0.3.24 bug#4): when the live session has NO real adaptive layout
208
- // window (the topology is effectively per-agent, even though state says
209
- // display_backend=adaptive), DO NOT synthesise a fresh `team-w<N>`
186
+ // When the live session has no real layout window, do not synthesise
187
+ // a fresh `team-w<N>`
210
188
  // window — that would force the new agent into an adaptive-layout pane
211
189
  // shape the rest of the session does not actually use. Return None so
212
190
  // the caller (`start_agent_at_paths` → `spawn_agent_window`) falls back
@@ -29,7 +29,7 @@ use std::process::Command;
29
29
 
30
30
  use crate::lifecycle::profile_launch::parse_provider;
31
31
  use crate::lifecycle::*;
32
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
32
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
33
33
  use crate::model::ids::AgentId;
34
34
  use crate::model::yaml::{self, Value};
35
35
  use crate::state::persist::load_runtime_state;
@@ -31,7 +31,7 @@ use std::path::{Path, PathBuf};
31
31
  use std::process::Command;
32
32
 
33
33
  use crate::lifecycle::*;
34
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
34
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
35
35
  use crate::model::yaml::{self, Value};
36
36
  use crate::state::persist::load_runtime_state;
37
37
  use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
@@ -23,7 +23,7 @@ use std::path::{Path, PathBuf};
23
23
  use std::process::Command;
24
24
 
25
25
  use crate::lifecycle::*;
26
- use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
26
+ use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
27
27
  use crate::model::ids::AgentId;
28
28
  use crate::model::yaml::{self, Value};
29
29
  use crate::state::persist::load_runtime_state;
@@ -26,7 +26,7 @@ use std::time::{Duration, Instant};
26
26
 
27
27
  use sha2::{Digest, Sha256};
28
28
 
29
- use crate::model::enums::ProviderEffort;
29
+ use crate::model::enums::{Provider, ProviderEffort};
30
30
  use crate::provider::adapters::pi::{build_pi_command_argv, PiCommandRequest, PiSessionSelector};
31
31
  use crate::provider::{CommandPlan, McpConfig, ProviderError, SessionId};
32
32
 
@@ -559,12 +559,12 @@ pub(crate) fn parse_pi_leader_args(args: &[String]) -> Result<PiLeaderArgs, Prov
559
559
  match flag {
560
560
  "--model" if model.is_none() => model = Some(value.clone()),
561
561
  "--thinking" if effort.is_none() => {
562
- effort = ProviderEffort::parse(value);
563
- if effort.is_none() {
564
- return Err(ProviderError::Command(format!(
565
- "unknown Pi thinking effort {value:?}"
566
- )));
567
- }
562
+ let parsed = ProviderEffort::parse(value).ok_or_else(|| {
563
+ ProviderError::Command(format!("unknown Pi thinking effort {value:?}"))
564
+ })?;
565
+ effort = parsed
566
+ .resolve_for_provider(Provider::Pi)
567
+ .map_err(|reason| ProviderError::Command(reason.to_string()))?;
568
568
  }
569
569
  _ => {
570
570
  return Err(ProviderError::Command(format!(