@team-agent/installer 0.5.75 → 0.5.78

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 (98) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/README.md +9 -0
  4. package/README.zh.md +8 -0
  5. package/crates/team-agent/src/cli/adapters.rs +184 -125
  6. package/crates/team-agent/src/cli/diagnose.rs +333 -68
  7. package/crates/team-agent/src/cli/emit.rs +59 -15
  8. package/crates/team-agent/src/cli/mod.rs +600 -134
  9. package/crates/team-agent/src/cli/models.rs +485 -44
  10. package/crates/team-agent/src/cli/named_address.rs +19 -5
  11. package/crates/team-agent/src/cli/profile.rs +35 -4
  12. package/crates/team-agent/src/cli/spec.rs +7 -2
  13. package/crates/team-agent/src/cli/status_port/brief.rs +1137 -0
  14. package/crates/team-agent/src/cli/status_port/compact.rs +12 -8
  15. package/crates/team-agent/src/cli/status_port/snapshot.rs +15 -12
  16. package/crates/team-agent/src/cli/status_port/store.rs +1 -1
  17. package/crates/team-agent/src/cli/status_port.rs +8 -0
  18. package/crates/team-agent/src/cli/tests/missing_subcommands.rs +62 -8
  19. package/crates/team-agent/src/cli/tests/mod.rs +1 -0
  20. package/crates/team-agent/src/cli/tests/named_address.rs +70 -0
  21. package/crates/team-agent/src/cli/tests/run_delegation.rs +29 -24
  22. package/crates/team-agent/src/cli/tests/status_brief.rs +691 -0
  23. package/crates/team-agent/src/cli/tests/status_send.rs +8 -2
  24. package/crates/team-agent/src/cli/tests/verb_profile.rs +81 -6
  25. package/crates/team-agent/src/cli/types.rs +1 -0
  26. package/crates/team-agent/src/leader/lease.rs +538 -41
  27. package/crates/team-agent/src/leader/owner_bind.rs +40 -12
  28. package/crates/team-agent/src/leader/rediscover/tests.rs +65 -0
  29. package/crates/team-agent/src/leader/rediscover.rs +36 -6
  30. package/crates/team-agent/src/leader/start.rs +151 -14
  31. package/crates/team-agent/src/leader/tests/wake_start_owner.rs +15 -9
  32. package/crates/team-agent/src/leader/types.rs +4 -0
  33. package/crates/team-agent/src/lifecycle/launch/add_agent.rs +28 -227
  34. package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +0 -18
  35. package/crates/team-agent/src/lifecycle/launch/cursor_mcp.rs +94 -227
  36. package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +59 -10
  37. package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +138 -14
  38. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +1449 -282
  39. package/crates/team-agent/src/lifecycle/launch/readiness.rs +349 -4
  40. package/crates/team-agent/src/lifecycle/launch/spawn.rs +11 -11
  41. package/crates/team-agent/src/lifecycle/launch/spec_state.rs +35 -3
  42. package/crates/team-agent/src/lifecycle/launch/worker_env.rs +16 -0
  43. package/crates/team-agent/src/lifecycle/launch.rs +30 -7
  44. package/crates/team-agent/src/lifecycle/profile_launch.rs +37 -3
  45. package/crates/team-agent/src/lifecycle/restart/agent.rs +112 -100
  46. package/crates/team-agent/src/lifecycle/restart/common.rs +82 -52
  47. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +1002 -65
  48. package/crates/team-agent/src/lifecycle/restart.rs +2 -2
  49. package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +3 -0
  50. package/crates/team-agent/src/lifecycle/tests/b0_reader_hideone_audit_contract.rs +45 -14
  51. package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +15 -0
  52. package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +5 -0
  53. package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +11 -13
  54. package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +119 -3
  55. package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +12 -0
  56. package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +22 -0
  57. package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +12 -0
  58. package/crates/team-agent/src/lifecycle/tests/cursor_mcp_overlay.rs +265 -198
  59. package/crates/team-agent/src/lifecycle/tests/cursor_require_explicit_model_red.rs +14 -30
  60. package/crates/team-agent/src/lifecycle/tests/cursor_restart_resume_red.rs +3 -0
  61. package/crates/team-agent/src/lifecycle/tests/g1_silent_faces.rs +2 -5
  62. package/crates/team-agent/src/lifecycle/tests/grok_effort_argv_red.rs +10 -0
  63. package/crates/team-agent/src/lifecycle/tests/grok_mcp_overlay_red.rs +58 -35
  64. package/crates/team-agent/src/lifecycle/tests/grok_require_explicit_model_red.rs +10 -0
  65. package/crates/team-agent/src/lifecycle/tests/grok_restart_resume_red.rs +9 -0
  66. package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +4 -3
  67. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +0 -168
  68. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +145 -212
  69. package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +16 -2
  70. package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +69 -28
  71. package/crates/team-agent/src/lifecycle/tests/pi_dual_entry_red.rs +78 -0
  72. package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +3 -0
  73. package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +51 -10
  74. package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +22 -10
  75. package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +50 -7
  76. package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +137 -0
  77. package/crates/team-agent/src/lifecycle/types.rs +12 -0
  78. package/crates/team-agent/src/mcp_server/wire.rs +140 -11
  79. package/crates/team-agent/src/messaging/delivery.rs +67 -8
  80. package/crates/team-agent/src/messaging/leader_channel.rs +56 -0
  81. package/crates/team-agent/src/messaging/tests/runtime.rs +10 -2
  82. package/crates/team-agent/src/messaging/watchers.rs +48 -4
  83. package/crates/team-agent/src/provider/adapters/cursor_agent.rs +2 -5
  84. package/crates/team-agent/src/state/paths.rs +17 -2
  85. package/crates/team-agent/src/state/persist.rs +97 -1
  86. package/crates/team-agent/src/state/projection.rs +18 -2
  87. package/crates/team-agent/src/state/repository.rs +29 -0
  88. package/crates/team-agent/src/state/selector.rs +23 -3
  89. package/crates/team-agent/src/test_support/models_timeout_fixture.rs +144 -0
  90. package/crates/team-agent/src/tmux_backend/tests.rs +121 -4
  91. package/crates/team-agent/src/tmux_backend.rs +208 -118
  92. package/crates/team-agent/src/transport.rs +72 -0
  93. package/crates/team-agent/src/transport_factory.rs +53 -0
  94. package/package.json +4 -5
  95. package/skills/team-agent/SKILL.md +45 -17
  96. package/skills/team-agent/command-coverage.json +4 -29
  97. package/npm/check-skill-links.mjs +0 -88
  98. package/skills/team-agent/references/team-agent-operator.md +0 -672
