@team-agent/installer 0.5.100 → 0.5.102

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 (63) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/src/cli/diagnose.rs +29 -7
  4. package/crates/team-agent/src/cli/mod.rs +24 -8
  5. package/crates/team-agent/src/cli/tests/main_preserved.rs +0 -74
  6. package/crates/team-agent/src/compiler/tests.rs +20 -23
  7. package/crates/team-agent/src/compiler.rs +52 -65
  8. package/crates/team-agent/src/coordinator/tests/s3_bounded.rs +16 -48
  9. package/crates/team-agent/src/leader/start.rs +1 -14
  10. package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +211 -16
  11. package/crates/team-agent/src/lifecycle/launch/clone_agent.rs +1 -0
  12. package/crates/team-agent/src/lifecycle/launch/fork_agent.rs +15 -5
  13. package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +89 -6
  14. package/crates/team-agent/src/lifecycle/launch/role_source.rs +168 -32
  15. package/crates/team-agent/src/lifecycle/launch/spawn.rs +1 -1
  16. package/crates/team-agent/src/lifecycle/launch.rs +11 -3
  17. package/crates/team-agent/src/lifecycle/profile_launch.rs +23 -8
  18. package/crates/team-agent/src/lifecycle/restart/agent.rs +2 -2
  19. package/crates/team-agent/src/lifecycle/restart/avatar.rs +1806 -0
  20. package/crates/team-agent/src/lifecycle/restart/common.rs +115 -2
  21. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +8 -2
  22. package/crates/team-agent/src/lifecycle/restart/selection.rs +14 -2
  23. package/crates/team-agent/src/lifecycle/restart.rs +11 -4
  24. package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +0 -28
  25. package/crates/team-agent/src/lifecycle/tests/pi_compiler_red.rs +11 -9
  26. package/crates/team-agent/src/lifecycle/tests/pi_dual_entry_red.rs +8 -401
  27. package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +2 -2
  28. package/crates/team-agent/src/lifecycle/tests/pi_fork_session_inheritance_red.rs +1398 -0
  29. package/crates/team-agent/src/lifecycle/tests.rs +1 -0
  30. package/crates/team-agent/src/lifecycle/types.rs +10 -2
  31. package/crates/team-agent/src/lifecycle/worker_command_context.rs +22 -8
  32. package/crates/team-agent/src/mcp_server/helpers.rs +0 -16
  33. package/crates/team-agent/src/mcp_server/lifecycle_tools/mod.rs +2 -7
  34. package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +1 -127
  35. package/crates/team-agent/src/mcp_server/mod.rs +7 -12
  36. package/crates/team-agent/src/mcp_server/tests/scoped.rs +1 -132
  37. package/crates/team-agent/src/mcp_server/tests/send.rs +1 -93
  38. package/crates/team-agent/src/mcp_server/tests/tools.rs +0 -61
  39. package/crates/team-agent/src/mcp_server/tests/wire.rs +6 -51
  40. package/crates/team-agent/src/mcp_server/tests.rs +4 -200
  41. package/crates/team-agent/src/mcp_server/tools.rs +5 -396
  42. package/crates/team-agent/src/mcp_server/types.rs +3 -36
  43. package/crates/team-agent/src/mcp_server/wire.rs +2 -223
  44. package/crates/team-agent/src/messaging/leader_receiver.rs +1 -1
  45. package/crates/team-agent/src/messaging/mod.rs +2 -2
  46. package/crates/team-agent/src/messaging/scheduler.rs +2 -205
  47. package/crates/team-agent/src/messaging/tests/basic.rs +0 -31
  48. package/crates/team-agent/src/messaging/tests/main_preserved.rs +0 -73
  49. package/crates/team-agent/src/messaging/tests/runtime.rs +0 -26
  50. package/crates/team-agent/src/messaging/types.rs +0 -20
  51. package/crates/team-agent/src/model/spec.rs +15 -18
  52. package/crates/team-agent/src/provider/types.rs +2 -0
  53. package/crates/team-agent/src/state/persist.rs +58 -2
  54. package/crates/team-agent/src/state/projection.rs +5 -1
  55. package/crates/team-agent/src/state/repository/tests.rs +1 -16
  56. package/crates/team-agent/src/state/repository.rs +126 -37
  57. package/crates/team-agent/src/transport/test_support.rs +23 -3
  58. package/package.json +4 -4
  59. package/skills/team-agent/SKILL.md +18 -47
  60. package/skills/team-agent/command-coverage.json +7 -0
  61. package/skills/team-agent/references/team-agent-operator.md +28 -118
  62. package/skills/team-agent/references/team-in-team.md +4 -19
  63. package/crates/team-agent/src/mcp_server/lifecycle_tools/agent_ops.rs +0 -484
