@team-agent/installer 0.5.100 → 0.5.101
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/diagnose.rs +29 -7
- package/crates/team-agent/src/cli/mod.rs +24 -8
- package/crates/team-agent/src/compiler.rs +3 -0
- package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +211 -16
- package/crates/team-agent/src/lifecycle/launch/clone_agent.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch/fork_agent.rs +15 -5
- package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +89 -6
- package/crates/team-agent/src/lifecycle/launch/role_source.rs +168 -32
- package/crates/team-agent/src/lifecycle/launch.rs +11 -3
- package/crates/team-agent/src/lifecycle/profile_launch.rs +23 -8
- package/crates/team-agent/src/lifecycle/restart/agent.rs +2 -2
- package/crates/team-agent/src/lifecycle/restart/avatar.rs +1806 -0
- package/crates/team-agent/src/lifecycle/restart/common.rs +114 -1
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +8 -2
- package/crates/team-agent/src/lifecycle/restart/selection.rs +14 -2
- package/crates/team-agent/src/lifecycle/restart.rs +11 -4
- package/crates/team-agent/src/lifecycle/tests/pi_fork_session_inheritance_red.rs +1398 -0
- package/crates/team-agent/src/lifecycle/tests.rs +1 -0
- package/crates/team-agent/src/lifecycle/types.rs +10 -2
- package/crates/team-agent/src/model/spec.rs +1 -0
- package/crates/team-agent/src/provider/types.rs +2 -0
- package/crates/team-agent/src/state/persist.rs +58 -2
- package/crates/team-agent/src/state/projection.rs +5 -1
- package/crates/team-agent/src/state/repository.rs +125 -4
- package/crates/team-agent/src/transport/test_support.rs +23 -3
- package/package.json +4 -4
- package/skills/team-agent/SKILL.md +17 -46
- package/skills/team-agent/references/team-agent-operator.md +4 -2
|
@@ -954,7 +954,7 @@ pub(crate) fn lifecycle_worker_transport_for_selected_state(
|
|
|
954
954
|
/// returns: 后端与 endpoint 来源
|
|
955
955
|
/// errors: state 声明后端是 conpty 时返回 TeamSelect
|
|
956
956
|
/// ---
|
|
957
|
-
pub(
|
|
957
|
+
pub(crate) fn lifecycle_worker_tmux_backend_selection_for_state(
|
|
958
958
|
run_workspace: &Path,
|
|
959
959
|
state: &serde_json::Value,
|
|
960
960
|
) -> Result<crate::tmux_backend::RuntimeTmuxBackendSelection, LifecycleError> {
|
|
@@ -1344,6 +1344,119 @@ pub(crate) fn session_identity_probe_for_agent(
|
|
|
1344
1344
|
}
|
|
1345
1345
|
}
|
|
1346
1346
|
|
|
1347
|
+
/// ---
|
|
1348
|
+
/// purpose: 将合法 Pi fork 血统纳入共享会话身份判定
|
|
1349
|
+
/// params:
|
|
1350
|
+
/// workspace/state/agent: 当前被验证席位及同队来源记录
|
|
1351
|
+
/// rollout_path: 当前席位的精确 backing
|
|
1352
|
+
/// returns: 字面身份一致,或经独立 Pi backing 与 fork 血统验证后合法继承时为 true
|
|
1353
|
+
/// ---
|
|
1354
|
+
pub(crate) fn session_identity_probe_for_agent_with_fork_ancestry(
|
|
1355
|
+
workspace: &Path,
|
|
1356
|
+
state: &serde_json::Value,
|
|
1357
|
+
agent_id: &AgentId,
|
|
1358
|
+
agent: &serde_json::Value,
|
|
1359
|
+
provider: Provider,
|
|
1360
|
+
rollout_path: Option<&RolloutPath>,
|
|
1361
|
+
) -> SessionIdentityProbeResult {
|
|
1362
|
+
let mut probe = session_identity_probe_for_agent(agent_id, provider, rollout_path);
|
|
1363
|
+
if probe.identity_ok != Some(false)
|
|
1364
|
+
|| !pi_fork_ancestor_identity_is_valid(
|
|
1365
|
+
workspace,
|
|
1366
|
+
state,
|
|
1367
|
+
agent_id,
|
|
1368
|
+
agent,
|
|
1369
|
+
provider,
|
|
1370
|
+
rollout_path,
|
|
1371
|
+
probe.embedded_agent_id.as_deref(),
|
|
1372
|
+
)
|
|
1373
|
+
{
|
|
1374
|
+
return probe;
|
|
1375
|
+
}
|
|
1376
|
+
probe.identity_ok = Some(true);
|
|
1377
|
+
probe
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
fn pi_fork_ancestor_identity_is_valid(
|
|
1381
|
+
workspace: &Path,
|
|
1382
|
+
state: &serde_json::Value,
|
|
1383
|
+
agent_id: &AgentId,
|
|
1384
|
+
agent: &serde_json::Value,
|
|
1385
|
+
provider: Provider,
|
|
1386
|
+
rollout_path: Option<&RolloutPath>,
|
|
1387
|
+
embedded_agent_id: Option<&str>,
|
|
1388
|
+
) -> bool {
|
|
1389
|
+
if provider != Provider::Pi
|
|
1390
|
+
|| agent.get("attribution_ambiguous").and_then(serde_json::Value::as_bool) == Some(true)
|
|
1391
|
+
|| agent.get("capture_state").and_then(serde_json::Value::as_str)
|
|
1392
|
+
== Some("attribution_ambiguous")
|
|
1393
|
+
|| !matches!(
|
|
1394
|
+
agent
|
|
1395
|
+
.get("attribution_confidence")
|
|
1396
|
+
.and_then(serde_json::Value::as_str),
|
|
1397
|
+
Some("high" | "medium")
|
|
1398
|
+
)
|
|
1399
|
+
{
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1402
|
+
let (Some(embedded_agent_id), Some(forked_from), Some(target_path)) = (
|
|
1403
|
+
embedded_agent_id,
|
|
1404
|
+
agent
|
|
1405
|
+
.get("forked_from")
|
|
1406
|
+
.and_then(serde_json::Value::as_str)
|
|
1407
|
+
.filter(|value| !value.is_empty()),
|
|
1408
|
+
rollout_path.map(RolloutPath::as_path),
|
|
1409
|
+
) else {
|
|
1410
|
+
return false;
|
|
1411
|
+
};
|
|
1412
|
+
if forked_from != embedded_agent_id || forked_from == agent_id.as_str() {
|
|
1413
|
+
return false;
|
|
1414
|
+
}
|
|
1415
|
+
let Some(source_agent) = state
|
|
1416
|
+
.get("agents")
|
|
1417
|
+
.and_then(|agents| agents.get(forked_from))
|
|
1418
|
+
.filter(|source| agent_provider(source) == Provider::Pi)
|
|
1419
|
+
else {
|
|
1420
|
+
return false;
|
|
1421
|
+
};
|
|
1422
|
+
let Some(source_path) = agent_rollout_path(source_agent) else {
|
|
1423
|
+
return false;
|
|
1424
|
+
};
|
|
1425
|
+
if source_path.as_path() == target_path {
|
|
1426
|
+
return false;
|
|
1427
|
+
}
|
|
1428
|
+
let (Some(session_id), Ok(target_path), Some(target_root)) = (
|
|
1429
|
+
agent_session_id(agent),
|
|
1430
|
+
std::fs::canonicalize(target_path),
|
|
1431
|
+
agent
|
|
1432
|
+
.get("claude_projects_root")
|
|
1433
|
+
.and_then(serde_json::Value::as_str)
|
|
1434
|
+
.filter(|path| !path.is_empty())
|
|
1435
|
+
.map(std::path::PathBuf::from),
|
|
1436
|
+
) else {
|
|
1437
|
+
return false;
|
|
1438
|
+
};
|
|
1439
|
+
let Ok(target_root) = std::fs::canonicalize(target_root) else {
|
|
1440
|
+
return false;
|
|
1441
|
+
};
|
|
1442
|
+
if !target_path.starts_with(target_root)
|
|
1443
|
+
|| std::fs::canonicalize(source_path.as_path())
|
|
1444
|
+
.is_ok_and(|source_path| source_path == target_path)
|
|
1445
|
+
|| !resume_backing_probe_for_agent(
|
|
1446
|
+
workspace,
|
|
1447
|
+
agent_id,
|
|
1448
|
+
agent,
|
|
1449
|
+
provider,
|
|
1450
|
+
&session_id,
|
|
1451
|
+
rollout_path,
|
|
1452
|
+
)
|
|
1453
|
+
.exists
|
|
1454
|
+
{
|
|
1455
|
+
return false;
|
|
1456
|
+
}
|
|
1457
|
+
true
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1347
1460
|
/// ---
|
|
1348
1461
|
/// purpose: 按 provider 分支探测 resume 依据,并记录所有查过的路径
|
|
1349
1462
|
/// returns: 存在位与查过的路径列表;持久化的 rollout 路径即使不存在也记进列表
|
|
@@ -1133,8 +1133,11 @@ fn restart_with_selected_team_and_transport(
|
|
|
1133
1133
|
&session_id,
|
|
1134
1134
|
agent_rollout_path(&agent).as_ref(),
|
|
1135
1135
|
);
|
|
1136
|
-
let identity_probe =
|
|
1136
|
+
let identity_probe = session_identity_probe_for_agent_with_fork_ancestry(
|
|
1137
|
+
&selected.run_workspace,
|
|
1138
|
+
&state,
|
|
1137
1139
|
&decision.agent_id,
|
|
1140
|
+
&agent,
|
|
1138
1141
|
provider,
|
|
1139
1142
|
agent_rollout_path(&agent).as_ref(),
|
|
1140
1143
|
);
|
|
@@ -1221,8 +1224,11 @@ fn restart_with_selected_team_and_transport(
|
|
|
1221
1224
|
&session_id,
|
|
1222
1225
|
agent_rollout_path(&agent_after).as_ref(),
|
|
1223
1226
|
);
|
|
1224
|
-
let identity_probe_after =
|
|
1227
|
+
let identity_probe_after = session_identity_probe_for_agent_with_fork_ancestry(
|
|
1228
|
+
&selected.run_workspace,
|
|
1229
|
+
&state,
|
|
1225
1230
|
&decision.agent_id,
|
|
1231
|
+
&agent_after,
|
|
1226
1232
|
provider,
|
|
1227
1233
|
agent_rollout_path(&agent_after).as_ref(),
|
|
1228
1234
|
);
|
|
@@ -349,8 +349,20 @@ pub(crate) fn classify_restart_plan_with_resume_validation(
|
|
|
349
349
|
}
|
|
350
350
|
_ => (true, Vec::new()),
|
|
351
351
|
};
|
|
352
|
-
let identity_probe =
|
|
353
|
-
|
|
352
|
+
let identity_probe = workspace
|
|
353
|
+
.map(|workspace| {
|
|
354
|
+
session_identity_probe_for_agent_with_fork_ancestry(
|
|
355
|
+
workspace,
|
|
356
|
+
state,
|
|
357
|
+
&agent_id,
|
|
358
|
+
agent,
|
|
359
|
+
provider,
|
|
360
|
+
rollout_path.as_ref(),
|
|
361
|
+
)
|
|
362
|
+
})
|
|
363
|
+
.unwrap_or_else(|| {
|
|
364
|
+
session_identity_probe_for_agent(&agent_id, provider, rollout_path.as_ref())
|
|
365
|
+
});
|
|
354
366
|
let session_identity_mismatch = session_id.is_some()
|
|
355
367
|
&& provider_can_resume
|
|
356
368
|
&& resume_backing_exists
|
|
@@ -66,6 +66,8 @@ struct LifecyclePathRefs<'a> {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
mod agent;
|
|
69
|
+
mod avatar;
|
|
70
|
+
pub(crate) use avatar::fork_pi_new_seat_locked;
|
|
69
71
|
mod common;
|
|
70
72
|
mod orchestrator;
|
|
71
73
|
pub mod preflight;
|
|
@@ -82,11 +84,16 @@ pub(crate) use agent::{
|
|
|
82
84
|
};
|
|
83
85
|
pub(crate) use common::refresh_missing_provider_sessions;
|
|
84
86
|
pub(crate) use common::restart_required_missing_session_agent_ids;
|
|
85
|
-
pub(crate) use common::
|
|
87
|
+
pub(crate) use common::{
|
|
88
|
+
session_identity_probe_for_agent, session_identity_probe_for_agent_with_fork_ancestry,
|
|
89
|
+
};
|
|
86
90
|
// 0.3.24 add-agent socket drift fix: state-aware tmux resolver shared with
|
|
87
91
|
// `lifecycle::launch::add_agent` / `fork_agent` so all three (restart / add / fork)
|
|
88
92
|
// route to the SAME tmux socket the live team uses.
|
|
89
|
-
pub(crate) use common::
|
|
93
|
+
pub(crate) use common::{
|
|
94
|
+
lifecycle_worker_tmux_backend_for_selected_state,
|
|
95
|
+
lifecycle_worker_tmux_backend_selection_for_state,
|
|
96
|
+
};
|
|
90
97
|
pub(crate) use orchestrator::{halt_plan, plan_status};
|
|
91
98
|
pub(crate) use rebuild::restart_with_transport_with_session_convergence_deadline;
|
|
92
99
|
// 0.5.38 (`.team/artifacts/startup-latency-locate.md` §5): expose the phase
|
|
@@ -100,10 +107,10 @@ pub(crate) use rebuild::{
|
|
|
100
107
|
restart_candidates, restart_with_transport, restart_with_transport_with_readiness_deadline,
|
|
101
108
|
select_restart_state,
|
|
102
109
|
};
|
|
103
|
-
pub use remove::{remove_agent, remove_agent_flag_requirements};
|
|
104
110
|
pub(crate) use remove::remove_agent_with_transport;
|
|
105
|
-
pub
|
|
111
|
+
pub use remove::{remove_agent, remove_agent_flag_requirements};
|
|
106
112
|
pub use selection::decide_start_mode;
|
|
113
|
+
pub(crate) use selection::{classify_first_send_at, classify_restart_plan, python_type_name};
|
|
107
114
|
// Layer 2 (leader follow-up 2026-06-22): test-visible workspace-aware
|
|
108
115
|
// classification so lifecycle/tests/restart.rs can exercise the
|
|
109
116
|
// SessionBackingStoreMissing + checked_paths + RecoveryHint path
|