@team-agent/installer 0.5.106 → 0.5.108
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.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/src/cli/adapters.rs +1 -1
- package/crates/team-agent/src/cli/emit.rs +3 -3
- package/crates/team-agent/src/cli/mod.rs +87 -4
- package/crates/team-agent/src/cli/models.rs +252 -3
- package/crates/team-agent/src/cli/spec.rs +1 -1
- package/crates/team-agent/src/cli/status_port/brief.rs +155 -37
- package/crates/team-agent/src/cli/tests/base.rs +112 -225
- package/crates/team-agent/src/cli/tests/shutdown_kill_plan.rs +184 -0
- package/crates/team-agent/src/cli/tests/status_brief.rs +624 -0
- package/crates/team-agent/src/compiler/tests.rs +46 -59
- package/crates/team-agent/src/leader/tests/byte_findings.rs +1 -14
- package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +57 -173
- package/crates/team-agent/src/lifecycle/launch/pi_mcp_extension.js +226 -0
- package/crates/team-agent/src/lifecycle/launch/quick_start.rs +0 -37
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +0 -9
- package/crates/team-agent/src/lifecycle/tests/fixtures/pi_native_mcp_host.mjs +71 -0
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +0 -66
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +0 -392
- package/crates/team-agent/src/lifecycle/tests/lifecycle_lock.rs +0 -5
- package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +2 -361
- package/crates/team-agent/src/lifecycle/tests/pi_dual_entry_red.rs +1 -16
- package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +20 -112
- package/crates/team-agent/src/lifecycle/tests/pi_fork_session_inheritance_red.rs +1 -12
- package/crates/team-agent/src/lifecycle/tests/pi_native_mcp_capability_red.rs +546 -0
- package/crates/team-agent/src/lifecycle/tests.rs +1 -0
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +11 -54
- package/crates/team-agent/src/messaging/tests/wave2.rs +2 -302
- package/crates/team-agent/src/model/name_similarity.rs +52 -67
- package/crates/team-agent/src/model/task_graph.rs +37 -124
- package/crates/team-agent/src/model/yaml/tests.rs +46 -165
- package/crates/team-agent/src/provider/model_catalog.rs +166 -3
- package/crates/team-agent/src/provider/testdata/cursor-list-models-native.stdout +250 -0
- package/crates/team-agent/src/provider/testdata/grok-models-authenticated.stdout +9 -0
- package/crates/team-agent/src/provider/testdata/grok-models-unauthenticated.stdout +7 -0
- package/crates/team-agent/src/provider/tests/adapter.rs +0 -20
- package/crates/team-agent/src/provider/tests/classify.rs +106 -198
- package/crates/team-agent/src/tmux_backend/tests.rs +178 -501
- package/crates/team-agent/src/transport/tests/wire.rs +0 -55
- package/package.json +4 -4
|
@@ -2800,130 +2800,6 @@ fn fork_refuses_source_with_partial_tuple() {
|
|
|
2800
2800
|
);
|
|
2801
2801
|
}
|
|
2802
2802
|
|
|
2803
|
-
#[test]
|
|
2804
|
-
#[ignore = "legacy adaptive display layout contract removed; runtime is silent tmux only"]
|
|
2805
|
-
fn add_agent_adaptive_splits_last_non_full_layout_window() {
|
|
2806
|
-
let roles = [("w1.md", role_doc("w1")), ("w2.md", role_doc("w2"))];
|
|
2807
|
-
let role_refs = roles
|
|
2808
|
-
.iter()
|
|
2809
|
-
.map(|(file, doc)| (*file, doc.as_str()))
|
|
2810
|
-
.collect::<Vec<_>>();
|
|
2811
|
-
let team = quick_start_team_dir_with_roles(&role_refs);
|
|
2812
|
-
let session = "team-layout-add";
|
|
2813
|
-
crate::state::persist::save_runtime_state(
|
|
2814
|
-
&team,
|
|
2815
|
-
&json!({
|
|
2816
|
-
"session_name": session,
|
|
2817
|
-
"legacy_display_key": "adaptive",
|
|
2818
|
-
"active_team_key": "teamdir",
|
|
2819
|
-
"agents": {
|
|
2820
|
-
"w1": {"status": "running", "provider": "codex", "window": "team-w1", "layout_window": "team-w1", "layout_index": 0, "pane_index": 0, "pane_id": "%1"},
|
|
2821
|
-
"w2": {"status": "running", "provider": "codex", "window": "team-w1", "layout_window": "team-w1", "layout_index": 0, "pane_index": 1, "pane_id": "%2"}
|
|
2822
|
-
}
|
|
2823
|
-
}),
|
|
2824
|
-
)
|
|
2825
|
-
.unwrap();
|
|
2826
|
-
seed_healthy_coordinator(&team);
|
|
2827
|
-
let role_file = team.join("w3-role.md");
|
|
2828
|
-
std::fs::write(&role_file, role_doc("w3")).unwrap();
|
|
2829
|
-
let transport = OfflineTransport::new()
|
|
2830
|
-
.with_session_present(true)
|
|
2831
|
-
.with_targets(vec![
|
|
2832
|
-
layout_pane(session, "team-w1", "%1", 0),
|
|
2833
|
-
layout_pane(session, "team-w1", "%2", 1),
|
|
2834
|
-
])
|
|
2835
|
-
.with_pane_presence("%1", true)
|
|
2836
|
-
.with_pane_presence("%2", true);
|
|
2837
|
-
|
|
2838
|
-
add_agent_with_transport(
|
|
2839
|
-
&team,
|
|
2840
|
-
&AgentId::new("w3"),
|
|
2841
|
-
&role_file,
|
|
2842
|
-
true,
|
|
2843
|
-
None,
|
|
2844
|
-
&transport,
|
|
2845
|
-
)
|
|
2846
|
-
.expect("adaptive add-agent should start");
|
|
2847
|
-
|
|
2848
|
-
assert_eq!(
|
|
2849
|
-
transport.spawn_window_records().last(),
|
|
2850
|
-
Some(&(String::from("spawn_split"), String::from("team-w1"))),
|
|
2851
|
-
"last non-full layout window should be split"
|
|
2852
|
-
);
|
|
2853
|
-
let (_raw, state) = raw_runtime_state(&team);
|
|
2854
|
-
assert_eq!(
|
|
2855
|
-
state.pointer("/agents/w3/layout_window"),
|
|
2856
|
-
Some(&json!("team-w1"))
|
|
2857
|
-
);
|
|
2858
|
-
assert_eq!(state.pointer("/agents/w3/pane_index"), Some(&json!(2)));
|
|
2859
|
-
}
|
|
2860
|
-
|
|
2861
|
-
#[test]
|
|
2862
|
-
#[ignore = "legacy adaptive display layout contract removed; runtime is silent tmux only"]
|
|
2863
|
-
fn add_agent_adaptive_creates_suffix_window_when_last_layout_full_and_name_collides() {
|
|
2864
|
-
let roles = [
|
|
2865
|
-
("w1.md", role_doc("w1")),
|
|
2866
|
-
("w2.md", role_doc("w2")),
|
|
2867
|
-
("w3.md", role_doc("w3")),
|
|
2868
|
-
];
|
|
2869
|
-
let role_refs = roles
|
|
2870
|
-
.iter()
|
|
2871
|
-
.map(|(file, doc)| (*file, doc.as_str()))
|
|
2872
|
-
.collect::<Vec<_>>();
|
|
2873
|
-
let team = quick_start_team_dir_with_roles(&role_refs);
|
|
2874
|
-
let session = "team-layout-add-full";
|
|
2875
|
-
crate::state::persist::save_runtime_state(
|
|
2876
|
-
&team,
|
|
2877
|
-
&json!({
|
|
2878
|
-
"session_name": session,
|
|
2879
|
-
"legacy_display_key": "adaptive",
|
|
2880
|
-
"active_team_key": "teamdir",
|
|
2881
|
-
"agents": {
|
|
2882
|
-
"w1": {"status": "running", "provider": "codex", "window": "team-w1", "layout_window": "team-w1", "layout_index": 0, "pane_index": 0, "pane_id": "%1"},
|
|
2883
|
-
"w2": {"status": "running", "provider": "codex", "window": "team-w1", "layout_window": "team-w1", "layout_index": 0, "pane_index": 1, "pane_id": "%2"},
|
|
2884
|
-
"w3": {"status": "running", "provider": "codex", "window": "team-w1", "layout_window": "team-w1", "layout_index": 0, "pane_index": 2, "pane_id": "%3"}
|
|
2885
|
-
}
|
|
2886
|
-
}),
|
|
2887
|
-
)
|
|
2888
|
-
.unwrap();
|
|
2889
|
-
seed_healthy_coordinator(&team);
|
|
2890
|
-
let role_file = team.join("w4-role.md");
|
|
2891
|
-
std::fs::write(&role_file, role_doc("w4")).unwrap();
|
|
2892
|
-
let transport = OfflineTransport::new()
|
|
2893
|
-
.with_session_present(true)
|
|
2894
|
-
.with_targets(vec![
|
|
2895
|
-
layout_pane(session, "team-w1", "%1", 0),
|
|
2896
|
-
layout_pane(session, "team-w1", "%2", 1),
|
|
2897
|
-
layout_pane(session, "team-w1", "%3", 2),
|
|
2898
|
-
layout_pane(session, "team-w2", "%9", 0),
|
|
2899
|
-
])
|
|
2900
|
-
.with_pane_presence("%1", true)
|
|
2901
|
-
.with_pane_presence("%2", true)
|
|
2902
|
-
.with_pane_presence("%3", true);
|
|
2903
|
-
|
|
2904
|
-
add_agent_with_transport(
|
|
2905
|
-
&team,
|
|
2906
|
-
&AgentId::new("w4"),
|
|
2907
|
-
&role_file,
|
|
2908
|
-
true,
|
|
2909
|
-
None,
|
|
2910
|
-
&transport,
|
|
2911
|
-
)
|
|
2912
|
-
.expect("adaptive add-agent should start");
|
|
2913
|
-
|
|
2914
|
-
assert_eq!(
|
|
2915
|
-
transport.spawn_window_records().last(),
|
|
2916
|
-
Some(&(String::from("spawn_into"), String::from("team-w2-2"))),
|
|
2917
|
-
"full last layout window should create next window with collision suffix"
|
|
2918
|
-
);
|
|
2919
|
-
let (_raw, state) = raw_runtime_state(&team);
|
|
2920
|
-
assert_eq!(
|
|
2921
|
-
state.pointer("/agents/w4/layout_window"),
|
|
2922
|
-
Some(&json!("team-w2-2"))
|
|
2923
|
-
);
|
|
2924
|
-
assert_eq!(state.pointer("/agents/w4/pane_index"), Some(&json!(0)));
|
|
2925
|
-
}
|
|
2926
|
-
|
|
2927
2803
|
#[test]
|
|
2928
2804
|
fn stop_agent_adaptive_kills_target_pane_not_shared_layout_window() {
|
|
2929
2805
|
let roles = [("w1.md", role_doc("w1")), ("w2.md", role_doc("w2"))];
|
|
@@ -2978,55 +2854,6 @@ fn stop_agent_adaptive_kills_target_pane_not_shared_layout_window() {
|
|
|
2978
2854
|
);
|
|
2979
2855
|
}
|
|
2980
2856
|
|
|
2981
|
-
#[test]
|
|
2982
|
-
#[ignore = "legacy adaptive display layout contract removed; runtime is silent tmux only"]
|
|
2983
|
-
fn start_agent_adaptive_restarts_missing_pane_in_existing_layout_window() {
|
|
2984
|
-
let ws = temp_ws();
|
|
2985
|
-
crate::state::persist::save_runtime_state(
|
|
2986
|
-
&ws,
|
|
2987
|
-
&json!({
|
|
2988
|
-
"session_name": "team-layout-restart",
|
|
2989
|
-
"legacy_display_key": "adaptive",
|
|
2990
|
-
"agents": {
|
|
2991
|
-
"w1": {"status": "running", "provider": "codex", "role": "w1", "model": "gpt-5.5", "auth_mode": "subscription", "window": "team-w1", "layout_window": "team-w1", "layout_index": 0, "pane_index": 0, "pane_id": "%1"},
|
|
2992
|
-
"w2": {"status": "running", "provider": "codex", "role": "w2", "model": "gpt-5.5", "auth_mode": "subscription", "window": "team-w1", "layout_window": "team-w1", "layout_index": 0, "pane_index": 1, "pane_id": "%2"}
|
|
2993
|
-
}
|
|
2994
|
-
}),
|
|
2995
|
-
)
|
|
2996
|
-
.unwrap();
|
|
2997
|
-
seed_healthy_coordinator(&ws);
|
|
2998
|
-
let transport = OfflineTransport::new()
|
|
2999
|
-
.with_session_present(true)
|
|
3000
|
-
.with_targets(vec![layout_pane("team-layout-restart", "team-w1", "%2", 1)])
|
|
3001
|
-
.with_pane_presence("%1", false)
|
|
3002
|
-
.with_pane_presence("%2", true);
|
|
3003
|
-
|
|
3004
|
-
let outcome = start_agent_with_transport(
|
|
3005
|
-
&ws,
|
|
3006
|
-
&AgentId::new("w1"),
|
|
3007
|
-
false,
|
|
3008
|
-
true,
|
|
3009
|
-
true,
|
|
3010
|
-
None,
|
|
3011
|
-
&transport,
|
|
3012
|
-
)
|
|
3013
|
-
.expect("adaptive restart should spawn");
|
|
3014
|
-
|
|
3015
|
-
assert!(matches!(outcome, StartAgentOutcome::Running { .. }));
|
|
3016
|
-
assert_eq!(
|
|
3017
|
-
transport.spawn_window_records().last(),
|
|
3018
|
-
Some(&(String::from("spawn_split"), String::from("team-w1"))),
|
|
3019
|
-
"missing worker pane should be rebuilt in its existing layout window"
|
|
3020
|
-
);
|
|
3021
|
-
let (_raw, state) = raw_runtime_state(&ws);
|
|
3022
|
-
assert_eq!(
|
|
3023
|
-
state.pointer("/agents/w1/layout_window"),
|
|
3024
|
-
Some(&json!("team-w1"))
|
|
3025
|
-
);
|
|
3026
|
-
assert_eq!(state.pointer("/agents/w1/window"), Some(&json!("team-w1")));
|
|
3027
|
-
assert_eq!(state.pointer("/agents/w2/pane_id"), Some(&json!("%2")));
|
|
3028
|
-
}
|
|
3029
|
-
|
|
3030
2857
|
// ═════════════════════════════════════════════════════════════════════════
|
|
3031
2858
|
// WAVE 2 · LANE A — agent-lifecycle byte-parity contracts. stop_agent / reset_agent / remove_agent /
|
|
3032
2859
|
// fork_agent are stubs (OwnerRefused / RequirementUnmet / "session_id missing"). These RED contracts
|
|
@@ -3714,175 +3541,6 @@ fn e43_adaptive_placement_skips_existing_agent_whose_live_pane_window_name_diffe
|
|
|
3714
3541
|
}
|
|
3715
3542
|
}
|
|
3716
3543
|
|
|
3717
|
-
/// **Regression guard — Fix A**: when an existing agent's live pane DOES
|
|
3718
|
-
/// reside under the claimed layout_window, placement keeps the prior
|
|
3719
|
-
/// behaviour (groups the new agent into that window). This is the canonical
|
|
3720
|
-
/// adaptive 1-window-multiple-panes use case.
|
|
3721
|
-
#[test]
|
|
3722
|
-
#[ignore = "legacy adaptive display layout contract removed; runtime is silent tmux only"]
|
|
3723
|
-
fn e43_adaptive_placement_groups_into_layout_window_when_live_pane_matches_claim() {
|
|
3724
|
-
use crate::lifecycle::launch::adaptive_placement_for_agent;
|
|
3725
|
-
use crate::model::ids::AgentId;
|
|
3726
|
-
use crate::transport::{SessionName, WindowName};
|
|
3727
|
-
|
|
3728
|
-
let state = json!({
|
|
3729
|
-
"legacy_display_key": "adaptive",
|
|
3730
|
-
"session_name": "team-iso",
|
|
3731
|
-
"agents": {
|
|
3732
|
-
"alpha": {
|
|
3733
|
-
"status": "running",
|
|
3734
|
-
"provider": "codex",
|
|
3735
|
-
"layout_window": "team-w1",
|
|
3736
|
-
"pane_id": "%1",
|
|
3737
|
-
}
|
|
3738
|
-
}
|
|
3739
|
-
});
|
|
3740
|
-
|
|
3741
|
-
let transport = OfflineTransport::new()
|
|
3742
|
-
.with_targets(vec![layout_pane("team-iso", "team-w1", "%1", 0)])
|
|
3743
|
-
.with_windows(vec![WindowName::new("team-w1")]);
|
|
3744
|
-
|
|
3745
|
-
let placement = adaptive_placement_for_agent(
|
|
3746
|
-
&state,
|
|
3747
|
-
&transport,
|
|
3748
|
-
&SessionName::new("team-iso"),
|
|
3749
|
-
&AgentId::new("beta"),
|
|
3750
|
-
)
|
|
3751
|
-
.expect("placement should succeed");
|
|
3752
|
-
|
|
3753
|
-
assert_eq!(
|
|
3754
|
-
placement.layout_window.as_str(),
|
|
3755
|
-
"team-w1",
|
|
3756
|
-
"E43 Fix A regression guard: when alpha's live pane DOES live under \
|
|
3757
|
-
layout_window 'team-w1', the new agent beta should be grouped into \
|
|
3758
|
-
the same window (canonical adaptive behaviour). Got {placement:?}"
|
|
3759
|
-
);
|
|
3760
|
-
assert!(
|
|
3761
|
-
!placement.starts_window,
|
|
3762
|
-
"E43 Fix A regression guard: grouping into an existing window means \
|
|
3763
|
-
starts_window=false (split into the window). Got {placement:?}"
|
|
3764
|
-
);
|
|
3765
|
-
}
|
|
3766
|
-
|
|
3767
|
-
/// **RED — Fix B**: `adaptive_existing_placement_for_agent` must NOT return a
|
|
3768
|
-
/// `starts_window=true` placement that names a window NOT present in
|
|
3769
|
-
/// `live_windows`. When the agent's claimed `layout_window` is stale and the
|
|
3770
|
-
/// session is effectively per-agent (live windows are named after agent_ids),
|
|
3771
|
-
/// the placement must fall back to a per-agent window named after the
|
|
3772
|
-
/// agent_id itself — so the subsequent spawn opens a new window, not a split
|
|
3773
|
-
/// of a phantom.
|
|
3774
|
-
#[test]
|
|
3775
|
-
#[ignore = "legacy adaptive display layout contract removed; runtime is silent tmux only"]
|
|
3776
|
-
fn e43_adaptive_existing_placement_falls_back_to_agent_id_window_when_claim_missing_from_live() {
|
|
3777
|
-
use crate::lifecycle::launch::adaptive_existing_placement_for_agent;
|
|
3778
|
-
use crate::model::ids::AgentId;
|
|
3779
|
-
use crate::transport::{SessionName, WindowName};
|
|
3780
|
-
|
|
3781
|
-
let state = json!({
|
|
3782
|
-
"legacy_display_key": "adaptive",
|
|
3783
|
-
"session_name": "team-iso",
|
|
3784
|
-
"agents": {
|
|
3785
|
-
"demo-director": {
|
|
3786
|
-
"status": "running",
|
|
3787
|
-
"provider": "codex",
|
|
3788
|
-
// Stale claim — live session has no team-w2 window.
|
|
3789
|
-
"layout_window": "team-w2",
|
|
3790
|
-
"pane_id": "%99",
|
|
3791
|
-
}
|
|
3792
|
-
}
|
|
3793
|
-
});
|
|
3794
|
-
|
|
3795
|
-
let transport = OfflineTransport::new()
|
|
3796
|
-
.with_targets(vec![
|
|
3797
|
-
layout_pane("team-iso", "architect", "%1", 0),
|
|
3798
|
-
layout_pane("team-iso", "test-engineer", "%2", 0),
|
|
3799
|
-
])
|
|
3800
|
-
.with_windows(vec![
|
|
3801
|
-
WindowName::new("architect"),
|
|
3802
|
-
WindowName::new("test-engineer"),
|
|
3803
|
-
]);
|
|
3804
|
-
|
|
3805
|
-
let placement = adaptive_existing_placement_for_agent(
|
|
3806
|
-
&state,
|
|
3807
|
-
&transport,
|
|
3808
|
-
&SessionName::new("team-iso"),
|
|
3809
|
-
&AgentId::new("demo-director"),
|
|
3810
|
-
)
|
|
3811
|
-
.expect("placement should resolve");
|
|
3812
|
-
|
|
3813
|
-
assert_ne!(
|
|
3814
|
-
placement.layout_window.as_str(),
|
|
3815
|
-
"team-w2",
|
|
3816
|
-
"E43 Fix B: stale claim 'team-w2' is not in live_windows; placement \
|
|
3817
|
-
must NOT reuse that name (otherwise spawn issues split -t :team-w2 \
|
|
3818
|
-
and tmux says 'can't find window: team-w2'). Got {placement:?}"
|
|
3819
|
-
);
|
|
3820
|
-
assert_eq!(
|
|
3821
|
-
placement.layout_window.as_str(),
|
|
3822
|
-
"demo-director",
|
|
3823
|
-
"E43 Fix B: when the claim is stale and the live layout is \
|
|
3824
|
-
per-agent-named, fall back to a window named after the agent_id \
|
|
3825
|
-
(canonical per-agent pattern). Got {placement:?}"
|
|
3826
|
-
);
|
|
3827
|
-
assert!(
|
|
3828
|
-
placement.starts_window,
|
|
3829
|
-
"E43 Fix B: the fallback opens a NEW window (starts_window=true); \
|
|
3830
|
-
do not try to split an existing window with the wrong name. Got \
|
|
3831
|
-
{placement:?}"
|
|
3832
|
-
);
|
|
3833
|
-
}
|
|
3834
|
-
|
|
3835
|
-
/// **Regression guard — Fix B**: when the agent's claimed layout_window IS
|
|
3836
|
-
/// in live_windows, the existing-placement path keeps its current behaviour
|
|
3837
|
-
/// (return a starts_window=false placement that splits into the existing
|
|
3838
|
-
/// window).
|
|
3839
|
-
#[test]
|
|
3840
|
-
#[ignore = "legacy adaptive display layout contract removed; runtime is silent tmux only"]
|
|
3841
|
-
fn e43_adaptive_existing_placement_keeps_starts_window_false_when_claim_in_live_windows() {
|
|
3842
|
-
use crate::lifecycle::launch::adaptive_existing_placement_for_agent;
|
|
3843
|
-
use crate::model::ids::AgentId;
|
|
3844
|
-
use crate::transport::{SessionName, WindowName};
|
|
3845
|
-
|
|
3846
|
-
let state = json!({
|
|
3847
|
-
"legacy_display_key": "adaptive",
|
|
3848
|
-
"session_name": "team-iso",
|
|
3849
|
-
"agents": {
|
|
3850
|
-
"alpha": {
|
|
3851
|
-
"status": "running",
|
|
3852
|
-
"provider": "codex",
|
|
3853
|
-
"layout_window": "team-w1",
|
|
3854
|
-
"pane_id": "%1",
|
|
3855
|
-
"pane_index": 1u64,
|
|
3856
|
-
}
|
|
3857
|
-
}
|
|
3858
|
-
});
|
|
3859
|
-
|
|
3860
|
-
let transport = OfflineTransport::new()
|
|
3861
|
-
.with_targets(vec![layout_pane("team-iso", "team-w1", "%1", 0)])
|
|
3862
|
-
.with_windows(vec![WindowName::new("team-w1")]);
|
|
3863
|
-
|
|
3864
|
-
let placement = adaptive_existing_placement_for_agent(
|
|
3865
|
-
&state,
|
|
3866
|
-
&transport,
|
|
3867
|
-
&SessionName::new("team-iso"),
|
|
3868
|
-
&AgentId::new("alpha"),
|
|
3869
|
-
)
|
|
3870
|
-
.expect("placement should resolve");
|
|
3871
|
-
|
|
3872
|
-
assert_eq!(
|
|
3873
|
-
placement.layout_window.as_str(),
|
|
3874
|
-
"team-w1",
|
|
3875
|
-
"E43 Fix B regression guard: when claim 'team-w1' IS in live_windows, \
|
|
3876
|
-
existing-placement must keep it. Got {placement:?}"
|
|
3877
|
-
);
|
|
3878
|
-
// pane_index=1 → starts_window=false in the existing behaviour.
|
|
3879
|
-
assert!(
|
|
3880
|
-
!placement.starts_window,
|
|
3881
|
-
"E43 Fix B regression guard: existing window + pane_index>0 → \
|
|
3882
|
-
starts_window=false. Got {placement:?}"
|
|
3883
|
-
);
|
|
3884
|
-
}
|
|
3885
|
-
|
|
3886
3544
|
/// **RED — Fix C end-to-end**: `add_agent` end-to-end must NOT emit a
|
|
3887
3545
|
/// spawn_split with the stale window name. With state carrying
|
|
3888
3546
|
/// `legacy_display_key=adaptive` + stale `layout_window=team-w2` residue and
|
|
@@ -4178,56 +3836,6 @@ fn e45_add_agent_opens_new_window_does_not_split_into_per_agent_window() {
|
|
|
4178
3836
|
);
|
|
4179
3837
|
}
|
|
4180
3838
|
|
|
4181
|
-
/// **Regression guard**: when the live session DOES have a real `team-w1`
|
|
4182
|
-
/// adaptive window with a live pane that matches state's claim, the
|
|
4183
|
-
/// existing E43+adaptive grouping behaviour is preserved (split into team-w1
|
|
4184
|
-
/// as before). E45 only changes behaviour for per-agent windows.
|
|
4185
|
-
#[test]
|
|
4186
|
-
#[ignore = "legacy adaptive display layout contract removed; runtime is silent tmux only"]
|
|
4187
|
-
fn e45_real_team_w_adaptive_layout_still_groups_into_layout_window() {
|
|
4188
|
-
use crate::lifecycle::launch::adaptive_placement_for_agent;
|
|
4189
|
-
use crate::model::ids::AgentId;
|
|
4190
|
-
use crate::transport::{SessionName, WindowName};
|
|
4191
|
-
|
|
4192
|
-
let state = json!({
|
|
4193
|
-
"legacy_display_key": "adaptive",
|
|
4194
|
-
"session_name": "team-iso",
|
|
4195
|
-
"agents": {
|
|
4196
|
-
"alpha": {
|
|
4197
|
-
"status": "running",
|
|
4198
|
-
"provider": "codex",
|
|
4199
|
-
"layout_window": "team-w1",
|
|
4200
|
-
"layout_index": 0u64,
|
|
4201
|
-
"pane_id": "%1",
|
|
4202
|
-
}
|
|
4203
|
-
}
|
|
4204
|
-
});
|
|
4205
|
-
|
|
4206
|
-
let transport = OfflineTransport::new()
|
|
4207
|
-
.with_targets(vec![layout_pane("team-iso", "team-w1", "%1", 0)])
|
|
4208
|
-
.with_windows(vec![WindowName::new("team-w1")]);
|
|
4209
|
-
|
|
4210
|
-
let placement = adaptive_placement_for_agent(
|
|
4211
|
-
&state,
|
|
4212
|
-
&transport,
|
|
4213
|
-
&SessionName::new("team-iso"),
|
|
4214
|
-
&AgentId::new("beta"),
|
|
4215
|
-
)
|
|
4216
|
-
.expect("E45 regression guard: real team-w1 adaptive layout must still group new agents in");
|
|
4217
|
-
|
|
4218
|
-
assert_eq!(
|
|
4219
|
-
placement.layout_window.as_str(),
|
|
4220
|
-
"team-w1",
|
|
4221
|
-
"E45 regression guard: real `team-w1` adaptive window must still \
|
|
4222
|
-
host new agents (canonical adaptive behaviour). Got {placement:?}"
|
|
4223
|
-
);
|
|
4224
|
-
assert!(
|
|
4225
|
-
!placement.starts_window,
|
|
4226
|
-
"E45 regression guard: grouping into existing team-w1 → \
|
|
4227
|
-
starts_window=false. Got {placement:?}"
|
|
4228
|
-
);
|
|
4229
|
-
}
|
|
4230
|
-
|
|
4231
3839
|
/// **Regression guard**: helper `is_adaptive_layout_window` golden cases.
|
|
4232
3840
|
/// `team-w1`, `team-w42`, `team-w7-foo` are adaptive; agent_id names and
|
|
4233
3841
|
/// other shapes are not.
|
|
@@ -130,11 +130,6 @@ fn lifecycle_lock_long_held_event_records_holder_and_waiter() {
|
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
#[test]
|
|
134
|
-
fn lifecycle_lock_phase_b_golden_source_guard() {
|
|
135
|
-
r2_lifecycle_lock_exists_precondition();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
133
|
#[test]
|
|
139
134
|
fn r2_lifecycle_lock_exists_precondition() {
|
|
140
135
|
let src = manifest_src();
|