@@ -1,9 +1,8 @@
1
1
  use crate::cli::spec::{CommandKind, COMMAND_SPECS};
2
2
  use crate::compiler::compile_role_agent;
3
3
  use crate::lifecycle::launch::pi_mcp::parse_pi_leader_args;
4
- use crate::mcp_server::TeamOrchestratorTools;
5
4
  use crate::model::enums::{AuthMode, Provider, ProviderEffort};
6
- use crate::model::ids::{AgentId, TeamKey};
5
+ use crate::model::ids::AgentId;
7
6
  use crate::model::yaml::Value;
8
7
  use crate::provider::{get_adapter, ProviderCommandContext};
9
8
  use crate::transport::test_support::OfflineTransport;
@@ -44,71 +43,6 @@ fn run_process_isolated(marker: &str, test_name: &str, body: impl FnOnce()) {
44
43
  );
45
44
  }
46
45
 
47
- #[cfg(unix)]
48
- const FILE_H_NATIVE_COMPILE_DEADLINE: std::time::Duration = std::time::Duration::from_secs(15);
49
- #[cfg(unix)]
50
- const FILE_H_NATIVE_READINESS_DEADLINE: std::time::Duration = std::time::Duration::from_secs(3);
51
-
52
- #[cfg(unix)]
53
- #[derive(Debug)]
54
- struct FileHCommandTimeout {
55
- stage: &'static str,
56
- pid: u32,
57
- deadline: std::time::Duration,
58
- elapsed: std::time::Duration,
59
- reaped_status: std::process::ExitStatus,
60
- }
61
-
62
- #[cfg(unix)]
63
- fn run_file_h_command_with_deadline(
64
- command: &mut std::process::Command,
65
- stage: &'static str,
66
- deadline: std::time::Duration,
67
- stdout_path: &Path,
68
- stderr_path: &Path,
69
- ) -> Result<std::process::Output, FileHCommandTimeout> {
70
- let stdout_file = std::fs::File::create(stdout_path)
71
- .unwrap_or_else(|error| panic!("{stage}: create stdout receipt failed: {error}"));
72
- let stderr_file = std::fs::File::create(stderr_path)
73
- .unwrap_or_else(|error| panic!("{stage}: create stderr receipt failed: {error}"));
74
- let mut child = command
75
- .stdout(std::process::Stdio::from(stdout_file))
76
- .stderr(std::process::Stdio::from(stderr_file))
77
- .spawn()
78
- .unwrap_or_else(|error| panic!("{stage}: spawn failed: {error}"));
79
- let pid = child.id();
80
- let started = std::time::Instant::now();
81
- loop {
82
- if let Some(status) = child
83
- .try_wait()
84
- .unwrap_or_else(|error| panic!("{stage}: poll pid {pid} failed: {error}"))
85
- {
86
- return Ok(std::process::Output {
87
- status,
88
- stdout: std::fs::read(stdout_path).unwrap_or_default(),
89
- stderr: std::fs::read(stderr_path).unwrap_or_default(),
90
- });
91
- }
92
- let elapsed = started.elapsed();
93
- if elapsed >= deadline {
94
- child
95
- .kill()
96
- .unwrap_or_else(|error| panic!("{stage}: kill exact pid {pid} failed: {error}"));
97
- let reaped_status = child
98
- .wait()
99
- .unwrap_or_else(|error| panic!("{stage}: reap exact pid {pid} failed: {error}"));
100
- return Err(FileHCommandTimeout {
101
- stage,
102
- pid,
103
- deadline,
104
- elapsed,
105
- reaped_status,
106
- });
107
- }
108
- std::thread::park_timeout(std::time::Duration::from_millis(10));
109
- }
110
- }
111
-
112
46
  fn dynamic_add_fixture(root: &Path, label: &str, role_doc: &str) -> (PathBuf, PathBuf) {
113
47
  let team = root.join(label);
114
48
  std::fs::create_dir_all(team.join("agents")).expect("create dynamic team fixture");
@@ -287,10 +221,13 @@ fn pi_leader_and_teammate_body(hermetic: &HermeticTestEnv) {
287
221
  .expect("write provider-default teammate role");
288
222
  let defaults = compile_role_agent(&role, &Value::Map(Vec::new()), "/workspace")
289
223
  .expect("provider: pi teammate may use Pi model and effort defaults");
290
- assert_eq!(defaults.agent.get("model"), Some(&Value::Null));
291
- assert!(
292
- defaults.agent.get("effort").is_none(),
293
- "omitted Pi model and effort must remain absent"
224
+ assert_eq!(
225
+ defaults.agent.get("model"),
226
+ Some(&Value::Str("openai-codex/gpt-6-luna".to_string()))
227
+ );
228
+ assert_eq!(
229
+ defaults.agent.get("effort"),
230
+ Some(&Value::Str("max".to_string()))
294
231
  );
295
232
  std::fs::remove_dir_all(root).expect("remove role fixture");
296
233
 
@@ -572,336 +509,6 @@ fn pi_leader_and_teammate_body(hermetic: &HermeticTestEnv) {
572
509
  crate::state::persist::load_runtime_state(&dead_team).expect("load dead rollback state");
573
510
  assert!(dead_state.pointer("/agents/mate").is_none());
574
511
 
575
- #[cfg(unix)]
576
- {
577
- let live = dynamic_root.join("live-public-add");
578
- std::fs::create_dir_all(live.join("agents")).expect("create live agents dir");
579
- std::fs::create_dir_all(live.join("roles")).expect("create live roles dir");
580
- std::fs::write(
581
- live.join("TEAM.md"),
582
- "---\nname: current\nobjective: Public no-spec add fixture.\nprovider: fake\n---\n\nfixture\n",
583
- )
584
- .expect("write live TEAM.md");
585
- std::fs::write(
586
- live.join("agents/implementer.md"),
587
- "---\nname: implementer\nrole: Existing Worker\nprovider: fake\nmodel: fake\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nexisting\n",
588
- )
589
- .expect("write live existing role");
590
- std::fs::write(live.join("roles/mate.md"), fake_role).expect("write live add role");
591
- let live_socket = "/private/tmp/tmux-501/ta-live-owning";
592
- let live_session = "team-agent-leader-pi-live-owning";
593
- crate::state::persist::save_runtime_state(
594
- &live,
595
- &json!({
596
- "active_team_key": "current",
597
- "tmux_endpoint": worker_socket,
598
- "tmux_socket": worker_socket,
599
- "agents": {
600
- "implementer": {
601
- "status": "running",
602
- "provider": "fake",
603
- "model": "fake",
604
- "auth_mode": "subscription",
605
- "window": "implementer"
606
- }
607
- },
608
- "teams": {
609
- "current": {
610
- "status": "alive",
611
- "team_dir": live,
612
- "session_name": null,
613
- "tmux_endpoint": worker_socket,
614
- "tmux_socket": worker_socket,
615
- "agents": {
616
- "implementer": {
617
- "status": "running",
618
- "provider": "fake",
619
- "model": "fake",
620
- "auth_mode": "subscription",
621
- "window": "implementer"
622
- }
623
- },
624
- "leader_receiver": {
625
- "status": "attached",
626
- "session_name": live_session,
627
- "tmux_socket": live_socket
628
- }
629
- },
630
- "sibling": {
631
- "status": "alive",
632
- "team_dir": live.join("sibling"),
633
- "session_name": null,
634
- "agents": {},
635
- "leader_receiver": {
636
- "status": "attached",
637
- "session_name": "team-agent-leader-pi-sibling",
638
- "tmux_socket": "/private/tmp/tmux-501/ta-live-sibling"
639
- }
640
- }
641
- }
642
- }),
643
- )
644
- .expect("seed live nested receiver");
645
- super::launch_spawn::seed_healthy_coordinator(&live);
646
- let runtime_spec = crate::model::paths::runtime_spec_path(&live, "current");
647
- assert!(
648
- !runtime_spec.exists(),
649
- "fixture must enter the TEAM.md fallback before runtime spec exists"
650
- );
651
-
652
- let shim_root = live.join("tmux-shim");
653
- std::fs::create_dir_all(&shim_root).expect("create tmux shim dir");
654
- let shim_log = shim_root.join("argv.log");
655
- let shim_source = shim_root.join("tmux.c");
656
- let shim = shim_root.join("tmux");
657
- std::fs::write(
658
- &shim_source,
659
- r#"#include <stdio.h>
660
- #include <stdlib.h>
661
- #include <string.h>
662
- #include <unistd.h>
663
-
664
- static int has_arg(int argc, char **argv, const char *needle) {
665
- for (int i = 1; i < argc; i++) {
666
- if (strcmp(argv[i], needle) == 0) return 1;
667
- }
668
- return 0;
669
- }
670
-
671
- int main(int argc, char **argv) {
672
- if (getenv("TEAM_AGENT_PI_TEST_HANG") != NULL) for (;;) pause();
673
- const char *log_path = getenv("TEAM_AGENT_PI_TMUX_LOG");
674
- const char *socket = getenv("TEAM_AGENT_PI_OWNING_SOCKET");
675
- const char *session = getenv("TEAM_AGENT_PI_OWNING_SESSION");
676
- const char *workspace = getenv("TEAM_AGENT_PI_RUN_WORKSPACE");
677
- FILE *log = log_path == NULL ? NULL : fopen(log_path, "a");
678
- if (log == NULL || socket == NULL || session == NULL || workspace == NULL) return 92;
679
- for (int i = 1; i < argc; i++) fprintf(log, "%s%s", i == 1 ? "" : " ", argv[i]);
680
- fputc('\n', log);
681
- fclose(log);
682
-
683
- int owns_socket = 0;
684
- for (int i = 1; i + 1 < argc; i++) {
685
- if (strcmp(argv[i], "-S") == 0 && strcmp(argv[i + 1], socket) == 0) owns_socket = 1;
686
- }
687
- if (!owns_socket) return 91;
688
- if (has_arg(argc, argv, "new-window") || has_arg(argc, argv, "display-message")) {
689
- puts("%9101");
690
- } else if (has_arg(argc, argv, "list-panes")) {
691
- printf("%%9101__TA_FIELD__%s__TA_FIELD__0__TA_FIELD__mate__TA_FIELD__0__TA_FIELD__/dev/ttys099__TA_FIELD__sh__TA_FIELD__1__TA_FIELD__%s__TA_FIELD__1__TA_FIELD__0__TA_FIELD__9101__TA_FIELD__\n", session, workspace);
692
- }
693
- return 0;
694
- }
695
- "#,
696
- )
697
- .expect("write native tmux shim source");
698
- let compile = run_file_h_command_with_deadline(
699
- std::process::Command::new("cc")
700
- .args(["-O0", "-o"])
701
- .arg(&shim)
702
- .arg(&shim_source),
703
- "File-H native fake compile",
704
- FILE_H_NATIVE_COMPILE_DEADLINE,
705
- &shim_root.join("compile.stdout"),
706
- &shim_root.join("compile.stderr"),
707
- )
708
- .unwrap_or_else(|timeout| panic!("{timeout:?}"));
709
- assert!(
710
- compile.status.success(),
711
- "native tmux shim compile failed: {}",
712
- String::from_utf8_lossy(&compile.stderr)
713
- );
714
- let tooth_started = std::time::Instant::now();
715
- let tooth = run_file_h_command_with_deadline(
716
- std::process::Command::new(&shim).env("TEAM_AGENT_PI_TEST_HANG", "1"),
717
- "File-H native fake readiness timeout tooth",
718
- FILE_H_NATIVE_READINESS_DEADLINE,
719
- &shim_root.join("readiness-tooth.stdout"),
720
- &shim_root.join("readiness-tooth.stderr"),
721
- )
722
- .expect_err("non-exiting native fake must hit the readiness deadline");
723
- assert_eq!(tooth.stage, "File-H native fake readiness timeout tooth");
724
- assert_eq!(tooth.deadline, FILE_H_NATIVE_READINESS_DEADLINE);
725
- assert!(!tooth.reaped_status.success(), "{tooth:?}");
726
- assert!(
727
- !crate::platform::process::pid_is_alive(tooth.pid),
728
- "readiness timeout must leave its exact child dead and reaped: {tooth:?}"
729
- );
730
- assert!(
731
- tooth_started.elapsed()
732
- <= FILE_H_NATIVE_READINESS_DEADLINE + std::time::Duration::from_secs(1),
733
- "readiness timeout tooth exceeded its deadline plus reap allowance: {tooth:?}"
734
- );
735
-
736
- let preflight = run_file_h_command_with_deadline(
737
- std::process::Command::new(&shim)
738
- .args(["-S", worker_socket, "has-session"])
739
- .env("TEAM_AGENT_PI_TMUX_LOG", shim_root.join("preflight.log"))
740
- .env("TEAM_AGENT_PI_OWNING_SOCKET", worker_socket)
741
- .env("TEAM_AGENT_PI_OWNING_SESSION", live_session)
742
- .env("TEAM_AGENT_PI_RUN_WORKSPACE", &live),
743
- "File-H native fake has-session preflight",
744
- FILE_H_NATIVE_READINESS_DEADLINE,
745
- &shim_root.join("preflight.stdout"),
746
- &shim_root.join("preflight.stderr"),
747
- )
748
- .unwrap_or_else(|timeout| panic!("{timeout:?}"));
749
- assert!(
750
- preflight.status.success(),
751
- "native tmux shim preflight failed: {}",
752
- String::from_utf8_lossy(&preflight.stderr)
753
- );
754
- let previous_path = std::env::var_os("PATH").unwrap_or_default();
755
- let joined_path = std::env::join_paths(
756
- std::iter::once(shim_root.clone()).chain(std::env::split_paths(&previous_path)),
757
- )
758
- .expect("join native shim PATH");
759
- let _path = EnvVarGuard::set("PATH", joined_path);
760
- let _log = EnvVarGuard::set("TEAM_AGENT_PI_TMUX_LOG", &shim_log);
761
- let _socket = EnvVarGuard::set("TEAM_AGENT_PI_OWNING_SOCKET", worker_socket);
762
- let _session = EnvVarGuard::set("TEAM_AGENT_PI_OWNING_SESSION", live_session);
763
- let _workspace = EnvVarGuard::set("TEAM_AGENT_PI_RUN_WORKSPACE", &live);
764
-
765
- let tools = TeamOrchestratorTools::with_identity(
766
- &live,
767
- Some(AgentId::new("leader")),
768
- Some(TeamKey::new("current")),
769
- );
770
- let result = tools
771
- .add_agent("mate", "roles/mate.md")
772
- .expect("public MCP add must use the persisted worker endpoint");
773
- assert_eq!(
774
- result.fields.get("ok").and_then(serde_json::Value::as_bool),
775
- Some(true)
776
- );
777
- let tmux_argv = std::fs::read_to_string(&shim_log).expect("read tmux shim log");
778
- assert!(
779
- tmux_argv.contains(&format!("-S {worker_socket}")),
780
- "public add must address the persisted worker socket: {tmux_argv}"
781
- );
782
- assert!(
783
- tmux_argv.contains(&format!(
784
- "new-window -d -P -F #{{pane_id}} -t {live_session} -n mate"
785
- )),
786
- "public add must reuse the owner session with new-window: {tmux_argv}"
787
- );
788
- assert!(
789
- tmux_argv.contains(&live.to_string_lossy().to_string()),
790
- "spawn command must retain the MCP scratch as cwd: {tmux_argv}"
791
- );
792
- assert!(
793
- !tmux_argv.contains("new-session"),
794
- "public add must not start a same-named session on another server: {tmux_argv}"
795
- );
796
- let parent_socket = crate::tmux_backend::socket_name_for_workspace(
797
- live.parent().expect("live scratch parent"),
798
- );
799
- assert!(
800
- !tmux_argv.contains(&parent_socket),
801
- "public add must not derive transport from the scratch parent: {tmux_argv}"
802
- );
803
-
804
- let added_state = crate::state::persist::load_runtime_state(&live)
805
- .expect("load public add state for send/status");
806
- assert_eq!(
807
- added_state
808
- .pointer("/teams/current/session_name")
809
- .and_then(serde_json::Value::as_str),
810
- Some(live_session),
811
- "dynamic add must persist the selected receiver session for shared send/status routing"
812
- );
813
- assert!(
814
- added_state
815
- .pointer("/teams/sibling/session_name")
816
- .is_some_and(serde_json::Value::is_null),
817
- "selected-team routing must not borrow or rewrite a sibling session: {added_state}"
818
- );
819
- assert_eq!(
820
- added_state
821
- .pointer("/teams/sibling/leader_receiver/session_name")
822
- .and_then(serde_json::Value::as_str),
823
- Some("team-agent-leader-pi-sibling")
824
- );
825
-
826
- let mut old_state = added_state.clone();
827
- old_state["teams"]["current"]["session_name"] = serde_json::Value::Null;
828
- crate::state::persist::save_runtime_state(&live, &old_state)
829
- .expect("seed controlled old null-session view");
830
- let blocked = tools
831
- .send_message(
832
- &crate::messaging::MessageTarget::Single("mate".to_string()),
833
- "controlled old session routing probe",
834
- None,
835
- None,
836
- None,
837
- )
838
- .expect("old public send must return a structured refusal")
839
- .to_value();
840
- assert_eq!(blocked.get("ok"), Some(&json!(false)), "{blocked}");
841
- assert_eq!(
842
- blocked.get("reason"),
843
- Some(&json!("tmux_target_missing")),
844
- "the old null-session view must fail at real send target resolution: {blocked}"
845
- );
846
- let old_status = tools
847
- .get_team_status()
848
- .expect("old public status must return an honest dead view");
849
- assert_eq!(
850
- old_status
851
- .fields
852
- .get("agents")
853
- .and_then(|agents| agents.get("mate"))
854
- .and_then(|mate| mate.get("stale_reason"))
855
- .and_then(serde_json::Value::as_str),
856
- Some("pane_dead"),
857
- "the old null-session view must fail at real status liveness resolution: {:?}",
858
- old_status.fields
859
- );
860
- crate::state::persist::save_runtime_state(&live, &added_state)
861
- .expect("restore corrected selected-team session");
862
-
863
- let sent = tools
864
- .send_message(
865
- &crate::messaging::MessageTarget::Single("mate".to_string()),
866
- "session routing probe",
867
- None,
868
- None,
869
- None,
870
- )
871
- .expect("public send must resolve the added mate")
872
- .to_value();
873
- assert_eq!(sent.get("status"), Some(&json!("accepted")), "{sent}");
874
- assert!(
875
- sent.get("message_id")
876
- .and_then(serde_json::Value::as_str)
877
- .is_some_and(|message_id| message_id.starts_with("msg_")),
878
- "blocked target resolution must not be reported as a successful send: {sent}"
879
- );
880
-
881
- let status = tools
882
- .get_team_status()
883
- .expect("public status must resolve the selected owner session");
884
- assert_eq!(
885
- status
886
- .fields
887
- .get("session_name")
888
- .and_then(serde_json::Value::as_str),
889
- Some(live_session),
890
- "status must report the selected receiver session"
891
- );
892
- assert_ne!(
893
- status
894
- .fields
895
- .get("agents")
896
- .and_then(|agents| agents.get("mate"))
897
- .and_then(|mate| mate.get("stale_reason"))
898
- .and_then(serde_json::Value::as_str),
899
- Some("pane_dead"),
900
- "the live owner-session mate must not be reported pane_dead: {:?}",
901
- status.fields
902
- );
903
- }
904
-
905
512
  let shared_source = include_str!("../launch/pi_mcp.rs");
906
513
  let leader_source = include_str!("../../leader/start.rs");
907
514
  let teammate_source = include_str!("../launch/spawn.rs");
@@ -372,7 +372,7 @@ fn pi_leader_wrapper_materializes_from_empty_unicode_wsl_workspace() {
372
372
  team_id: "current",
373
373
  agent_id: "leader",
374
374
  workspace: &workspace,
375
- include_tools: &["assign_task", "send_message"],
375
+ include_tools: &["send_message", "report_result", "get_team_status"],
376
376
  })
377
377
  .expect("materialize Pi leader wrapper from an empty Unicode workspace");
378
378
 
@@ -437,7 +437,7 @@ fn pi_wrapper_publish_needs_no_final_path_metadata_lookup() {
437
437
  team_id: "current",
438
438
  agent_id: "leader",
439
439
  workspace: &workspace,
440
- include_tools: &["assign_task", "send_message"],
440
+ include_tools: &["send_message", "report_result", "get_team_status"],
441
441
  },
442
442
  |temp, destination| {
443
443
  std::fs::rename(temp, destination)?;