@team-agent/installer 0.5.101 → 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.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/src/cli/tests/main_preserved.rs +0 -74
- package/crates/team-agent/src/compiler/tests.rs +20 -23
- package/crates/team-agent/src/compiler.rs +49 -65
- package/crates/team-agent/src/coordinator/tests/s3_bounded.rs +16 -48
- package/crates/team-agent/src/leader/start.rs +1 -14
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +1 -1
- package/crates/team-agent/src/lifecycle/restart/common.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +0 -28
- package/crates/team-agent/src/lifecycle/tests/pi_compiler_red.rs +11 -9
- package/crates/team-agent/src/lifecycle/tests/pi_dual_entry_red.rs +8 -401
- package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +22 -8
- package/crates/team-agent/src/mcp_server/helpers.rs +0 -16
- package/crates/team-agent/src/mcp_server/lifecycle_tools/mod.rs +2 -7
- package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +1 -127
- package/crates/team-agent/src/mcp_server/mod.rs +7 -12
- package/crates/team-agent/src/mcp_server/tests/scoped.rs +1 -132
- package/crates/team-agent/src/mcp_server/tests/send.rs +1 -93
- package/crates/team-agent/src/mcp_server/tests/tools.rs +0 -61
- package/crates/team-agent/src/mcp_server/tests/wire.rs +6 -51
- package/crates/team-agent/src/mcp_server/tests.rs +4 -200
- package/crates/team-agent/src/mcp_server/tools.rs +5 -396
- package/crates/team-agent/src/mcp_server/types.rs +3 -36
- package/crates/team-agent/src/mcp_server/wire.rs +2 -223
- package/crates/team-agent/src/messaging/leader_receiver.rs +1 -1
- package/crates/team-agent/src/messaging/mod.rs +2 -2
- package/crates/team-agent/src/messaging/scheduler.rs +2 -205
- package/crates/team-agent/src/messaging/tests/basic.rs +0 -31
- package/crates/team-agent/src/messaging/tests/main_preserved.rs +0 -73
- package/crates/team-agent/src/messaging/tests/runtime.rs +0 -26
- package/crates/team-agent/src/messaging/types.rs +0 -20
- package/crates/team-agent/src/model/spec.rs +14 -18
- package/crates/team-agent/src/state/repository/tests.rs +1 -16
- package/crates/team-agent/src/state/repository.rs +1 -33
- package/package.json +4 -4
- package/skills/team-agent/SKILL.md +5 -5
- package/skills/team-agent/command-coverage.json +7 -0
- package/skills/team-agent/references/team-agent-operator.md +24 -116
- package/skills/team-agent/references/team-in-team.md +4 -19
- package/crates/team-agent/src/mcp_server/lifecycle_tools/agent_ops.rs +0 -484
|
@@ -1,78 +1,5 @@
|
|
|
1
1
|
use super::*;
|
|
2
2
|
|
|
3
|
-
// ── F1 [P1 byte-shape] — stuck_cancel suppression snapshot.delivered_message_ids must use golden's
|
|
4
|
-
// _DELIVERED_MESSAGE_STATUSES = {visible, submitted, delivered, acknowledged} (scheduler.py:27,376-383),
|
|
5
|
-
// sorted. The Rust delivered_message_ids (scheduler.rs:243) used {injected, visible, submitted,
|
|
6
|
-
// submitted_unverified, delivered} — the WRONG set (reviewer's explicit warning: don't copy the
|
|
7
|
-
// activity.rs deadlock query set): it EXCLUDES 'acknowledged' and INCLUDES 'injected'/'submitted_unverified'.
|
|
8
|
-
// (The snapshot also must carry BOTH assigned_task_ids AND delivered_message_ids — that structural half
|
|
9
|
-
// is already present; this pins the STATUS SET.)
|
|
10
|
-
#[test]
|
|
11
|
-
fn stuck_cancel_snapshot_delivered_message_ids_uses_golden_status_set() {
|
|
12
|
-
let ws = tmp_ws("f1_delivered");
|
|
13
|
-
crate::state::persist::save_runtime_state(
|
|
14
|
-
&ws,
|
|
15
|
-
&serde_json::json!({
|
|
16
|
-
"active_team_key": "teamX",
|
|
17
|
-
"agents": {"w1": {"status": "running", "provider": "codex"}}
|
|
18
|
-
}),
|
|
19
|
-
)
|
|
20
|
-
.unwrap();
|
|
21
|
-
let store = crate::message_store::MessageStore::open(&ws).unwrap();
|
|
22
|
-
// golden-delivered (must be IN delivered_message_ids): acknowledged + visible.
|
|
23
|
-
let m_ack = store
|
|
24
|
-
.create_message(None, "leader", "w1", "ack-me", None, true, Some("teamX"))
|
|
25
|
-
.unwrap();
|
|
26
|
-
store.mark(&m_ack, "delivered", None).unwrap();
|
|
27
|
-
store.mark(&m_ack, "acknowledged", None).unwrap();
|
|
28
|
-
let m_vis = store
|
|
29
|
-
.create_message(None, "leader", "w1", "vis", None, true, Some("teamX"))
|
|
30
|
-
.unwrap();
|
|
31
|
-
store.mark(&m_vis, "visible", None).unwrap();
|
|
32
|
-
// NOT golden-delivered (must be EXCLUDED): injected.
|
|
33
|
-
let m_inj = store
|
|
34
|
-
.create_message(None, "leader", "w1", "inj", None, true, Some("teamX"))
|
|
35
|
-
.unwrap();
|
|
36
|
-
store.mark(&m_inj, "injected", None).unwrap();
|
|
37
|
-
drop(store);
|
|
38
|
-
let _ = stuck_cancel(&ws, "w1", None, "leader").unwrap();
|
|
39
|
-
let state = crate::state::persist::load_runtime_state(&ws).unwrap();
|
|
40
|
-
let snapshot =
|
|
41
|
-
&state["coordinator"]["suppressed_idle_alerts"]["teamX"]["w1"]["stuck"]["snapshot"];
|
|
42
|
-
assert!(
|
|
43
|
-
snapshot.get("assigned_task_ids").is_some(),
|
|
44
|
-
"F1: snapshot must carry assigned_task_ids; got {snapshot}"
|
|
45
|
-
);
|
|
46
|
-
let delivered = snapshot
|
|
47
|
-
.get("delivered_message_ids")
|
|
48
|
-
.and_then(serde_json::Value::as_array)
|
|
49
|
-
.map(|a| {
|
|
50
|
-
a.iter()
|
|
51
|
-
.filter_map(|v| v.as_str().map(str::to_string))
|
|
52
|
-
.collect::<Vec<_>>()
|
|
53
|
-
})
|
|
54
|
-
.unwrap_or_else(|| panic!("F1: snapshot must carry delivered_message_ids; got {snapshot}"));
|
|
55
|
-
assert!(
|
|
56
|
-
delivered.contains(&m_ack),
|
|
57
|
-
"F1: golden _DELIVERED_MESSAGE_STATUSES includes 'acknowledged' — the acknowledged message must be \
|
|
58
|
-
in delivered_message_ids; the Rust set omits it. got {delivered:?}"
|
|
59
|
-
);
|
|
60
|
-
assert!(
|
|
61
|
-
delivered.contains(&m_vis),
|
|
62
|
-
"F1: 'visible' is delivered (golden); got {delivered:?}"
|
|
63
|
-
);
|
|
64
|
-
assert!(
|
|
65
|
-
!delivered.contains(&m_inj),
|
|
66
|
-
"F1: 'injected' is NOT in golden _DELIVERED_MESSAGE_STATUSES — it must be EXCLUDED; the Rust set \
|
|
67
|
-
wrongly includes it. got {delivered:?}"
|
|
68
|
-
);
|
|
69
|
-
let mut sorted = delivered.clone();
|
|
70
|
-
sorted.sort();
|
|
71
|
-
assert_eq!(
|
|
72
|
-
delivered, sorted,
|
|
73
|
-
"F1: delivered_message_ids must be sorted (golden sorts); got {delivered:?}"
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
3
|
// ── collect --result-file INGEST SEMANTIC (golden results.py:58-73) ──────────────────────────────
|
|
77
4
|
// Golden `collect(result_file=…)` INDEPENDENTLY INGESTS a standalone result: a valid result_envelope_v1
|
|
78
5
|
// is `store.add_result(envelope)`'d (results.py:73) regardless of any in-flight delivery, then the
|
|
@@ -979,32 +979,6 @@ fn requeue_delivery_exhausted_watchers_reopens_only_exhausted() {
|
|
|
979
979
|
);
|
|
980
980
|
}
|
|
981
981
|
|
|
982
|
-
// ════════════════════════════════════════════════════════════════════════
|
|
983
|
-
// GROUP P — stuck_cancel owner-gate + invalid alert type refusal.
|
|
984
|
-
// scheduler.py:262-294.
|
|
985
|
-
// ════════════════════════════════════════════════════════════════════════
|
|
986
|
-
|
|
987
|
-
#[test]
|
|
988
|
-
fn stuck_cancel_none_alert_type_expands_to_all() {
|
|
989
|
-
// alert_type None == Python "all" → sorted(_ALERT_TYPES) expansion.
|
|
990
|
-
let ws = tmp_ws("stuckcancel");
|
|
991
|
-
let out = stuck_cancel(&ws, "w1", None, "leader").unwrap();
|
|
992
|
-
// The suppression result must enumerate all three alert types.
|
|
993
|
-
let types = out.get("alert_types").and_then(|v| v.as_array()).map(|a| {
|
|
994
|
-
a.iter()
|
|
995
|
-
.filter_map(|x| x.as_str().map(str::to_string))
|
|
996
|
-
.collect::<Vec<_>>()
|
|
997
|
-
});
|
|
998
|
-
assert_eq!(
|
|
999
|
-
types,
|
|
1000
|
-
Some(vec![
|
|
1001
|
-
"cross_worker_deadlock".to_string(),
|
|
1002
|
-
"idle_fallback".to_string(),
|
|
1003
|
-
"stuck".to_string()
|
|
1004
|
-
])
|
|
1005
|
-
);
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
982
|
// ════════════════════════════════════════════════════════════════════════
|
|
1009
983
|
// GROUP Q — collect intake (results.py:45-167): valid result advances task,
|
|
1010
984
|
// returns collected_results + delivered_messages + results counts shape.
|
|
@@ -219,26 +219,6 @@ impl WorkerRuntimeState {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
/// 告警类型 (card §49;`scheduler.py:38` `_ALERT_TYPES`)。`stuck_cancel` 还接 `all` (展开全集)。
|
|
223
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
224
|
-
#[serde(rename_all = "snake_case")]
|
|
225
|
-
pub enum AlertType {
|
|
226
|
-
Stuck,
|
|
227
|
-
IdleFallback,
|
|
228
|
-
CrossWorkerDeadlock,
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
impl AlertType {
|
|
232
|
-
/// `stuck_cancel(alert_type="all")` → `sorted(_ALERT_TYPES)` 全集 (`scheduler.py:269`)。
|
|
233
|
-
pub fn all() -> [AlertType; 3] {
|
|
234
|
-
[
|
|
235
|
-
AlertType::CrossWorkerDeadlock,
|
|
236
|
-
AlertType::IdleFallback,
|
|
237
|
-
AlertType::Stuck,
|
|
238
|
-
]
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
222
|
/// selftest check 状态 (card §47;`diagnose/comms.py`)。§19 必变 enum。
|
|
243
223
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
244
224
|
#[serde(rename_all = "snake_case")]
|
|
@@ -1135,19 +1135,10 @@ mod tests {
|
|
|
1135
1135
|
);
|
|
1136
1136
|
}
|
|
1137
1137
|
|
|
1138
|
-
// 0.5.66 bypass 单源 §4.1:7
|
|
1139
|
-
//
|
|
1140
|
-
// compile 级校验确实 fail-loud,即各触发面(经 compile_team)都被覆盖。
|
|
1138
|
+
// 0.5.66 bypass 单源 §4.1:7 个生命周期入口共享编译后的 spec。
|
|
1139
|
+
// 缺失 role frontmatter 值时由编译器注入 true;此处锁定公共编译入口的默认结果。
|
|
1141
1140
|
#[test]
|
|
1142
|
-
fn
|
|
1143
|
-
// compile_team 是 7 触发面的 spec 校验必经点:
|
|
1144
|
-
// quick-start(quick_start.rs:233 compile_team)
|
|
1145
|
-
// restart(rebuild.rs:3245 rebuild_runtime_spec_from_roles → compile_team)
|
|
1146
|
-
// add-agent(add_agent.rs:331 compile_role_agent)
|
|
1147
|
-
// clone-agent(clone_agent.rs:62 → add_agent)
|
|
1148
|
-
// fork-agent(fork_agent.rs:96 validate_spec)
|
|
1149
|
-
// start-agent / reset-agent(操作已编译 spec,团队创建时经 compile_team 校验)
|
|
1150
|
-
// 验证 compile_team 对缺字段的角色文档 fail-loud。
|
|
1141
|
+
fn test_all_7_triggers_use_compiled_default_bypass() {
|
|
1151
1142
|
let team = std::env::temp_dir().join(format!(
|
|
1152
1143
|
"ta-spec-7trigger-{}",
|
|
1153
1144
|
std::process::id()
|
|
@@ -1159,17 +1150,22 @@ mod tests {
|
|
|
1159
1150
|
"---\nname: t7\nobjective: 7 trigger.\nprovider: codex\n---\n\nteam.\n",
|
|
1160
1151
|
)
|
|
1161
1152
|
.unwrap();
|
|
1162
|
-
//
|
|
1153
|
+
// 角色文档故意省略该字段;纯文本默认必须写入 compiled spec。
|
|
1163
1154
|
std::fs::write(
|
|
1164
1155
|
team.join("agents").join("w.md"),
|
|
1165
1156
|
"---\nname: w\nrole: Worker\nprovider: codex\ntools:\n - mcp_team\n---\n\nw.\n",
|
|
1166
1157
|
)
|
|
1167
1158
|
.unwrap();
|
|
1168
|
-
let
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1159
|
+
let spec = crate::compiler::compile_team(&team)
|
|
1160
|
+
.expect("compile_team must materialize the default bypass value");
|
|
1161
|
+
let agent = spec
|
|
1162
|
+
.get("agents")
|
|
1163
|
+
.and_then(Yaml::as_list)
|
|
1164
|
+
.and_then(|agents| agents.first())
|
|
1165
|
+
.expect("compiled spec has a worker");
|
|
1166
|
+
assert_eq!(
|
|
1167
|
+
agent.get("dangerously_skip_permissions"),
|
|
1168
|
+
Some(&Yaml::Bool(true))
|
|
1173
1169
|
);
|
|
1174
1170
|
let _ = std::fs::remove_dir_all(&team);
|
|
1175
1171
|
}
|
|
@@ -1,20 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
use super::
|
|
3
|
-
|
|
4
|
-
#[test]
|
|
5
|
-
fn mcp_reapply_scope_matches_legacy_helpers() {
|
|
6
|
-
assert!(
|
|
7
|
-
reapply_scope(&StateWriteIntent::McpUpdateStateNote {
|
|
8
|
-
team_key: Some("team-a"),
|
|
9
|
-
}) == ReapplyScope::Team
|
|
10
|
-
);
|
|
11
|
-
assert!(
|
|
12
|
-
reapply_scope(&StateWriteIntent::McpAssignTask {
|
|
13
|
-
team_key: Some("team-a"),
|
|
14
|
-
task_id: "task-a",
|
|
15
|
-
}) == ReapplyScope::Root
|
|
16
|
-
);
|
|
17
|
-
}
|
|
2
|
+
use super::StateWriteIntent;
|
|
18
3
|
|
|
19
4
|
#[test]
|
|
20
5
|
fn optional_unmigrated_read_preserves_missing_corrupt_and_valid_shapes(
|
|
@@ -161,10 +161,6 @@ impl<'a> StateRepository<'a> {
|
|
|
161
161
|
#[cfg(test)]
|
|
162
162
|
test_support::before_commit();
|
|
163
163
|
let team_key = match intent {
|
|
164
|
-
// Assignment's existing reconcile helper updates the root task
|
|
165
|
-
// array and the explicit Team array independently (legacy parity).
|
|
166
|
-
StateWriteIntent::McpAssignTask { .. } => None,
|
|
167
|
-
StateWriteIntent::McpUpdateStateNote { team_key } => team_key,
|
|
168
164
|
StateWriteIntent::ResultCollection { owner_team_id } => owner_team_id,
|
|
169
165
|
StateWriteIntent::ForkAgent { team_key, .. } => Some(team_key),
|
|
170
166
|
_ => {
|
|
@@ -517,16 +513,6 @@ pub enum StateWriteIntent<'a> {
|
|
|
517
513
|
CoordinatorConptyShim {
|
|
518
514
|
team_key: Option<&'a str>,
|
|
519
515
|
},
|
|
520
|
-
McpAssignTask {
|
|
521
|
-
team_key: Option<&'a str>,
|
|
522
|
-
task_id: &'a str,
|
|
523
|
-
},
|
|
524
|
-
McpLifecycleAgentOps {
|
|
525
|
-
team_key: Option<&'a str>,
|
|
526
|
-
},
|
|
527
|
-
McpUpdateStateNote {
|
|
528
|
-
team_key: Option<&'a str>,
|
|
529
|
-
},
|
|
530
516
|
MessagingDeliveryState {
|
|
531
517
|
owner_team_id: Option<&'a str>,
|
|
532
518
|
},
|
|
@@ -537,9 +523,6 @@ pub enum StateWriteIntent<'a> {
|
|
|
537
523
|
ResultCollection {
|
|
538
524
|
owner_team_id: Option<&'a str>,
|
|
539
525
|
},
|
|
540
|
-
SchedulerSuppression {
|
|
541
|
-
owner_team_id: Option<&'a str>,
|
|
542
|
-
},
|
|
543
526
|
TaskRepair {
|
|
544
527
|
team_key: Option<&'a str>,
|
|
545
528
|
},
|
|
@@ -735,15 +718,6 @@ fn route_direct(
|
|
|
735
718
|
// CoordinatorConptyShim -> root save
|
|
736
719
|
// (coordinator/conpty_shim.rs:426/674).
|
|
737
720
|
StateWriteIntent::CoordinatorConptyShim { .. } => helper_write_root(workspace, state),
|
|
738
|
-
// McpAssignTask uses the reapply variant today; direct save routes
|
|
739
|
-
// to the root helper for parity.
|
|
740
|
-
StateWriteIntent::McpAssignTask { .. } => helper_write_root(workspace, state),
|
|
741
|
-
// McpLifecycleAgentOps -> root save
|
|
742
|
-
// (mcp_server/lifecycle_tools/agent_ops.rs:385).
|
|
743
|
-
StateWriteIntent::McpLifecycleAgentOps { .. } => helper_write_root(workspace, state),
|
|
744
|
-
// McpUpdateStateNote -> root save
|
|
745
|
-
// (mcp_server/lifecycle_tools/state_status.rs:29/69).
|
|
746
|
-
StateWriteIntent::McpUpdateStateNote { .. } => helper_write_root(workspace, state),
|
|
747
721
|
// MessagingDeliveryState direct writes cover team-scoped, root
|
|
748
722
|
// fallback, and root (messaging/delivery.rs:2356/2358/2361).
|
|
749
723
|
StateWriteIntent::MessagingDeliveryState { owner_team_id } => match owner_team_id {
|
|
@@ -766,8 +740,6 @@ fn route_direct(
|
|
|
766
740
|
Some(_) => helper_write_team_scoped(workspace, state),
|
|
767
741
|
None => helper_write_root(workspace, state),
|
|
768
742
|
},
|
|
769
|
-
// SchedulerSuppression -> root save (messaging/scheduler.rs:259).
|
|
770
|
-
StateWriteIntent::SchedulerSuppression { .. } => helper_write_root(workspace, state),
|
|
771
743
|
// TaskRepair -> `save_team_scoped_state` (cli/adapters.rs:675).
|
|
772
744
|
StateWriteIntent::TaskRepair { .. } => helper_write_team_scoped(workspace, state),
|
|
773
745
|
// FakeE2eSeed / SelfMigration are diagnostic seams. The current
|
|
@@ -798,9 +770,6 @@ fn reapply_scope(intent: &StateWriteIntent<'_>) -> ReapplyScope {
|
|
|
798
770
|
owner_team_id: Some(_),
|
|
799
771
|
}
|
|
800
772
|
| StateWriteIntent::CoordinatorTick { .. }
|
|
801
|
-
| StateWriteIntent::McpUpdateStateNote {
|
|
802
|
-
team_key: Some(_),
|
|
803
|
-
}
|
|
804
773
|
) {
|
|
805
774
|
ReapplyScope::Team
|
|
806
775
|
} else {
|
|
@@ -817,8 +786,7 @@ fn route_reapply<F>(
|
|
|
817
786
|
where
|
|
818
787
|
F: FnOnce(&mut Value),
|
|
819
788
|
{
|
|
820
|
-
if matches!(&intent, StateWriteIntent::
|
|
821
|
-
| StateWriteIntent::McpUpdateStateNote { .. } | StateWriteIntent::ResultCollection { .. })
|
|
789
|
+
if matches!(&intent, StateWriteIntent::ResultCollection { .. })
|
|
822
790
|
{
|
|
823
791
|
return StateRepository::new(workspace).commit(intent, reapply).map(|_| ());
|
|
824
792
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@team-agent/installer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.102",
|
|
4
4
|
"description": "npx installer for Team Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codex",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"team-agent-installer": "npm/install.mjs"
|
|
21
21
|
},
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"@team-agent/cli-darwin-arm64": "0.5.
|
|
24
|
-
"@team-agent/cli-darwin-x64": "0.5.
|
|
25
|
-
"@team-agent/cli-linux-x64": "0.5.
|
|
23
|
+
"@team-agent/cli-darwin-arm64": "0.5.102",
|
|
24
|
+
"@team-agent/cli-darwin-x64": "0.5.102",
|
|
25
|
+
"@team-agent/cli-linux-x64": "0.5.102"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"postinstall": "node npm/bincheck.mjs",
|
|
@@ -12,14 +12,14 @@ team-agent --version
|
|
|
12
12
|
team-agent --help
|
|
13
13
|
team-agent doctor --help
|
|
14
14
|
```
|
|
15
|
-
**Launch** from a tmux-addressable pane: `team-agent claude` or `team-agent codex`, then `team-agent quick-start .team/current`. Do not start a real team from a naked terminal; workers use independent background windows on the workspace-scoped tmux server.
|
|
15
|
+
**Launch** from a tmux-addressable pane: `team-agent claude` or `team-agent codex`, then `team-agent quick-start .team/current`. For a plain-text team directory, use `team-agent quick-start <plain-text-team-dir>`. Do not start a real team from a naked terminal; workers use independent background windows on the workspace-scoped tmux server.
|
|
16
16
|
**Operate**
|
|
17
17
|
- Dispatch: `team-agent send TO MESSAGE` (positional TO; `--watch-result` is deprecated). After success, do not poll with `sleep` / `status` / `inbox` / `collect`. TO has two co-equal logical forms: an in-team short name (`team-agent send reviewer "..."`) and a fully qualified `<workspace>::<team>/<agent>`. Use the qualified form across workspaces.
|
|
18
18
|
- Inspect: `team-agent status` / `status --json`; `ok: true` plus `ready: false` is not a crash.
|
|
19
19
|
- Lifecycle: `restart .` resumes a stopped team; `add-agent NAME --role-file FILE` adds or `--force` recreates one worker; `shutdown --workspace .` stops. Do not shutdown the team to add a worker.
|
|
20
|
-
-
|
|
20
|
+
- Documents: `TEAM.md` and `agents/*.md` may be plain text/Markdown with no frontmatter; the whole team body is its objective and the whole role body is the prompt. Default worker id is the filename stem, provider `pi`, model `openai-codex/gpt-6-luna`, effort `max`, and bypass enabled. Valid optional frontmatter can override supported metadata.
|
|
21
21
|
- On a structured failure `action`, run that action first, then stop. Do not guess flags. `coordinator.session_missing` is self-healing; re-check `status --json`, do not shutdown.
|
|
22
|
-
The current user-facing agent is the leader (orchestrate only). Workers call `report_result` exactly once. Nested teams: `references/team-in-team.md`.
|
|
22
|
+
The current user-facing agent is the leader (orchestrate only). Worker MCP exposes exactly `send_message`, `report_result`, and optional `get_team_status`; lifecycle management stays on the authorized native CLI. Workers call `report_result` exactly once. Nested teams: `references/team-in-team.md`.
|
|
23
23
|
## Provider Capability Matrix
|
|
24
24
|
See `references/team-agent-operator.md` for Claude / Codex / Copilot / Gemini / fake. `quick-start` / `restart` / `claim-leader` JSON is compact by default; pass `--detail` only for internal diagnostics.
|
|
25
25
|
| Provider | Resume | Turn-state detection | Per-worker model override | Team Agent fork |
|
|
@@ -30,8 +30,8 @@ See `references/team-agent-operator.md` for Claude / Codex / Copilot / Gemini /
|
|
|
30
30
|
Grok / `cursor_agent` have no JSONL turn-state reader (classify → Unknown). Pi `fork-agent SOURCE --as TARGET` requires a captured Pi subscription source and reports both session ids plus the target backing path; it does not mutate the source session.
|
|
31
31
|
## Provider Prep
|
|
32
32
|
### Cursor provider notes
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
To opt into Cursor, use optional frontmatter with `provider: cursor_agent` (not `cursor`; launcher verb `team-agent cursor`) and `auth_mode: subscription`; no profile or bypass field is required. `agent_id` (legacy `name`) and `role` can be omitted, but Cursor still requires an explicit `model:`.
|
|
34
|
+
The model flag stays on argv; same-family catalog ids can change pane chrome, while unknown ids silent-fallback without warning. Pick a catalog id; after spawn, `capture-pane` once for chrome. Pane chrome does not prove the live model.
|
|
35
35
|
One `cursor_agent` per workspace; a second seat fail-closes because `.cursor/mcp.json` is directory-scoped and overwrites `TEAM_AGENT_ID`. Several Cursor seats need separate workspace directories. Same seat, fresh context: `reset-agent --discard-session`.
|
|
36
36
|
`clone-agent` copies the source role but starts fresh. Runtime role replacement: `clone-agent` → `stop-agent` → `remove-agent --confirm` (deletes `.team/dynamic-role-files/`) → write role file → `add-agent --role-file` → dispatch.
|
|
37
37
|
- Restart emits `--resume <chatId>` when `store.db` / `meta.json` exist; the gate does not read chat text. Persist anything that must survive restart.
|
|
@@ -261,6 +261,13 @@
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
},
|
|
264
|
+
{
|
|
265
|
+
"command": "team-agent quick-start <plain-text-team-dir>",
|
|
266
|
+
"bucket": "declared_gap",
|
|
267
|
+
"covered": false,
|
|
268
|
+
"owner": "runtime-owner:lifecycle",
|
|
269
|
+
"plan": "Run exact argv team-agent quick-start <plain-text-team-dir> in an isolated workspace with plain-text TEAM.md and agents/<stem>.md; bind successful compilation, objective, filename-derived id, and default provider/model/effort/bypass in the generated spec."
|
|
270
|
+
},
|
|
264
271
|
{
|
|
265
272
|
"command": "team-agent remove-agent <agent> --workspace . --confirm",
|
|
266
273
|
"bucket": "declared_gap",
|
|
@@ -45,7 +45,7 @@ team-agent claude
|
|
|
45
45
|
|
|
46
46
|
Pass provider flags after the provider name, for example `team-agent codex --dangerously-bypass-approvals-and-sandbox`. Run `team-agent quick-start` from the leader's current tmux pane. Do not start a real team from a naked terminal that Team Agent cannot address through tmux.
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
Leader `--dangerously-*` flags do not determine worker bypass. Worker bypass defaults to enabled in compiled role specs; no bypass field needs to be written (see Document Format and Permissions).
|
|
49
49
|
|
|
50
50
|
## Leader Role
|
|
51
51
|
|
|
@@ -55,48 +55,22 @@ When the user has been communicating in Chinese throughout the conversation, all
|
|
|
55
55
|
|
|
56
56
|
## Minimal Copy-Paste Team
|
|
57
57
|
|
|
58
|
-
`
|
|
58
|
+
`TEAM.md` and `agents/*.md` are plain text/Markdown; YAML frontmatter is optional. The whole `TEAM.md` body becomes the team objective, and the whole role body becomes the worker prompt. A default role uses its filename stem as its id, provider `pi`, model `openai-codex/gpt-6-luna`, effort `max`, and bypass enabled. Valid optional frontmatter may still override supported metadata.
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
mkdir -p .team/current/agents
|
|
62
|
-
team-agent profile init codex-default --auth-mode subscription --workspace .
|
|
63
62
|
cat > .team/current/TEAM.md <<'EOF'
|
|
64
|
-
|
|
65
|
-
name: demo-team
|
|
66
|
-
objective: One worker handles bounded tasks and reports through Team Agent MCP.
|
|
67
|
-
dangerous_auto_approve: false
|
|
68
|
-
fast: false
|
|
69
|
-
provider_models:
|
|
70
|
-
codex: gpt-5.5
|
|
71
|
-
claude: claude-sonnet-4-6
|
|
72
|
-
claude_code: claude-sonnet-4-6
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
Team config only. This is not a worker role.
|
|
63
|
+
A small team for bounded implementation tasks. Workers report progress to the leader and return a concise result.
|
|
76
64
|
EOF
|
|
77
65
|
cat > .team/current/agents/coder.md <<'EOF'
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
provider: codex
|
|
82
|
-
auth_mode: subscription
|
|
83
|
-
profile: codex-default
|
|
84
|
-
dangerously_skip_permissions: false
|
|
85
|
-
tools:
|
|
86
|
-
- fs_read
|
|
87
|
-
- fs_list
|
|
88
|
-
- fs_write
|
|
89
|
-
- execute_bash
|
|
90
|
-
- mcp_team
|
|
91
|
-
- provider_builtin
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
Handle one bounded task at a time. Send progress to leader only when needed. Final completion must call report_result exactly once; MCP fills task ids and result envelope fields.
|
|
66
|
+
# Implementation Worker
|
|
67
|
+
|
|
68
|
+
Handle one bounded task at a time. Send progress or blockers to the leader with `send_message`, and report completion exactly once with `report_result`.
|
|
95
69
|
EOF
|
|
96
70
|
team-agent quick-start .team/current
|
|
97
71
|
```
|
|
98
72
|
|
|
99
|
-
|
|
73
|
+
The MCP surface is exactly `send_message`, `report_result`, and `get_team_status`; status is optional, not a prerequisite. Agent/team lifecycle management remains on the separately authorized native CLI.
|
|
100
74
|
|
|
101
75
|
Workers always run headlessly in independent windows on the per-workspace tmux server. No GUI display backend is configured in `TEAM.md`.
|
|
102
76
|
|
|
@@ -132,7 +106,7 @@ Run `claim-leader` only from the **leader** pane. From a worker pane it refuses
|
|
|
132
106
|
| `fake` (testing only) | no | no | n/a | no |
|
|
133
107
|
|
|
134
108
|
Notes:
|
|
135
|
-
-
|
|
109
|
+
- A plain-text/default role uses Pi with `openai-codex/gpt-6-luna` and `max` effort; valid optional role frontmatter can select a provider and override supported model settings. For provider paths using `provider_models`, an explicit role `model:` takes precedence.
|
|
136
110
|
- Copilot fork copies the source session into an isolated `COPILOT_HOME` and rekeys its SQLite session references atomically. Missing or incomplete backing fails closed; it never falls back to a fresh spawn.
|
|
137
111
|
- Copilot phase-1 idle/turn detection is intentionally Unknown; tick emits a single explicit `provider.classify.unsupported` event per state change (P4 dedup), never a silent default.
|
|
138
112
|
- `pi` `fork-agent SOURCE --as TARGET` requires a captured Pi subscription source. It copies the complete JSONL history into a distinct target session with a new id and exact `--session <path>` resume; it does not alter the source file or fall back to a fresh session.
|
|
@@ -141,7 +115,7 @@ Notes:
|
|
|
141
115
|
|
|
142
116
|
### Subscription auth (Codex / Claude account login)
|
|
143
117
|
|
|
144
|
-
|
|
118
|
+
To opt a worker into Codex or Claude subscription providers, create a named subscription profile in the workspace and reference it from optional role frontmatter:
|
|
145
119
|
|
|
146
120
|
```bash
|
|
147
121
|
team-agent profile init codex-default --auth-mode subscription --workspace .
|
|
@@ -174,7 +148,7 @@ codex debug models
|
|
|
174
148
|
|
|
175
149
|
That command is the Codex catalog. This skill does **not** keep a model id list. If `codex` is not on PATH, the lookup is unavailable; do not invent slugs.
|
|
176
150
|
|
|
177
|
-
|
|
151
|
+
A plain-text/default role compiles as provider `pi` with model `openai-codex/gpt-6-luna` and effort `max`. If valid optional frontmatter selects another provider, its established provider-specific model/profile resolution applies; Grok and Cursor roles retain their explicit model requirements. **Do not treat provider/team fill-ins as a validity catalog.**
|
|
178
152
|
|
|
179
153
|
Claude: run `claude auth status`; if missing, run `claude auth login`. Team Agent stores Claude worker sessions by passing `--session-id` and resumes with `--resume`.
|
|
180
154
|
Use `provider: claude` or `provider: claude_code` for Claude workers.
|
|
@@ -250,7 +224,7 @@ Observed (exit 1): `usage error: invalid --auth-mode: not-a-mode`. That is the l
|
|
|
250
224
|
|
|
251
225
|
Team Agent loads the profile during quick-start, launch, restart, and start-agent. Compatible API workers inherit the current shell proxy/CA environment by default. Claude compatible API workers use Team Agent managed `CLAUDE_CONFIG_DIR` so user-level Claude subscription settings cannot re-inject Anthropic proxy variables into third-party API sessions. If quick-start reports an ambient proxy blocker, do not silently unset proxy for the whole team; tell the user to choose one path: fix that proxy for `BASE_URL`, put `HTTPS_PROXY=`/`HTTP_PROXY=` in the profile, or put `PROXY_MODE=direct` in the profile to bypass proxy only for that worker. Subscription workers keep their native provider settings and environment. Startup runs a redacted smoke check for compatible API profiles before worker windows are created, so a bad URL/key/model or proxy/base URL connectivity failure is reported to the leader command instead of producing idle workers.
|
|
252
226
|
|
|
253
|
-
## How role
|
|
227
|
+
## How role documents become live
|
|
254
228
|
|
|
255
229
|
```bash
|
|
256
230
|
team-agent restart --help
|
|
@@ -276,72 +250,15 @@ To apply a changed role file to an **existing** worker name, use `add-agent --fo
|
|
|
276
250
|
|
|
277
251
|
Do **not** shutdown/restart the whole team just to add a **new** worker (that drops other workers' resumable sessions). Use `add-agent` without `--force` for a new name.
|
|
278
252
|
|
|
279
|
-
## Permissions
|
|
280
|
-
|
|
281
|
-
There is **no** `team-agent permission-modes` command.
|
|
282
|
-
|
|
283
|
-
```bash
|
|
284
|
-
team-agent permission-modes
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
Observed (exit 1): `invalid choice: 'permission-modes'`.
|
|
288
|
-
|
|
289
|
-
`team-agent --help` does **not** list `permission_mode`, `TEAM_AGENT_LEADER_BYPASS`, or `dangerous_auto_approve`. Use `team-agent validate "$d" --json` with an existing spec file or team directory; it does not enumerate permission modes.
|
|
290
|
-
|
|
291
|
-
### Live control: role `dangerously_skip_permissions`
|
|
292
|
-
|
|
293
|
-
Required boolean on every role doc. Missing or non-bool fails the internal compiler; this is checked again before lifecycle launch.
|
|
294
|
-
|
|
295
|
-
For an existing spec file, the retained schema check is:
|
|
296
|
-
|
|
297
|
-
```bash
|
|
298
|
-
team-agent validate "$d" --json
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
With a team-directory input, `validate` internally compiles `TEAM.md` and `agents/*.md` and validates role-document completeness; with a file input, it runs schema structural validation. Neither input writes or exports a spec file. The internal compiler rejects non-bool (`dangerously_skip_permissions: bypass`) and accepts only boolean **`true`** or **`false`**.
|
|
302
|
-
|
|
303
|
-
`true` is the per-worker bypass opt-in. `false` is the default you should copy unless the user explicitly wants prompts skipped.
|
|
253
|
+
## Document Format and Permissions
|
|
304
254
|
|
|
305
|
-
|
|
255
|
+
`TEAM.md` and `agents/*.md` accept ordinary text/Markdown without required YAML frontmatter. A valid optional frontmatter map may set supported metadata; absent, malformed, unterminated, or non-object frontmatter is treated as part of the document body, not a compile error. The entire TEAM body becomes `objective`; the role body is injected as the prompt.
|
|
306
256
|
|
|
307
|
-
|
|
257
|
+
For a role with no overrides, the filename stem supplies its id, and defaults are provider `pi`, model `openai-codex/gpt-6-luna`, effort `max`, and `dangerously_skip_permissions: true`. A valid `agent_id` (or legacy `name`) may override the filename-derived id. Supported valid frontmatter overrides remain available for existing roles; no permission field needs to be written. TEAM defaults are the workspace directory name, a 2-second tick, `leader_centric` communication, and `team-<workspace-name>` session.
|
|
308
258
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
Do not set `permission_mode: bypass` expecting 0.5.66 bypass. Use `dangerously_skip_permissions: true`.
|
|
312
|
-
|
|
313
|
-
### `TEAM.md` `dangerous_auto_approve`
|
|
314
|
-
|
|
315
|
-
The demo `TEAM.md` still shows `dangerous_auto_approve: false`. Compile of a team with `dangerous_auto_approve: true` produced a spec **without** that key on the agent (only `dangerously_skip_permissions`). Treat it as leftover team YAML, not the bypass switch.
|
|
316
|
-
|
|
317
|
-
`dangerous_auto_approve` as a **tool sentinel** is internal (adapters). Operators do not configure it as a tools list item.
|
|
318
|
-
|
|
319
|
-
### `TEAM_AGENT_LEADER_BYPASS`
|
|
320
|
-
|
|
321
|
-
Not in `team-agent --help`. Not a user-facing config key. Do not export it by hand. Worker env injection was **not** live-spawned on this gauge.
|
|
322
|
-
|
|
323
|
-
### Leader argv bypass
|
|
324
|
-
|
|
325
|
-
Leader `--dangerously-*` is detected only as a **warning**, not as worker bypass (`detect_bypass_flag_in_argv` — "只做检测,不做行为决策"). Declare `dangerously_skip_permissions` per role.
|
|
326
|
-
|
|
327
|
-
### Priority — 未找到单一裁决点
|
|
328
|
-
|
|
329
|
-
An external report ranked `permission_mode` > `TEAM_AGENT_LEADER_BYPASS` > `TEAM.md` `dangerous_auto_approve`. **That ranking is not in this tree.** Grep of `crates/` found **no** function that takes those three keys and picks a winner (search: `permission_mode.*TEAM_AGENT_LEADER_BYPASS` and the reverse: zero hits).
|
|
330
|
-
|
|
331
|
-
What the sources actually do (reader can re-open these files):
|
|
332
|
-
|
|
333
|
-
| Symbol | File | What it does |
|
|
334
|
-
|---|---|---|
|
|
335
|
-
| `required_dangerously_skip_permissions` | `crates/team-agent/src/compiler.rs` | Compile **requires** role `dangerously_skip_permissions` bool. This is the 0.5.66 worker bypass source. |
|
|
336
|
-
| `resolved_tool_strings_for_command` | `crates/team-agent/src/lifecycle/worker_command_context.rs` | `true` appends tool sentinel `dangerous_auto_approve`; comment: no longer consumes team/runtime/leader `DangerousApproval`. |
|
|
337
|
-
| `provider_bypass_flag` | `crates/team-agent/src/provider/bypass_flags.rs` | **唯一权威**: role `dangerously_skip_permissions: true` decides whether to add a provider bypass argv flag. Maps provider → flag string only. |
|
|
338
|
-
| spec allowed key `permission_mode` | `crates/team-agent/src/model/spec.rs` | Historical; **not consumed** by compiler (comment: 0.5.66 起不再被 compiler 消费); the key is absent from the compiled agent spec. |
|
|
339
|
-
| `apply_mcp_auto_approval_env` | `crates/team-agent/src/lifecycle/launch/worker_env.rs` | Writes `TEAM_AGENT_LEADER_BYPASS` `1`/`0` from `DangerousApproval` when source is `LeaderProcess`. Separate from compile. |
|
|
340
|
-
| `worker_spawn_env` test | `crates/team-agent/src/layout/worker_env.rs` | **Strips** inherited `TEAM_AGENT_LEADER_BYPASS` from parent env. |
|
|
341
|
-
| `claude_dangerous_auto_approve` (and siblings) | `crates/team-agent/src/provider/adapters/*.rs` | Adapters look for tool name `dangerous_auto_approve`, not `TEAM.md`. |
|
|
342
|
-
|
|
343
|
-
**Do not copy a three-row priority table.** The live operator knob on this gauge is role `dangerously_skip_permissions`. The three names from the report still exist as strings; they are not one ranked merge.
|
|
259
|
+
The generated spec still carries a boolean bypass value. Missing or malformed role metadata defaults to `true`; an explicit valid boolean is preserved. Provider adapters translate that value using the provider's own mechanism. Do not copy a Codex-only bypass flag into Pi or another provider's launch command.
|
|
344
260
|
|
|
261
|
+
`permission_mode`, `dangerous_auto_approve`, and leader environment switches are not required document fields. Keep provider-native bypass behavior inside the adapter; do not ask users to add a bypass toggle to `TEAM.md` or a plain-text role.
|
|
345
262
|
## Ignore vs handle (status / alerts)
|
|
346
263
|
|
|
347
264
|
```bash
|
|
@@ -524,7 +441,7 @@ provider or treats a diagnostic example as a command approval.
|
|
|
524
441
|
|
|
525
442
|
`restart` takes one workspace argument. It preserves each worker's original provider. If a verified provider session exists, the worker resumes (`codex resume <id>` or `claude --resume <id>`). Claude sessions are considered resumable only after the provider has written a project transcript for that session; a freshly opened blank Claude window is not recorded as recovered context. If the stored id is stale, the runtime first tries to repair it from verified transcript history. If a stored session cannot be verified or repaired, restart fails closed instead of silently losing context; use `team-agent restart . --allow-fresh` only when the user explicitly accepts a fresh worker context. If multiple stopped teams in the same workspace have restart context, plain `team-agent restart .` fails and lists candidates; rerun with `--team <session_name_or_team_name>`. If no prior session id exists, that worker starts fresh and the event log records `restart.fresh_spawn`. Claude resume must run from the original cwd and the same provider transcript root; Team Agent stores `spawn_cwd` and compatible-API `claude_projects_root` for that.
|
|
526
443
|
|
|
527
|
-
`restart` `--help` does not mention rereading `agents/*.md`. See **How role
|
|
444
|
+
`restart` `--help` does not mention rereading `agents/*.md`. See **How role documents become live**.
|
|
528
445
|
|
|
529
446
|
Startup trust prompts are handled by the runtime/coordinator with bounded probes; do not wait on raw worker screens or manually press Enter for routine startup trust prompts.
|
|
530
447
|
|
|
@@ -536,20 +453,9 @@ To add a new worker to a running team, write the role doc and run **one command*
|
|
|
536
453
|
|
|
537
454
|
```bash
|
|
538
455
|
cat > .team/current/agents/reviewer.md <<'EOF'
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
provider: codex
|
|
543
|
-
auth_mode: subscription
|
|
544
|
-
profile: codex-default
|
|
545
|
-
dangerously_skip_permissions: false
|
|
546
|
-
tools:
|
|
547
|
-
- fs_read
|
|
548
|
-
- fs_list
|
|
549
|
-
- mcp_team
|
|
550
|
-
---
|
|
551
|
-
|
|
552
|
-
Review changed files and report findings to leader.
|
|
456
|
+
# Code Reviewer
|
|
457
|
+
|
|
458
|
+
Review changed files and report findings to the leader. Use `send_message` for progress and `report_result` exactly once for completion.
|
|
553
459
|
EOF
|
|
554
460
|
team-agent add-agent reviewer --role-file .team/current/agents/reviewer.md --workspace .
|
|
555
461
|
```
|
|
@@ -581,6 +487,8 @@ Removing a worker at runtime is the symmetric `team-agent remove-agent <agent> -
|
|
|
581
487
|
|
|
582
488
|
## Worker Protocol
|
|
583
489
|
|
|
490
|
+
The Team Agent MCP surface is exactly `send_message`, `report_result`, and optional `get_team_status`. Status is self-inspection only, never a prerequisite; lifecycle management remains on the authorized native CLI.
|
|
491
|
+
|
|
584
492
|
Workers normally do not run nested Team Agent teams. When the user or leader explicitly asks for a child team, follow `references/team-in-team.md`; otherwise workers only provide the target and content for progress, and a short completion summary at the end:
|
|
585
493
|
|
|
586
494
|
```text
|
|
@@ -594,7 +502,7 @@ team_orchestrator.report_result(summary="short completion", status="success", te
|
|
|
594
502
|
|
|
595
503
|
For typed orchestration traffic, both `send_message` and `report_result` accept `presentation={"sink":"leader|casefile|silent","class":"message|progress|stage_result|stage_pass|bounce|blocking|final_review|timeout","case_id":"optional-case"}`. If the object is present, `sink` and `class` are required and unknown values fail closed. `casefile` and `silent` are durable-only, not deletion. The fixed critical classes `stage_pass`, `bounce`, `blocking`, `final_review`, and `timeout` always appear on the leader screen even when another sink is requested. Routing uses the typed class, never words in the content or summary.
|
|
596
504
|
|
|
597
|
-
Do not pass `sender`, `task_id`, `
|
|
505
|
+
Do not pass `sender`, `task_id`, `schema_version`, or `agent_id` unless doing a low-level compatibility diagnostic. The MCP runtime fills those fields and keeps delivery metadata in runtime state and event logs. If provider env loses the worker id, MCP infers it from active task/message state and falls back to an explicit `unknown` sender instead of treating the worker as leader.
|
|
598
506
|
|
|
599
507
|
Message targets are team-scoped. Use `leader`, another teammate agent id, or `*` for all other team members. The runtime excludes the sender from `*` broadcasts and never scans unrelated terminal windows for recipients.
|
|
600
508
|
|
|
@@ -630,7 +538,7 @@ Examples of `action` observed on this gauge:
|
|
|
630
538
|
|
|
631
539
|
Do not retry with changed flags. Do not inspect source code or private runtime state. Do not operate tmux directly except when the user asks for a manual diagnostic. Do not answer provider approval prompts for the user.
|
|
632
540
|
|
|
633
|
-
If `quick-start` reports `tmux session already exists`, treat it as a team-name collision. The existing session may be an active team; do not terminate it and do not suggest `shutdown` as the normal fix.
|
|
541
|
+
If `quick-start` reports `tmux session already exists`, treat it as a team-name collision. The existing session may be an active team; do not terminate it and do not suggest `shutdown` as the normal fix. Choose a distinct workspace folder name or set an optional `name:` override in valid `TEAM.md` frontmatter, then retry `team-agent quick-start .team/current`.
|
|
634
542
|
|
|
635
543
|
Known Team Agent control-plane MCP prompts such as `team_orchestrator.report_result` and `team_orchestrator.send_message` are handled by the coordinator. It uses session-scoped approval, verifies the prompt cleared, retries boundedly, and logs the result. Do not ask the user to approve those routine internal prompts.
|
|
636
544
|
|