@team-agent/installer 0.5.98 → 0.5.100
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 -163
- package/crates/team-agent/src/cli/diagnose.rs +3 -19
- package/crates/team-agent/src/cli/emit.rs +20 -204
- package/crates/team-agent/src/cli/mod.rs +138 -205
- package/crates/team-agent/src/cli/send/coordinator.rs +2 -2
- package/crates/team-agent/src/cli/spec.rs +41 -67
- package/crates/team-agent/src/cli/tests/main_preserved.rs +2 -186
- package/crates/team-agent/src/cli/tests/missing_subcommands.rs +9 -10
- package/crates/team-agent/src/cli/tests/run_delegation.rs +0 -3
- package/crates/team-agent/src/cli/tests/verb_validate.rs +0 -1
- package/crates/team-agent/src/cli/triage.rs +1 -1
- package/crates/team-agent/src/cli/types.rs +0 -55
- package/crates/team-agent/src/compiler/tests.rs +5 -8
- package/crates/team-agent/src/compiler.rs +6 -14
- package/crates/team-agent/src/leader/lease.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/agent_state.rs +5 -25
- package/crates/team-agent/src/lifecycle/launch/identity.rs +2 -18
- package/crates/team-agent/src/lifecycle/launch/layout.rs +7 -29
- package/crates/team-agent/src/lifecycle/launch/leader_context.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/ownership.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +7 -7
- package/crates/team-agent/src/lifecycle/launch/quick_start.rs +12 -49
- package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +3 -9
- package/crates/team-agent/src/lifecycle/launch/readiness.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +2 -61
- package/crates/team-agent/src/lifecycle/launch/spec_state.rs +2 -15
- package/crates/team-agent/src/lifecycle/launch/state_projection.rs +3 -7
- package/crates/team-agent/src/lifecycle/launch/worker_env.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch.rs +3 -4
- package/crates/team-agent/src/lifecycle/mod.rs +0 -8
- package/crates/team-agent/src/lifecycle/restart/agent.rs +62 -8
- package/crates/team-agent/src/lifecycle/restart/common.rs +0 -32
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +6 -15
- package/crates/team-agent/src/lifecycle/tests/b0_reader_hideone_audit_contract.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +1 -2
- package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +0 -1
- package/crates/team-agent/src/lifecycle/tests/core.rs +0 -213
- package/crates/team-agent/src/lifecycle/tests/issue238_codex_effort_contract.rs +96 -0
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +1 -0
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +31 -77
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +4 -8
- package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +16 -9
- package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/realmachine_clusters_1_6_red.rs +0 -60
- package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +3 -4
- package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests.rs +1 -2
- package/crates/team-agent/src/lifecycle/types.rs +3 -133
- package/crates/team-agent/src/messaging/send.rs +2 -2
- package/crates/team-agent/src/model/enums.rs +21 -71
- package/crates/team-agent/src/model/spec.rs +5 -20
- package/crates/team-agent/src/provider/adapters/codex.rs +2 -2
- package/crates/team-agent/src/provider/types.rs +7 -6
- package/crates/team-agent/src/state/repository.rs +0 -5
- package/examples/team.spec.yaml +0 -1
- package/package.json +4 -4
- package/schemas/team.schema.json +2 -2
- package/skills/team-agent/SKILL.md +1 -1
- package/skills/team-agent/references/recovery-runbook.md +2 -2
- package/skills/team-agent/references/team-agent-operator.md +3 -10
- package/skills/team-agent/references/team-in-team.md +0 -6
- package/crates/team-agent/src/lifecycle/display.rs +0 -550
- package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +0 -884
- package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +0 -481
|
@@ -10,7 +10,6 @@ pub(crate) enum CommandTier {
|
|
|
10
10
|
Guided,
|
|
11
11
|
Secondary,
|
|
12
12
|
DevInternal,
|
|
13
|
-
CompatHidden,
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
@@ -23,14 +22,12 @@ pub(crate) enum CommandCategory {
|
|
|
23
22
|
Setup,
|
|
24
23
|
Observe,
|
|
25
24
|
Dev,
|
|
26
|
-
Compat,
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
30
28
|
pub(crate) enum CommandKind {
|
|
31
29
|
Dispatch(DispatchKind),
|
|
32
30
|
LeaderPassthrough { provider: &'static str },
|
|
33
|
-
SpecOnlyAlias { alias_of: &'static str },
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
@@ -42,15 +39,12 @@ pub(crate) enum TokenUsage {
|
|
|
42
39
|
|
|
43
40
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
44
41
|
pub(crate) enum DispatchKind {
|
|
45
|
-
Init,
|
|
46
42
|
QuickStart,
|
|
47
43
|
Send,
|
|
48
44
|
AllowPeerTalk,
|
|
49
45
|
Status,
|
|
50
|
-
Stop,
|
|
51
46
|
Shutdown,
|
|
52
47
|
Restart,
|
|
53
|
-
RestartAgent,
|
|
54
48
|
StartAgent,
|
|
55
49
|
StopAgent,
|
|
56
50
|
ResetAgent,
|
|
@@ -58,9 +52,6 @@ pub(crate) enum DispatchKind {
|
|
|
58
52
|
CloneAgent,
|
|
59
53
|
ForkAgent,
|
|
60
54
|
RemoveAgent,
|
|
61
|
-
StuckList,
|
|
62
|
-
StuckCancel,
|
|
63
|
-
AcknowledgeIdle,
|
|
64
55
|
Takeover,
|
|
65
56
|
ClaimLeader,
|
|
66
57
|
AttachLeader,
|
|
@@ -77,7 +68,6 @@ pub(crate) enum DispatchKind {
|
|
|
77
68
|
Profile,
|
|
78
69
|
Results,
|
|
79
70
|
Wait,
|
|
80
|
-
Diagnose,
|
|
81
71
|
Preflight,
|
|
82
72
|
WaitReady,
|
|
83
73
|
E2e,
|
|
@@ -87,15 +77,12 @@ pub(crate) enum DispatchKind {
|
|
|
87
77
|
}
|
|
88
78
|
|
|
89
79
|
pub(crate) const ALL_DISPATCH_KINDS: &[DispatchKind] = &[
|
|
90
|
-
DispatchKind::Init,
|
|
91
80
|
DispatchKind::QuickStart,
|
|
92
81
|
DispatchKind::Send,
|
|
93
82
|
DispatchKind::AllowPeerTalk,
|
|
94
83
|
DispatchKind::Status,
|
|
95
|
-
DispatchKind::Stop,
|
|
96
84
|
DispatchKind::Shutdown,
|
|
97
85
|
DispatchKind::Restart,
|
|
98
|
-
DispatchKind::RestartAgent,
|
|
99
86
|
DispatchKind::StartAgent,
|
|
100
87
|
DispatchKind::StopAgent,
|
|
101
88
|
DispatchKind::ResetAgent,
|
|
@@ -103,9 +90,6 @@ pub(crate) const ALL_DISPATCH_KINDS: &[DispatchKind] = &[
|
|
|
103
90
|
DispatchKind::CloneAgent,
|
|
104
91
|
DispatchKind::ForkAgent,
|
|
105
92
|
DispatchKind::RemoveAgent,
|
|
106
|
-
DispatchKind::StuckList,
|
|
107
|
-
DispatchKind::StuckCancel,
|
|
108
|
-
DispatchKind::AcknowledgeIdle,
|
|
109
93
|
DispatchKind::Takeover,
|
|
110
94
|
DispatchKind::ClaimLeader,
|
|
111
95
|
DispatchKind::AttachLeader,
|
|
@@ -122,7 +106,6 @@ pub(crate) const ALL_DISPATCH_KINDS: &[DispatchKind] = &[
|
|
|
122
106
|
DispatchKind::Profile,
|
|
123
107
|
DispatchKind::Results,
|
|
124
108
|
DispatchKind::Wait,
|
|
125
|
-
DispatchKind::Diagnose,
|
|
126
109
|
DispatchKind::Preflight,
|
|
127
110
|
DispatchKind::WaitReady,
|
|
128
111
|
DispatchKind::E2e,
|
|
@@ -149,7 +132,6 @@ pub(crate) struct CommandSpec {
|
|
|
149
132
|
pub(crate) command_help: bool,
|
|
150
133
|
pub(crate) suggestion_index: bool,
|
|
151
134
|
pub(crate) token_usage: TokenUsage,
|
|
152
|
-
pub(crate) alias_of: Option<&'static str>,
|
|
153
135
|
pub(crate) sunset: Option<&'static str>,
|
|
154
136
|
pub(crate) action: Option<&'static str>,
|
|
155
137
|
pub(crate) governance: Option<GovernanceNote>,
|
|
@@ -162,58 +144,50 @@ pub(crate) struct CommandSpec {
|
|
|
162
144
|
/// numeric slack threshold.
|
|
163
145
|
#[rustfmt::skip]
|
|
164
146
|
pub(crate) const COMMAND_SPECS: &[CommandSpec] = &[
|
|
165
|
-
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] [--
|
|
166
|
-
CommandSpec { name: "send", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Send), summary: "persist a message for an in-team short name or fully-qualified logical recipient", usage: "usage: team-agent send TO MESSAGE... [--workspace WORKSPACE] [--team TEAM] [--mailbox] [--json]\nTO forms are co-equal: an in-team short name (for example `team-agent send reviewer \"Review\"`) or `<workspace>::<team>/<agent>`.", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional,
|
|
167
|
-
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,
|
|
168
|
-
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|cursor_agent] [QUERY|--search TEXT] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No,
|
|
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: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No,
|
|
170
|
-
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,
|
|
171
|
-
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,
|
|
172
|
-
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,
|
|
173
|
-
CommandSpec { name: "add-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::AddAgent), summary: "add or force-recreate a worker", usage: "usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--
|
|
174
|
-
CommandSpec { name: "start-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::StartAgent), summary: "start an existing worker", usage: "usage: team-agent start-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--force] [--allow-fresh] [--
|
|
175
|
-
CommandSpec { name: "stop-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::StopAgent), summary: "stop a worker", usage: "usage: team-agent stop-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No,
|
|
176
|
-
CommandSpec { name: "reset-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ResetAgent), summary: "reset a worker session", usage: "usage: team-agent reset-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--
|
|
177
|
-
CommandSpec { name: "
|
|
178
|
-
CommandSpec { name: "
|
|
179
|
-
CommandSpec { name: "
|
|
180
|
-
CommandSpec { name: "attach-leader", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::AttachLeader), summary: "bind an external leader pane", usage: "usage: team-agent attach-leader [--workspace WORKSPACE] [--team TEAM] [--pane PANE] [--provider PROVIDER] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, alias_of: None, sunset: None, action: None, governance: None },
|
|
147
|
+
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] [--backend tmux|conpty] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, sunset: None, action: None, governance: None },
|
|
148
|
+
CommandSpec { name: "send", tier: CommandTier::Core, category: CommandCategory::Daily, kind: CommandKind::Dispatch(DispatchKind::Send), summary: "persist a message for an in-team short name or fully-qualified logical recipient", usage: "usage: team-agent send TO MESSAGE... [--workspace WORKSPACE] [--team TEAM] [--mailbox] [--json]\nTO forms are co-equal: an in-team short name (for example `team-agent send reviewer \"Review\"`) or `<workspace>::<team>/<agent>`.", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, sunset: Some("next compatibility release"), action: Some("use positional logical TO and the returned message id"), governance: None },
|
|
149
|
+
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, sunset: None, action: None, governance: None },
|
|
150
|
+
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|cursor_agent] [QUERY|--search TEXT] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
151
|
+
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, sunset: None, action: None, governance: None },
|
|
152
|
+
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, sunset: None, action: None, governance: None },
|
|
153
|
+
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, sunset: None, action: None, governance: None },
|
|
154
|
+
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, sunset: None, action: None, governance: None },
|
|
155
|
+
CommandSpec { name: "add-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::AddAgent), summary: "add or force-recreate a worker", usage: "usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, sunset: None, action: None, governance: None },
|
|
156
|
+
CommandSpec { name: "start-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::StartAgent), summary: "start an existing worker", usage: "usage: team-agent start-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--force] [--allow-fresh] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, sunset: None, action: None, governance: None },
|
|
157
|
+
CommandSpec { name: "stop-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::StopAgent), summary: "stop a worker", usage: "usage: team-agent stop-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
158
|
+
CommandSpec { name: "reset-agent", tier: CommandTier::Core, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ResetAgent), summary: "reset a worker session", usage: "usage: team-agent reset-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--discard-session] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::Conditional, sunset: None, action: None, governance: None },
|
|
159
|
+
CommandSpec { name: "claim-leader", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::ClaimLeader), summary: "bind this pane when doctor reports rebind_required", usage: "usage: team-agent claim-leader [--workspace WORKSPACE] [--team TEAM] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
160
|
+
CommandSpec { name: "takeover", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::Takeover), summary: "replace a live leader binding with explicit consent", usage: "usage: team-agent takeover [--workspace WORKSPACE] [--team TEAM] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
161
|
+
CommandSpec { name: "attach-leader", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::AttachLeader), summary: "bind an external leader pane", usage: "usage: team-agent attach-leader [--workspace WORKSPACE] [--team TEAM] [--pane PANE] [--provider PROVIDER] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
181
162
|
|
|
182
|
-
CommandSpec { name: "codex", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "codex" }, summary: "launch a Codex leader", usage: "usage: team-agent codex [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes,
|
|
183
|
-
CommandSpec { name: "claude", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "claude" }, summary: "launch a Claude leader", usage: "usage: team-agent claude [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes,
|
|
184
|
-
CommandSpec { name: "copilot", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "copilot" }, summary: "launch a Copilot leader", usage: "usage: team-agent copilot [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes,
|
|
185
|
-
CommandSpec { name: "grok", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "grok" }, summary: "launch a Grok leader", usage: "usage: team-agent grok [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes,
|
|
186
|
-
CommandSpec { name: "cursor", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "cursor" }, summary: "launch a Cursor leader", usage: "usage: team-agent cursor [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes,
|
|
187
|
-
CommandSpec { name: "pi", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "pi" }, summary: "launch a Pi leader", usage: "usage: team-agent pi -- --model <exact> --thinking <effort>", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes,
|
|
163
|
+
CommandSpec { name: "codex", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "codex" }, summary: "launch a Codex leader", usage: "usage: team-agent codex [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes, sunset: None, action: None, governance: None },
|
|
164
|
+
CommandSpec { name: "claude", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "claude" }, summary: "launch a Claude leader", usage: "usage: team-agent claude [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes, sunset: None, action: None, governance: None },
|
|
165
|
+
CommandSpec { name: "copilot", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "copilot" }, summary: "launch a Copilot leader", usage: "usage: team-agent copilot [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes, sunset: None, action: None, governance: None },
|
|
166
|
+
CommandSpec { name: "grok", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "grok" }, summary: "launch a Grok leader", usage: "usage: team-agent grok [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes, sunset: None, action: None, governance: None },
|
|
167
|
+
CommandSpec { name: "cursor", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "cursor" }, summary: "launch a Cursor leader", usage: "usage: team-agent cursor [provider args...]", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes, sunset: None, action: None, governance: None },
|
|
168
|
+
CommandSpec { name: "pi", tier: CommandTier::Core, category: CommandCategory::Start, kind: CommandKind::LeaderPassthrough { provider: "pi" }, summary: "launch a Pi leader", usage: "usage: team-agent pi -- --model <exact> --thinking <effort>", default_help: false, command_help: true, suggestion_index: true, token_usage: TokenUsage::Yes, sunset: None, action: None, governance: None },
|
|
188
169
|
|
|
189
|
-
CommandSpec { name: "
|
|
190
|
-
CommandSpec { name: "
|
|
191
|
-
CommandSpec { name: "
|
|
192
|
-
CommandSpec { name: "
|
|
193
|
-
CommandSpec { name: "
|
|
194
|
-
CommandSpec { name: "
|
|
195
|
-
CommandSpec { name: "
|
|
196
|
-
CommandSpec { name: "
|
|
197
|
-
CommandSpec { name: "
|
|
198
|
-
CommandSpec { name: "
|
|
199
|
-
CommandSpec { name: "
|
|
200
|
-
CommandSpec { name: "fork-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ForkAgent), summary: "fork a worker", usage: "usage: team-agent fork-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 },
|
|
201
|
-
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
|
-
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
|
-
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] [--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
|
-
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
|
-
CommandSpec { name: "inbox", tier: CommandTier::Secondary, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Inbox), summary: "inspect recent message summaries", usage: "usage: team-agent inbox AGENT [-n N|--limit N] [--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: None },
|
|
170
|
+
CommandSpec { name: "leaders", tier: CommandTier::Secondary, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Leaders), summary: "list live, stale, or ambiguous host leaders", usage: "usage: team-agent leaders [QUERY|--search TEXT] [--all|--stale] [--json] | --prune [--dry-run] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
171
|
+
CommandSpec { name: "doctor", tier: CommandTier::Core, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Doctor), summary: "inspect environment and Team runtime health", usage: "usage: team-agent doctor [SPEC] [--workspace WORKSPACE] [--team TEAM] [--gate orphans|comms] [--comms] [--fix] [--fix-schema] [--cleanup-orphans] [--confirm] [--json]", default_help: true, command_help: true, suggestion_index: true, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
172
|
+
CommandSpec { name: "attach-app-server-leader", tier: CommandTier::Guided, category: CommandCategory::GuidedRecovery, kind: CommandKind::Dispatch(DispatchKind::AttachAppServerLeader), summary: "bind an app-server leader receiver", usage: "usage: team-agent attach-app-server-leader [--workspace WORKSPACE] [--team TEAM] --socket unix:///path.sock --thread-id THREAD_ID [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
173
|
+
CommandSpec { name: "remove-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::RemoveAgent), summary: "remove a worker", usage: "usage: team-agent remove-agent AGENT [--workspace WORKSPACE] [--team TEAM] [--from-spec] [--confirm] [--force] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
174
|
+
CommandSpec { name: "fork-agent", tier: CommandTier::Secondary, category: CommandCategory::WorkerLifecycle, kind: CommandKind::Dispatch(DispatchKind::ForkAgent), summary: "fork a worker", usage: "usage: team-agent fork-agent SOURCE_AGENT --as AGENT [--label LABEL] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, sunset: None, action: None, governance: None },
|
|
175
|
+
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] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Conditional, sunset: None, action: None, governance: None },
|
|
176
|
+
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, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "capability/config surface" }) },
|
|
177
|
+
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, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "approval diagnostics" }) },
|
|
178
|
+
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, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "provider/profile setup" }) },
|
|
179
|
+
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, sunset: None, action: None, governance: Some(GovernanceNote { decision: "secondary", reason: "capability setup" }) },
|
|
180
|
+
CommandSpec { name: "inbox", tier: CommandTier::Secondary, category: CommandCategory::Observe, kind: CommandKind::Dispatch(DispatchKind::Inbox), summary: "inspect recent message summaries", usage: "usage: team-agent inbox AGENT [-n N|--limit N] [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
207
181
|
|
|
208
|
-
CommandSpec { name: "identity", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Identity), summary: "inspect identity metadata", usage: "usage: team-agent identity [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
209
|
-
CommandSpec { name: "watch", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Watch), summary: "watch event logs", usage: "usage: team-agent watch [--workspace WORKSPACE] [--team TEAM]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
210
|
-
CommandSpec { name: "sessions", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Sessions), summary: "inspect session inventory", usage: "usage: team-agent sessions [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
211
|
-
CommandSpec { name: "validate", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Validate), summary: "validate a team spec", usage: "usage: team-agent validate [SPEC] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
212
|
-
CommandSpec { name: "preflight", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Preflight), summary: "run preflight checks", usage: "usage: team-agent preflight [TEAMDIR] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
213
|
-
CommandSpec { name: "wait-ready", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::WaitReady), summary: "wait for runtime readiness", usage: "usage: team-agent wait-ready [--workspace WORKSPACE] [--team TEAM] [--timeout SECONDS] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
214
|
-
CommandSpec { name: "e2e", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::E2e), summary: "run e2e harness", usage: "usage: team-agent e2e [--workspace WORKSPACE] [--providers LIST] [--real] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Yes,
|
|
215
|
-
CommandSpec { name: "peek", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Peek), summary: "capture low-level terminal output", usage: "usage: team-agent peek AGENT [--workspace WORKSPACE] [--tail N|--head N] [--search TEXT] [--allow-raw-screen] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
216
|
-
CommandSpec { name: "coordinator", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Coordinator), summary: "run the coordinator daemon", usage: "usage: team-agent coordinator [--workspace WORKSPACE] [--once] [--tick-interval SECONDS]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No,
|
|
182
|
+
CommandSpec { name: "identity", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Identity), summary: "inspect identity metadata", usage: "usage: team-agent identity [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
183
|
+
CommandSpec { name: "watch", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Watch), summary: "watch event logs", usage: "usage: team-agent watch [--workspace WORKSPACE] [--team TEAM]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
184
|
+
CommandSpec { name: "sessions", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Sessions), summary: "inspect session inventory", usage: "usage: team-agent sessions [--workspace WORKSPACE] [--team TEAM] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
185
|
+
CommandSpec { name: "validate", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Validate), summary: "validate a team spec", usage: "usage: team-agent validate [SPEC] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
186
|
+
CommandSpec { name: "preflight", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Preflight), summary: "run preflight checks", usage: "usage: team-agent preflight [TEAMDIR] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
187
|
+
CommandSpec { name: "wait-ready", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::WaitReady), summary: "wait for runtime readiness", usage: "usage: team-agent wait-ready [--workspace WORKSPACE] [--team TEAM] [--timeout SECONDS] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
188
|
+
CommandSpec { name: "e2e", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::E2e), summary: "run e2e harness", usage: "usage: team-agent e2e [--workspace WORKSPACE] [--providers LIST] [--real] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::Yes, sunset: None, action: None, governance: None },
|
|
189
|
+
CommandSpec { name: "peek", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Peek), summary: "capture low-level terminal output", usage: "usage: team-agent peek AGENT [--workspace WORKSPACE] [--tail N|--head N] [--search TEXT] [--allow-raw-screen] [--json]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
190
|
+
CommandSpec { name: "coordinator", tier: CommandTier::DevInternal, category: CommandCategory::Dev, kind: CommandKind::Dispatch(DispatchKind::Coordinator), summary: "run the coordinator daemon", usage: "usage: team-agent coordinator [--workspace WORKSPACE] [--once] [--tick-interval SECONDS]", default_help: false, command_help: true, suggestion_index: false, token_usage: TokenUsage::No, sunset: None, action: None, governance: None },
|
|
217
191
|
];
|
|
218
192
|
|
|
219
193
|
pub(crate) fn command_spec(name: &str) -> Option<&'static CommandSpec> {
|
|
@@ -71,7 +71,6 @@ communication:
|
|
|
71
71
|
mirror_files: ".team/messages"
|
|
72
72
|
runtime:
|
|
73
73
|
backend: "tmux"
|
|
74
|
-
display_backend: "none"
|
|
75
74
|
session_name: "team-agent-fake-e2e"
|
|
76
75
|
auto_launch: true
|
|
77
76
|
require_user_approval_before_launch: false
|
|
@@ -107,92 +106,6 @@ fn seed_team_spec(ws: &std::path::Path) {
|
|
|
107
106
|
std::fs::write(ws.join("team.spec.yaml"), spec).unwrap();
|
|
108
107
|
}
|
|
109
108
|
|
|
110
|
-
// ── ACK-CRACK [P1 byte-shape] — acknowledge_idle must write golden's TTL suppression shape ───────
|
|
111
|
-
// golden runtime.py:680-688: manual-acknowledge persists
|
|
112
|
-
// coordinator.idle_acknowledged[team] = {acknowledged_at, expires_at, ttl_seconds}
|
|
113
|
-
// coordinator.suppressed_idle_alerts[team][worker].idle_fallback =
|
|
114
|
-
// {suppressed_at, suppressed_by:"manual_acknowledge", manual_acknowledge:true, expires_at, ttl_seconds}
|
|
115
|
-
// The clear logic does datetime.fromisoformat(entry["expires_at"]); a MISSING expires_at -> ValueError
|
|
116
|
-
// -> "invalid_suppression_timestamp" -> immediate self-clear (latent crack once detect_idle_fallbacks
|
|
117
|
-
// is ported). So BOTH idle_acknowledged and the entry MUST carry a non-empty expires_at.
|
|
118
|
-
#[test]
|
|
119
|
-
fn acknowledge_idle_writes_golden_ttl_suppression_shape() {
|
|
120
|
-
let ws = tmp_workspace();
|
|
121
|
-
crate::state::persist::save_runtime_state(
|
|
122
|
-
&ws,
|
|
123
|
-
&serde_json::json!({
|
|
124
|
-
"active_team_key": "teamX",
|
|
125
|
-
"agents": {"w1": {"status": "running", "provider": "codex"}}
|
|
126
|
-
}),
|
|
127
|
-
)
|
|
128
|
-
.unwrap();
|
|
129
|
-
let _ = lifecycle_port::acknowledge_idle(&ws, None).expect("acknowledge_idle ok");
|
|
130
|
-
let state = crate::state::persist::load_runtime_state(&ws).unwrap();
|
|
131
|
-
let ack = &state["coordinator"]["idle_acknowledged"]["teamX"];
|
|
132
|
-
assert!(
|
|
133
|
-
ack.get("expires_at")
|
|
134
|
-
.and_then(serde_json::Value::as_str)
|
|
135
|
-
.is_some_and(|s| !s.is_empty()),
|
|
136
|
-
"ACK-CRACK: idle_acknowledged[team] must carry a non-empty expires_at (golden); got {ack}"
|
|
137
|
-
);
|
|
138
|
-
assert!(
|
|
139
|
-
ack.get("ttl_seconds").is_some(),
|
|
140
|
-
"idle_acknowledged[team] must carry ttl_seconds; got {ack}"
|
|
141
|
-
);
|
|
142
|
-
let entry = &state["coordinator"]["suppressed_idle_alerts"]["teamX"]["w1"]["idle_fallback"];
|
|
143
|
-
assert!(
|
|
144
|
-
entry.get("expires_at").and_then(serde_json::Value::as_str).is_some_and(|s| !s.is_empty()),
|
|
145
|
-
"ACK-CRACK: the manual-ack suppression entry must carry expires_at (else clear logic ValueErrors \
|
|
146
|
-
-> instant self-clear); got {entry}"
|
|
147
|
-
);
|
|
148
|
-
assert_eq!(
|
|
149
|
-
entry["suppressed_by"],
|
|
150
|
-
serde_json::json!("manual_acknowledge"),
|
|
151
|
-
"golden suppressed_by; got {entry}"
|
|
152
|
-
);
|
|
153
|
-
assert_eq!(
|
|
154
|
-
entry["manual_acknowledge"],
|
|
155
|
-
serde_json::json!(true),
|
|
156
|
-
"golden manual_acknowledge:true; got {entry}"
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
// ── ACK return-shape [P1 byte-parity] — acknowledge_idle must RETURN golden's keys ───────────────
|
|
160
|
-
// golden runtime.py:691: return {ok, team, agent_id, acknowledged_at, expires_at, ttl_seconds}.
|
|
161
|
-
// Rust (cli/mod.rs) returns only {ok, team, ttl_seconds} -> missing agent_id, acknowledged_at,
|
|
162
|
-
// expires_at. RED. (acknowledged_at/expires_at are the same values written into idle_acknowledged.)
|
|
163
|
-
#[test]
|
|
164
|
-
fn acknowledge_idle_return_carries_golden_keys() {
|
|
165
|
-
let ws = tmp_workspace();
|
|
166
|
-
crate::state::persist::save_runtime_state(
|
|
167
|
-
&ws,
|
|
168
|
-
&serde_json::json!({ "active_team_key": "teamX", "agents": {"w1": {"status": "running", "provider": "codex"}} }),
|
|
169
|
-
)
|
|
170
|
-
.unwrap();
|
|
171
|
-
let r = lifecycle_port::acknowledge_idle(&ws, None).expect("acknowledge_idle ok");
|
|
172
|
-
let obj = r.as_object().expect("ack returns a dict");
|
|
173
|
-
for key in [
|
|
174
|
-
"ok",
|
|
175
|
-
"team",
|
|
176
|
-
"agent_id",
|
|
177
|
-
"acknowledged_at",
|
|
178
|
-
"expires_at",
|
|
179
|
-
"ttl_seconds",
|
|
180
|
-
] {
|
|
181
|
-
assert!(
|
|
182
|
-
obj.contains_key(key),
|
|
183
|
-
"ACK return-shape: golden return carries `{key}` (runtime.py:691: ok/team/agent_id/\
|
|
184
|
-
acknowledged_at/expires_at/ttl_seconds); Rust omits it. got keys {:?}",
|
|
185
|
-
obj.keys().collect::<Vec<_>>()
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
assert!(
|
|
189
|
-
obj.get("expires_at")
|
|
190
|
-
.and_then(serde_json::Value::as_str)
|
|
191
|
-
.is_some_and(|s| !s.is_empty()),
|
|
192
|
-
"ACK return-shape: expires_at must be a non-empty timestamp; got {r}"
|
|
193
|
-
);
|
|
194
|
-
let _ = std::fs::remove_dir_all(&ws);
|
|
195
|
-
}
|
|
196
109
|
// ── BUG-2 [real bug] — inbox must RETURN the stored messages, not a hardcoded []. ────────────────
|
|
197
110
|
// Golden status/inbox.py:35-38 -> MessageStore.inbox(agent_id) (core.py:242, owner_team_id=None):
|
|
198
111
|
// select <MESSAGE_SELECT> from messages where sender = ? or recipient = ? order by created_at desc
|
|
@@ -681,16 +594,7 @@ fn remove_agent_from_spec_refusal_is_not_success_envelope() {
|
|
|
681
594
|
fn stuck_cancel_persists_suppression_and_stuck_list_reads_state() {
|
|
682
595
|
let ws = tmp_workspace();
|
|
683
596
|
seed_collect_state(&ws);
|
|
684
|
-
let out =
|
|
685
|
-
cmd_stuck_cancel(&StuckCancelArgs {
|
|
686
|
-
agent: "fake_impl".to_string(),
|
|
687
|
-
workspace: ws.clone(),
|
|
688
|
-
alert_type: None,
|
|
689
|
-
json: true,
|
|
690
|
-
team: None,
|
|
691
|
-
})
|
|
692
|
-
.unwrap(),
|
|
693
|
-
);
|
|
597
|
+
let out = messaging::stuck_cancel(&ws, "fake_impl", None, "leader").unwrap();
|
|
694
598
|
let team_key = seeded_team_key(&ws);
|
|
695
599
|
assert_eq!(out["ok"], json!(true));
|
|
696
600
|
assert_eq!(
|
|
@@ -716,98 +620,10 @@ fn stuck_cancel_persists_suppression_and_stuck_list_reads_state() {
|
|
|
716
620
|
&& e["agent_id"] == json!("fake_impl")),
|
|
717
621
|
"stuck_cancel must write coordinator.idle_alert_suppressed"
|
|
718
622
|
);
|
|
719
|
-
let listed =
|
|
720
|
-
cmd_stuck_list(&StuckListArgs {
|
|
721
|
-
workspace: ws.clone(),
|
|
722
|
-
json: true,
|
|
723
|
-
team: None,
|
|
724
|
-
})
|
|
725
|
-
.unwrap(),
|
|
726
|
-
);
|
|
623
|
+
let listed = messaging::stuck_list(&ws).unwrap();
|
|
727
624
|
assert_eq!(
|
|
728
625
|
listed["suppressed_idle_alerts"]["fake_impl"]["stuck"]["suppressed_by"],
|
|
729
626
|
json!("leader"),
|
|
730
627
|
"stuck-list must read the persisted state mirror, not return a hard-coded empty list"
|
|
731
628
|
);
|
|
732
629
|
}
|
|
733
|
-
|
|
734
|
-
#[test]
|
|
735
|
-
fn stuck_cancel_explicit_team_is_rejected_until_backend_is_scoped() {
|
|
736
|
-
let ws = tmp_workspace();
|
|
737
|
-
seed_collect_state(&ws);
|
|
738
|
-
let err = cmd_stuck_cancel(&StuckCancelArgs {
|
|
739
|
-
agent: "fake_impl".to_string(),
|
|
740
|
-
workspace: ws.clone(),
|
|
741
|
-
alert_type: None,
|
|
742
|
-
json: true,
|
|
743
|
-
team: Some("current".to_string()),
|
|
744
|
-
})
|
|
745
|
-
.expect_err("explicit --team must not silently write global stuck suppression");
|
|
746
|
-
assert!(
|
|
747
|
-
err.to_string().contains("not supported yet"),
|
|
748
|
-
"stuck-cancel --team must be an explicit refusal until backend supports scoped writes; got {err}"
|
|
749
|
-
);
|
|
750
|
-
let _ = std::fs::remove_dir_all(&ws);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
#[test]
|
|
754
|
-
fn stuck_cancel_invalid_alert_type_is_rejected() {
|
|
755
|
-
let ws = tmp_workspace();
|
|
756
|
-
seed_collect_state(&ws);
|
|
757
|
-
let code = run(
|
|
758
|
-
&cli_argv(&[
|
|
759
|
-
"stuck-cancel",
|
|
760
|
-
"fake_impl",
|
|
761
|
-
"--workspace",
|
|
762
|
-
&ws.to_string_lossy(),
|
|
763
|
-
"--alert-type",
|
|
764
|
-
"bogus",
|
|
765
|
-
"--json",
|
|
766
|
-
]),
|
|
767
|
-
&ws,
|
|
768
|
-
);
|
|
769
|
-
assert_eq!(
|
|
770
|
-
code,
|
|
771
|
-
ExitCode::Error,
|
|
772
|
-
"Python rejects alert_type outside stuck/idle_fallback/cross_worker_deadlock/all; Rust must not silently coerce bogus to stuck"
|
|
773
|
-
);
|
|
774
|
-
}
|
|
775
|
-
#[test]
|
|
776
|
-
fn acknowledge_idle_records_manual_idle_fallback_suppression_and_event() {
|
|
777
|
-
let ws = tmp_workspace();
|
|
778
|
-
seed_collect_state(&ws);
|
|
779
|
-
let out = json_output(
|
|
780
|
-
cmd_acknowledge_idle(&AcknowledgeIdleArgs {
|
|
781
|
-
team: None,
|
|
782
|
-
workspace: ws.clone(),
|
|
783
|
-
json: true,
|
|
784
|
-
})
|
|
785
|
-
.unwrap(),
|
|
786
|
-
);
|
|
787
|
-
let team_key = seeded_team_key(&ws);
|
|
788
|
-
assert_eq!(out["ok"], json!(true));
|
|
789
|
-
assert_eq!(out["team"], json!(team_key));
|
|
790
|
-
assert_eq!(out["ttl_seconds"], json!(1800));
|
|
791
|
-
let state = read_state(&ws);
|
|
792
|
-
let ack = &state["coordinator"]["idle_acknowledged"][&team_key];
|
|
793
|
-
assert_eq!(ack["ttl_seconds"], json!(1800));
|
|
794
|
-
assert!(ack["acknowledged_at"].as_str().is_some());
|
|
795
|
-
assert_eq!(
|
|
796
|
-
state["coordinator"]["suppressed_idle_alerts"][&team_key]["fake_impl"]["idle_fallback"]
|
|
797
|
-
["suppressed_by"],
|
|
798
|
-
json!("manual_acknowledge")
|
|
799
|
-
);
|
|
800
|
-
assert_eq!(
|
|
801
|
-
state["coordinator"]["suppressed_idle_alerts"][&team_key]["fake_impl"]["idle_fallback"]
|
|
802
|
-
["manual_acknowledge"],
|
|
803
|
-
json!(true)
|
|
804
|
-
);
|
|
805
|
-
assert!(
|
|
806
|
-
read_events(&ws)
|
|
807
|
-
.iter()
|
|
808
|
-
.any(|e| e["event"] == json!("coordinator.idle_acknowledged")
|
|
809
|
-
&& e["team"] == json!(team_key)
|
|
810
|
-
&& e["ttl_seconds"] == json!(1800)),
|
|
811
|
-
"acknowledge-idle must emit coordinator.idle_acknowledged"
|
|
812
|
-
);
|
|
813
|
-
}
|
|
@@ -239,7 +239,6 @@ communication:
|
|
|
239
239
|
mirror_files: ".team/messages"
|
|
240
240
|
runtime:
|
|
241
241
|
backend: "tmux"
|
|
242
|
-
display_backend: "none"
|
|
243
242
|
session_name: "team-agent-fake-e2e"
|
|
244
243
|
auto_launch: true
|
|
245
244
|
require_user_approval_before_launch: false
|
|
@@ -333,15 +332,15 @@ fn dispatch_routes_diagnose_checks_runtime_beyond_healthy_leader() {
|
|
|
333
332
|
leader_env: Default::default(),
|
|
334
333
|
}]);
|
|
335
334
|
crate::transport_factory::with_leader_endpoint_transport(endpoint, transport, || {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
343
|
-
let result = cmd_diagnose(&DiagnoseArgs {
|
|
335
|
+
let code = run(
|
|
336
|
+
&cli_argv(&["doctor", "--workspace", &ws.to_string_lossy(), "--json"]),
|
|
337
|
+
&ws,
|
|
338
|
+
);
|
|
339
|
+
assert_eq!(code, ExitCode::Error, "healthy binding alone cannot hide missing coordinator");
|
|
340
|
+
let result = cmd_doctor(&DoctorArgs {
|
|
344
341
|
workspace: ws.clone(), json: true, team: None,
|
|
342
|
+
spec: None, gate: None, comms: false, fix: false,
|
|
343
|
+
fix_schema: false, cleanup_orphans: false, confirm: false,
|
|
345
344
|
}).expect("diagnostic report");
|
|
346
345
|
let CmdOutput::Json(report) = result.output else {
|
|
347
346
|
panic!("expected JSON diagnostic report");
|
|
@@ -378,7 +377,7 @@ fn dispatch_routes_diagnose_self_signed_attached_without_registry_is_not_ok() {
|
|
|
378
377
|
let ws = tmp_workspace();
|
|
379
378
|
seed_self_signed_attached_leader(&ws);
|
|
380
379
|
let code = run(
|
|
381
|
-
&cli_argv(&["
|
|
380
|
+
&cli_argv(&["doctor", "--workspace", &ws.to_string_lossy(), "--json"]),
|
|
382
381
|
&ws,
|
|
383
382
|
);
|
|
384
383
|
assert_ne!(
|
|
@@ -222,7 +222,6 @@ fn cli_quick_start_invokes_real_lifecycle_compiles_spec() {
|
|
|
222
222
|
name: None,
|
|
223
223
|
team_id: None,
|
|
224
224
|
yes: true,
|
|
225
|
-
no_display: false,
|
|
226
225
|
backend: None,
|
|
227
226
|
json: true,
|
|
228
227
|
detail: false,
|
|
@@ -258,7 +257,6 @@ fn cli_quick_start_invalid_spec_surfaces_real_compile_error() {
|
|
|
258
257
|
name: None,
|
|
259
258
|
team_id: None,
|
|
260
259
|
yes: false,
|
|
261
|
-
no_display: false,
|
|
262
260
|
backend: None,
|
|
263
261
|
json: true,
|
|
264
262
|
detail: false,
|
|
@@ -324,7 +322,6 @@ fn cli_add_agent_duplicate_id_surfaces_real_error() {
|
|
|
324
322
|
team: None,
|
|
325
323
|
role_file: dup_role.to_string_lossy().to_string(),
|
|
326
324
|
force: false,
|
|
327
|
-
no_display: false,
|
|
328
325
|
json: true,
|
|
329
326
|
};
|
|
330
327
|
let text = outcome_text(cmd_add_agent(&args));
|
|
@@ -138,7 +138,7 @@ mod tests {
|
|
|
138
138
|
"providers": {"claude": {"version": "secret"}},
|
|
139
139
|
"runtime": {"workspace": "/tmp/secret"}
|
|
140
140
|
});
|
|
141
|
-
let output = render("
|
|
141
|
+
let output = render("doctor", &report);
|
|
142
142
|
assert!(output.contains("issue: short_issue"));
|
|
143
143
|
assert!(output.contains("issue: code=object_issue"));
|
|
144
144
|
assert!(output.contains("repair: action=run repair"));
|