@@ -20,17 +20,20 @@ pub fn cmd_profile(args: &ProfileArgs) -> Result<CmdResult, CliError> {
20
20
  fn init_profile(args: &ProfileArgs) -> Result<Value, CliError> {
21
21
  let auth_mode = args.auth_mode.as_deref().unwrap_or("subscription");
22
22
  validate_auth_mode(auth_mode)?;
23
+ let proxy_mode = args.proxy_mode.as_deref().unwrap_or("inherit");
24
+ validate_proxy_mode(proxy_mode)?;
23
25
  let dir = profile_dir(args);
24
26
  std::fs::create_dir_all(&dir)?;
25
27
  let path = dir.join(format!("{}.env", args.name));
26
28
  let template_path = dir.join(format!("{}.example.env", args.name));
27
- let body = profile_template(&args.name, auth_mode);
29
+ let body = profile_template(&args.name, auth_mode, proxy_mode);
28
30
  let created_profile = write_new_file(&path, &body)?;
29
31
  if created_profile {
30
32
  set_owner_only_permissions(&path)?;
31
33
  }
32
34
  let created_template = write_new_file(&template_path, &body)?;
33
35
  write_boundary_files(&dir)?;
36
+ let actual_proxy_mode = display_proxy_mode(&read_profile_env(&path)?);
34
37
 
35
38
  let mut obj = Map::new();
36
39
  obj.insert("ok".to_string(), Value::Bool(true));
@@ -39,6 +42,14 @@ fn init_profile(args: &ProfileArgs) -> Result<Value, CliError> {
39
42
  "auth_mode".to_string(),
40
43
  Value::String(auth_mode.to_string()),
41
44
  );
45
+ obj.insert(
46
+ "proxy_mode".to_string(),
47
+ Value::String(actual_proxy_mode),
48
+ );
49
+ obj.insert(
50
+ "proxy_mode_changed".to_string(),
51
+ Value::Bool(created_profile),
52
+ );
42
53
  obj.insert("path".to_string(), path_value(&path));
43
54
  obj.insert("template_path".to_string(), path_value(&template_path));
44
55
  obj.insert("created_profile".to_string(), Value::Bool(created_profile));
@@ -72,6 +83,7 @@ fn doctor_profile(args: &ProfileArgs) -> Result<Value, CliError> {
72
83
  let values = read_profile_env(&path)?;
73
84
  let auth_mode =
74
85
  profile_value(&values, "AUTH_MODE").unwrap_or_else(|| "subscription".to_string());
86
+ let proxy_mode = display_proxy_mode(&values);
75
87
  let secret_keys = secret_keys_present(&values);
76
88
  let keys = sorted_keys(&values);
77
89
  let mut obj = Map::new();
@@ -83,6 +95,7 @@ fn doctor_profile(args: &ProfileArgs) -> Result<Value, CliError> {
83
95
  Value::Bool(credential_present(&values)),
84
96
  );
85
97
  obj.insert("auth_mode".to_string(), Value::String(auth_mode));
98
+ obj.insert("proxy_mode".to_string(), Value::String(proxy_mode));
86
99
  obj.insert("keys_present".to_string(), string_array(keys));
87
100
  obj.insert(
88
101
  "raw_file_read_allowed_for_agents".to_string(),
@@ -112,6 +125,7 @@ fn show_profile(args: &ProfileArgs) -> Result<Value, CliError> {
112
125
  let values = read_profile_env(&path)?;
113
126
  let auth_mode =
114
127
  profile_value(&values, "AUTH_MODE").unwrap_or_else(|| "subscription".to_string());
128
+ let proxy_mode = display_proxy_mode(&values);
115
129
  let secret_keys = secret_keys_present(&values);
116
130
  let missing_common = missing_common_keys(&values, &auth_mode);
117
131
  let mut obj = Map::new();
@@ -122,6 +136,7 @@ fn show_profile(args: &ProfileArgs) -> Result<Value, CliError> {
122
136
  Value::Bool(credential_present(&values)),
123
137
  );
124
138
  obj.insert("auth_mode".to_string(), Value::String(auth_mode));
139
+ obj.insert("proxy_mode".to_string(), Value::String(proxy_mode));
125
140
  obj.insert("values".to_string(), redacted_values(&values));
126
141
  obj.insert(
127
142
  "keys_present".to_string(),
@@ -157,12 +172,21 @@ fn validate_auth_mode(auth_mode: &str) -> Result<(), CliError> {
157
172
  }
158
173
  }
159
174
 
160
- fn profile_template(name: &str, auth_mode: &str) -> String {
175
+ fn validate_proxy_mode(proxy_mode: &str) -> Result<(), CliError> {
176
+ match proxy_mode {
177
+ "direct" | "inherit" => Ok(()),
178
+ other => Err(CliError::Usage(format!(
179
+ "invalid --proxy-mode: {other} (expected direct|inherit)"
180
+ ))),
181
+ }
182
+ }
183
+
184
+ fn profile_template(name: &str, auth_mode: &str, proxy_mode: &str) -> String {
161
185
  match auth_mode {
162
186
  "compatible_api" | "official_api" => {
163
- format!("AUTH_MODE={auth_mode}\nPROFILE_NAME={name}\nBASE_URL=\nAPI_KEY=\nMODEL=\n")
187
+ format!("AUTH_MODE={auth_mode}\nPROFILE_NAME={name}\nPROXY_MODE={proxy_mode}\nBASE_URL=\nAPI_KEY=\nMODEL=\n")
164
188
  }
165
- _ => format!("AUTH_MODE=subscription\nPROFILE_NAME={name}\n"),
189
+ _ => format!("AUTH_MODE=subscription\nPROFILE_NAME={name}\nPROXY_MODE={proxy_mode}\n"),
166
190
  }
167
191
  }
168
192
 
@@ -235,6 +259,13 @@ fn profile_value(values: &Map<String, Value>, key: &str) -> Option<String> {
235
259
  .map(ToString::to_string)
236
260
  }
237
261
 
262
+ fn display_proxy_mode(values: &Map<String, Value>) -> String {
263
+ profile_value(values, "PROXY_MODE")
264
+ .or_else(|| profile_value(values, "NETWORK_MODE"))
265
+ .map(|value| value.trim().to_ascii_lowercase())
266
+ .unwrap_or_else(|| "inherit".to_string())
267
+ }
268
+
238
269
  fn missing_profile_value(args: &ProfileArgs, path: &Path, template_path: Option<&Path>) -> Value {
239
270
  let mut obj = Map::new();
240
271
  obj.insert("ok".to_string(), Value::Bool(false));
@@ -159,6 +159,11 @@ pub(crate) struct CommandSpec {
159
159
  pub(crate) governance: Option<GovernanceNote>,
160
160
  }
161
161
 
162
+ /// Visible default-help contract:
163
+ /// - d40 / v0.5.77 published 15 names including `models` and excluding `results`.
164
+ /// - `results` remains a public handler and must stay discoverable.
165
+ /// - Exact composed set is d40 ∪ {results}. This is a frozen name set, not a
166
+ /// numeric slack threshold.
162
167
  #[rustfmt::skip]
163
168
  pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
164
169
  CommandSpec { name: "quick-start", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::Dispatch(DispatchKind::QuickStart), summary: "start or attach a team from TEAM.md", usage: "usage: team-agent quick-start [TEAMDIR] [--workspace WORKSPACE] [--name NAME] [--team-id TEAM|--team TEAM] [--yes] [--no-display] [--backend tmux|conpty] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
@@ -166,7 +171,7 @@ pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
166
171
  CommandSpec { name: "status", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Status), summary: "show current team status", usage: "usage: team-agent status [AGENT] [--workspace WORKSPACE] [--team TEAM] [--summary|--json] [--detail]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
167
172
  CommandSpec { name: "models", tier: CommandTier::Core, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Models), summary: "list exact provider model ids", usage: "usage: team-agent models --provider pi [--search TEXT] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
168
173
  CommandSpec { name: "collect", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Collect), summary: "collect reported results", usage: "usage: team-agent collect [--workspace WORKSPACE] [--team TEAM] [--result-file FILE] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
169
- CommandSpec { name: "results", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Results), summary: "read reported results for a case", usage: "usage: team-agent results --case CASE_ID [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
174
+ CommandSpec { name: "results", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Results), summary: "read reported results for a case", usage: "usage: team-agent results --case CASE_ID [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
170
175
  CommandSpec { name: "wait", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Wait), summary: "block until a task result is stored", usage: "usage: team-agent wait --task TASK [--workspace WORKSPACE] [--json]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
171
176
  CommandSpec { name: "restart", tier: CommandTier::Core, category: CommandCategory::TeamLifecycle, kind: CommandKind::Dispatch(DispatchKind::Restart), summary: "restart the selected team", usage: "usage: team-agent restart [WORKSPACE] [--team TEAM] [--allow-fresh] [--session-converge-deadline SECONDS] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
172
177
  CommandSpec { name: "shutdown", tier: CommandTier::Core, category: CommandCategory::TeamLifecycle, kind: CommandKind::Dispatch(DispatchKind::Shutdown), summary: "stop the selected team", usage: "usage: team-agent shutdown [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
@@ -201,7 +206,7 @@ pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
201
206
  CommandSpec { name: "clone-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::CloneAgent), summary: "clone a worker role into a fresh session", usage: "usage: team-agent clone-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--no-display] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, alias_of: None, sunset: None, action: None, governance: None },
202
207
  CommandSpec { name: "allow-peer-talk", tier: CommandTier::Secondary, category: CommandCategory::Setup, kind: CommandKind::Dispatch(DispatchKind::AllowPeerTalk), summary: "allow direct worker peer talk", usage: "usage: team-agent allow-peer-talk A B [--workspace WORKSPACE] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "capability/config surface" }) },
203
208
  CommandSpec { name: "approvals", tier: CommandTier::Secondary, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Approvals), summary: "inspect provider approval state", usage: "usage: team-agent approvals [AGENT] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "approval diagnostics" }) },
204
- CommandSpec { name: "profile", tier: CommandTier::Secondary, category: CommandCategory::Setup, kind: CommandKind::Dispatch(DispatchKind::Profile), summary: "manage provider profiles", usage: "usage: team-agent profile COMMAND NAME [--workspace WORKSPACE] [--team TEAM] [--auth-mode MODE] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "provider/profile setup" }) },
209
+ CommandSpec { name: "profile", tier: CommandTier::Secondary, category: CommandCategory::Setup, kind: CommandKind::Dispatch(DispatchKind::Profile), summary: "manage provider profiles", usage: "usage: team-agent profile COMMAND NAME [--workspace WORKSPACE] [--team TEAM] [--auth-mode MODE] [--proxy-mode direct|inherit] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "provider/profile setup" }) },
205
210
  CommandSpec { name: "install-skill", tier: CommandTier::Secondary, category: CommandCategory::Setup, kind: CommandKind::Dispatch(DispatchKind::InstallSkill), summary: "install or uninstall Team Agent skills", usage: "usage: team-agent install-skill (--source DIR | --uninstall) [--target codex|claude|copilot|all] [--dest DIR] [--dry-run] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "capability setup" }) },
206
211
  CommandSpec { name: "inbox", tier: CommandTier::Secondary, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Inbox), summary: "inspect queued messages", usage: "usage: team-agent inbox AGENT [--workspace WORKSPACE] [--team TEAM] [--limit N] [--since CURSOR] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
207
212