@team-agent/installer 0.5.65 → 0.5.68
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 +8 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/Cargo.toml +6 -0
- package/crates/team-agent/src/cli/adapters.rs +6 -1
- package/crates/team-agent/src/cli/diagnose.rs +82 -0
- package/crates/team-agent/src/cli/emit.rs +3 -3
- package/crates/team-agent/src/cli/grok_slot.rs +299 -0
- package/crates/team-agent/src/cli/leader.rs +21 -7
- package/crates/team-agent/src/cli/leaders.rs +125 -1
- package/crates/team-agent/src/cli/mod.rs +20 -0
- package/crates/team-agent/src/cli/send/presentation.rs +7 -1
- package/crates/team-agent/src/cli/spec.rs +2 -0
- package/crates/team-agent/src/cli/status_port/compact.rs +28 -0
- package/crates/team-agent/src/cli/status_port/snapshot.rs +25 -1
- package/crates/team-agent/src/cli/tests/base.rs +26 -3
- package/crates/team-agent/src/cli/tests/compile.rs +1 -1
- package/crates/team-agent/src/cli/tests/missing_subcommands.rs +129 -19
- package/crates/team-agent/src/cli/tests/mod.rs +2 -2
- package/crates/team-agent/src/cli/tests/run_delegation.rs +1 -1
- package/crates/team-agent/src/cli/tests/shutdown_kill_plan.rs +387 -6
- package/crates/team-agent/src/cli/tests/status_send.rs +79 -10
- package/crates/team-agent/src/cli/tests/verb_validate.rs +1 -1
- package/crates/team-agent/src/communication_mode/mod.rs +6 -4
- package/crates/team-agent/src/compiler/tests.rs +23 -20
- package/crates/team-agent/src/compiler.rs +84 -5
- package/crates/team-agent/src/conpty/backend.rs +16 -0
- package/crates/team-agent/src/coordinator/backoff.rs +55 -0
- package/crates/team-agent/src/coordinator/conpty_shim.rs +82 -0
- package/crates/team-agent/src/coordinator/health.rs +173 -0
- package/crates/team-agent/src/coordinator/mod.rs +31 -0
- package/crates/team-agent/src/coordinator/orphan.rs +31 -0
- package/crates/team-agent/src/coordinator/runtime_detectors.rs +30 -0
- package/crates/team-agent/src/coordinator/runtime_observation.rs +25 -0
- package/crates/team-agent/src/coordinator/steps/abnormal.rs +59 -0
- package/crates/team-agent/src/coordinator/steps/delivery.rs +10 -0
- package/crates/team-agent/src/coordinator/steps/health_sync.rs +10 -0
- package/crates/team-agent/src/coordinator/steps/mod.rs +22 -0
- package/crates/team-agent/src/coordinator/steps/persist.rs +10 -0
- package/crates/team-agent/src/coordinator/steps/runtime_prompts.rs +10 -0
- package/crates/team-agent/src/coordinator/steps/session_gate.rs +10 -0
- package/crates/team-agent/src/coordinator/tick.rs +133 -22
- package/crates/team-agent/src/coordinator/types.rs +49 -0
- package/crates/team-agent/src/db/message_store.rs +39 -5
- package/crates/team-agent/src/layout/worker_env.rs +20 -3
- package/crates/team-agent/src/layout/worker_window_helpers.rs +2 -0
- package/crates/team-agent/src/leader/provider_attribution.rs +53 -0
- package/crates/team-agent/src/leader/registry.rs +65 -0
- package/crates/team-agent/src/leader/start.rs +1080 -58
- package/crates/team-agent/src/leader/tests/team_in_team_state_scope_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/display.rs +56 -0
- package/crates/team-agent/src/lifecycle/helpers.rs +57 -0
- package/crates/team-agent/src/lifecycle/launch/add_agent.rs +332 -14
- package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +69 -2
- package/crates/team-agent/src/lifecycle/launch/agent_state.rs +196 -2
- package/crates/team-agent/src/lifecycle/launch/clone_agent.rs +101 -11
- package/crates/team-agent/src/lifecycle/launch/cursor_create_chat.rs +229 -0
- package/crates/team-agent/src/lifecycle/launch/cursor_mcp.rs +332 -0
- package/crates/team-agent/src/lifecycle/launch/fork_agent.rs +204 -457
- package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +24 -0
- package/crates/team-agent/src/lifecycle/launch/grok_per_seat.rs +260 -0
- package/crates/team-agent/src/lifecycle/launch/identity.rs +146 -0
- package/crates/team-agent/src/lifecycle/launch/layout.rs +60 -0
- package/crates/team-agent/src/lifecycle/launch/leader_context.rs +112 -0
- package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +530 -0
- package/crates/team-agent/src/lifecycle/launch/ownership.rs +40 -0
- package/crates/team-agent/src/lifecycle/launch/plan.rs +31 -0
- package/crates/team-agent/src/lifecycle/launch/quick_start.rs +66 -0
- package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +78 -0
- package/crates/team-agent/src/lifecycle/launch/readiness.rs +85 -38
- package/crates/team-agent/src/lifecycle/launch/role_source.rs +44 -44
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +101 -4
- package/crates/team-agent/src/lifecycle/launch/spec_state.rs +244 -48
- package/crates/team-agent/src/lifecycle/launch/state_projection.rs +109 -2
- package/crates/team-agent/src/lifecycle/launch/worker_env.rs +214 -1
- package/crates/team-agent/src/lifecycle/launch.rs +209 -43
- package/crates/team-agent/src/lifecycle/lock.rs +42 -1
- package/crates/team-agent/src/lifecycle/mod.rs +11 -0
- package/crates/team-agent/src/lifecycle/pane_input_lock.rs +161 -0
- package/crates/team-agent/src/lifecycle/profile_launch.rs +98 -0
- package/crates/team-agent/src/lifecycle/profile_smoke.rs +51 -1
- package/crates/team-agent/src/lifecycle/restart/agent.rs +213 -3
- package/crates/team-agent/src/lifecycle/restart/common.rs +373 -18
- package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +27 -0
- package/crates/team-agent/src/lifecycle/restart/preflight.rs +25 -0
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +165 -15
- package/crates/team-agent/src/lifecycle/restart/remove.rs +196 -5
- package/crates/team-agent/src/lifecycle/restart/selection.rs +72 -0
- package/crates/team-agent/src/lifecycle/restart/team_state.rs +22 -0
- package/crates/team-agent/src/lifecycle/restart.rs +29 -0
- package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +3 -4
- package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +4 -4
- package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +309 -0
- package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +159 -174
- package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +15 -13
- package/crates/team-agent/src/lifecycle/tests/core.rs +4 -18
- package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/cursor_mcp_overlay.rs +287 -0
- package/crates/team-agent/src/lifecycle/tests/cursor_require_explicit_model_red.rs +229 -0
- package/crates/team-agent/src/lifecycle/tests/cursor_restart_resume_red.rs +353 -0
- package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/f032_startup_prompt_best_effort_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/g1_silent_faces.rs +784 -0
- package/crates/team-agent/src/lifecycle/tests/gate_fixtures.rs +562 -0
- package/crates/team-agent/src/lifecycle/tests/grok_effort_argv_red.rs +239 -0
- package/crates/team-agent/src/lifecycle/tests/grok_mcp_overlay_red.rs +498 -0
- package/crates/team-agent/src/lifecycle/tests/grok_require_explicit_model_red.rs +250 -0
- package/crates/team-agent/src/lifecycle/tests/grok_restart_resume_red.rs +293 -0
- package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +3 -0
- package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +3 -3
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +65 -40
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +20 -32
- package/crates/team-agent/src/lifecycle/tests/lifecycle_rollback_red.rs +17 -9
- package/crates/team-agent/src/lifecycle/tests/mcp_tool_name_format_red.rs +69 -0
- package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +24 -23
- package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +98 -62
- package/crates/team-agent/src/lifecycle/tests/quick_start_worker_readiness_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/restart_liveness_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +3 -1
- package/crates/team-agent/src/lifecycle/tests/restart_session_capture_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/resume_recover_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/stale_team_saveconflict_contract.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +41 -8
- package/crates/team-agent/src/lifecycle/tests/status_credential_redaction_contract.rs +3 -3
- package/crates/team-agent/src/lifecycle/tests/subprep_codex_trust_roundtrip_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/swallow_batch4_semantics_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_in_team_sibling_quick_start_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_in_team_state_scope_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_key_retirement_txn_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +60 -2
- package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +69 -26
- package/crates/team-agent/src/lifecycle/tests.rs +23 -15
- package/crates/team-agent/src/lifecycle/types.rs +61 -2
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +200 -33
- package/crates/team-agent/src/mcp_server/tests/scoped.rs +100 -1
- package/crates/team-agent/src/mcp_server/tests.rs +196 -2
- package/crates/team-agent/src/messaging/delivery.rs +405 -40
- package/crates/team-agent/src/messaging/helpers.rs +2 -0
- package/crates/team-agent/src/messaging/leader_receiver.rs +53 -1
- package/crates/team-agent/src/messaging/results.rs +4 -0
- package/crates/team-agent/src/messaging/send.rs +34 -0
- package/crates/team-agent/src/messaging/tests/dup_inject.rs +406 -0
- package/crates/team-agent/src/messaging/tests/e23.rs +9 -0
- package/crates/team-agent/src/messaging/tests/leader_inject_acceptance.rs +66 -0
- package/crates/team-agent/src/messaging/tests/main_preserved.rs +1 -1
- package/crates/team-agent/src/messaging/tests/mod.rs +1 -0
- package/crates/team-agent/src/messaging/types.rs +4 -1
- package/crates/team-agent/src/model/enums.rs +14 -5
- package/crates/team-agent/src/model/permissions.rs +3 -0
- package/crates/team-agent/src/model/spec.rs +129 -6
- package/crates/team-agent/src/model/testdata/spec_invalid_a.yaml +3 -1
- package/crates/team-agent/src/model/testdata/team.spec.golden.yaml +3 -1
- package/crates/team-agent/src/model/testdata/team.spec.yaml +3 -1
- package/crates/team-agent/src/os_probe.rs +73 -2
- package/crates/team-agent/src/provider/adapter.rs +231 -4
- package/crates/team-agent/src/provider/adapters/claude.rs +5 -2
- package/crates/team-agent/src/provider/adapters/codex.rs +5 -2
- package/crates/team-agent/src/provider/adapters/copilot.rs +5 -2
- package/crates/team-agent/src/provider/adapters/cursor_agent.rs +86 -0
- package/crates/team-agent/src/provider/adapters/grok.rs +157 -0
- package/crates/team-agent/src/provider/adapters/mod.rs +2 -0
- package/crates/team-agent/src/provider/bypass_flags.rs +124 -0
- package/crates/team-agent/src/provider/classify.rs +4 -2
- package/crates/team-agent/src/provider/faults.rs +2 -1
- package/crates/team-agent/src/provider/mod.rs +13 -0
- package/crates/team-agent/src/provider/session/capture.rs +158 -20
- package/crates/team-agent/src/provider/session/context_fork/claude.rs +38 -1
- package/crates/team-agent/src/provider/session/context_fork/codex.rs +72 -1
- package/crates/team-agent/src/provider/session/context_fork/outcome.rs +57 -1
- package/crates/team-agent/src/provider/session/context_fork.rs +77 -3
- package/crates/team-agent/src/provider/session/mod.rs +18 -0
- package/crates/team-agent/src/provider/session/resume.rs +57 -0
- package/crates/team-agent/src/provider/session_scan/claude.rs +125 -1
- package/crates/team-agent/src/provider/session_scan/codex.rs +94 -1
- package/crates/team-agent/src/provider/session_scan/common.rs +204 -2
- package/crates/team-agent/src/provider/session_scan/copilot.rs +33 -1
- package/crates/team-agent/src/provider/session_scan/cursor.rs +538 -0
- package/crates/team-agent/src/provider/session_scan/grok.rs +288 -0
- package/crates/team-agent/src/provider/session_scan.rs +8 -0
- package/crates/team-agent/src/provider/submit_now.rs +94 -0
- package/crates/team-agent/src/provider/tests/adapter.rs +304 -0
- package/crates/team-agent/src/provider/types.rs +4 -2
- package/crates/team-agent/src/provider/wire.rs +23 -1
- package/crates/team-agent/src/state/persist.rs +301 -8
- package/crates/team-agent/src/state/repository.rs +5 -0
- package/crates/team-agent/src/tmux_backend/tests.rs +1737 -42
- package/crates/team-agent/src/tmux_backend.rs +1083 -75
- package/crates/team-agent/src/transport/test_support.rs +20 -0
- package/crates/team-agent/src/transport/tests/wire.rs +28 -2
- package/crates/team-agent/src/transport.rs +265 -1
- package/npm/install.mjs +129 -73
- package/package.json +4 -4
- package/skills/team-agent/SKILL.md +33 -238
- package/skills/team-agent/command-coverage.json +31 -0
- package/crates/team-agent/src/lifecycle/launch/approval.rs +0 -134
- package/crates/team-agent/src/lifecycle/launch/fork_agent/completion.rs +0 -59
- package/crates/team-agent/src/lifecycle/launch/fork_finalize.rs +0 -483
- package/crates/team-agent/src/lifecycle/launch/fork_pending.rs +0 -109
- package/crates/team-agent/src/lifecycle/launch/fork_state.rs +0 -447
- package/crates/team-agent/src/lifecycle/tests/codex_mcp_approval_inheritance_red.rs +0 -1187
- package/crates/team-agent/src/lifecycle/tests/worker_dangerous_bypass_argv_red.rs +0 -327
|
@@ -1,7 +1,29 @@
|
|
|
1
|
+
//! ---
|
|
2
|
+
//! purpose: plan 的停止与状态读取
|
|
3
|
+
//! contract:
|
|
4
|
+
//! provides:
|
|
5
|
+
//! - name: halt_plan
|
|
6
|
+
//! what: 读出 plan 状态并返回 Halted 结论
|
|
7
|
+
//! - name: plan_status
|
|
8
|
+
//! what: 读出 plan 的持久化状态
|
|
9
|
+
//! depends:
|
|
10
|
+
//! - crate::lifecycle::helpers
|
|
11
|
+
//! boundary:
|
|
12
|
+
//! - 只读状态文件,本文件不改写 plan 状态
|
|
13
|
+
//! - 不向席位投递任何消息
|
|
14
|
+
//! maturity: wired
|
|
15
|
+
//! ---
|
|
1
16
|
use super::*;
|
|
2
17
|
|
|
3
18
|
// ── lifecycle::orchestrator —— plan 多 stage 状态机(halt / status)──────────
|
|
4
19
|
|
|
20
|
+
/// ---
|
|
21
|
+
/// purpose: 对指定 plan 返回 Halted 结论
|
|
22
|
+
/// params:
|
|
23
|
+
/// reason: 当前实现未使用
|
|
24
|
+
/// returns: Halted,理由恒为 already_terminal;注意它不写盘,磁盘上的 status 不变
|
|
25
|
+
/// errors: 状态文件不存在或解析失败时返回 InvalidPlan
|
|
26
|
+
/// ---
|
|
5
27
|
/// `halt_plan(workspace, plan_id, reason)`(`orchestrator/__init__.py:152`)。停 plan;
|
|
6
28
|
/// 非 running → 幂等返回。
|
|
7
29
|
pub(crate) fn halt_plan(
|
|
@@ -25,6 +47,11 @@ pub(crate) fn halt_plan(
|
|
|
25
47
|
})
|
|
26
48
|
}
|
|
27
49
|
|
|
50
|
+
/// ---
|
|
51
|
+
/// purpose: 读出 plan 的持久化状态
|
|
52
|
+
/// returns: 反序列化出的 PlanState
|
|
53
|
+
/// errors: 状态文件不存在或解析失败时返回 InvalidPlan
|
|
54
|
+
/// ---
|
|
28
55
|
/// `plan_status(workspace, plan_id)`(`orchestrator/__init__.py:177`)。读 plan 持久态。
|
|
29
56
|
pub(crate) fn plan_status(workspace: &Path, plan_id: &PlanId) -> Result<PlanState, LifecycleError> {
|
|
30
57
|
let path = plan_state_path(workspace, plan_id);
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
//! ---
|
|
2
|
+
//! purpose: restart 拆除 worker session 之前的身份守卫,防止误杀 leader 会话
|
|
3
|
+
//! contract:
|
|
4
|
+
//! provides:
|
|
5
|
+
//! - name: SessionPreflight
|
|
6
|
+
//! what: 守卫结论,通过或指出 worker session 名其实是 leader 会话名
|
|
7
|
+
//! - name: check_session_preflight
|
|
8
|
+
//! what: 纯函数检查 state 里的 session 名字段
|
|
9
|
+
//! depends:
|
|
10
|
+
//! - crate::layout::RuntimeSessions
|
|
11
|
+
//! boundary:
|
|
12
|
+
//! - 纯计算,不做 IO 也不改 state
|
|
13
|
+
//! - 只判这一种异常,其他 session 异常不在本守卫范围
|
|
14
|
+
//! maturity: wired
|
|
15
|
+
//! ---
|
|
1
16
|
//! unit-3 (Stage 1) — restart preflight session-identity guard.
|
|
2
17
|
//!
|
|
3
18
|
//! Single check that runs BEFORE the worker-session teardown in
|
|
@@ -27,12 +42,22 @@ pub enum SessionPreflight {
|
|
|
27
42
|
}
|
|
28
43
|
|
|
29
44
|
impl SessionPreflight {
|
|
45
|
+
/// ---
|
|
46
|
+
/// purpose: 判断守卫是否放行
|
|
47
|
+
/// returns: 结论为 Ok 时为 true
|
|
48
|
+
/// ---
|
|
30
49
|
/// True when the preflight passed and the caller may proceed.
|
|
31
50
|
pub fn is_ok(&self) -> bool {
|
|
32
51
|
matches!(self, SessionPreflight::Ok)
|
|
33
52
|
}
|
|
34
53
|
}
|
|
35
54
|
|
|
55
|
+
/// ---
|
|
56
|
+
/// purpose: 检查 state 里的 session 名,决定接下来的 worker session 拆除是否安全
|
|
57
|
+
/// params:
|
|
58
|
+
/// state: runtime state
|
|
59
|
+
/// returns: 发现 worker session 名带 leader 前缀时返回拒绝结论并附名字与原因,否则 Ok
|
|
60
|
+
/// ---
|
|
36
61
|
/// Inspect `state.json` and decide whether the upcoming worker-session
|
|
37
62
|
/// kill is safe. Pure: no I/O, no mutation.
|
|
38
63
|
pub fn check_session_preflight(state: &serde_json::Value) -> SessionPreflight {
|
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
//! ---
|
|
2
|
+
//! purpose: 整队重建,先算 resume 计划与拒绝结论,再做破坏性拆除与重起
|
|
3
|
+
//! contract:
|
|
4
|
+
//! provides:
|
|
5
|
+
//! - name: restart
|
|
6
|
+
//! what: 整队重建入口,解析 team 与它实际使用的 transport 后执行
|
|
7
|
+
//! - name: restart_with_transport_with_session_convergence_deadline
|
|
8
|
+
//! what: 重建的实体实现,含入口门、spec 重建、计划分类、四种拒绝与重起
|
|
9
|
+
//! - name: RestartPhaseTimer
|
|
10
|
+
//! what: 阶段计时器,把 restart 与 launch 的分段耗时写成事件
|
|
11
|
+
//! - name: restart_candidates
|
|
12
|
+
//! what: 列出本 workspace 可重启的团队
|
|
13
|
+
//! - name: select_restart_state
|
|
14
|
+
//! what: 按 team 参数或唯一性选出重启目标
|
|
15
|
+
//! depends:
|
|
16
|
+
//! - crate::lifecycle::lock
|
|
17
|
+
//! - crate::lifecycle::display
|
|
18
|
+
//! - crate::lifecycle::restart::selection
|
|
19
|
+
//! - crate::lifecycle::restart::preflight
|
|
20
|
+
//! - crate::lifecycle::restart::remove
|
|
21
|
+
//! - crate::state::selector
|
|
22
|
+
//! - crate::state::projection
|
|
23
|
+
//! - crate::state::persist
|
|
24
|
+
//! - crate::event_log::EventLog
|
|
25
|
+
//! boundary:
|
|
26
|
+
//! - 四种拒绝一律先于任何 teardown 产出,拒绝时现场不变
|
|
27
|
+
//! - 每个非 paused 席位必发一条 resume 决策事件
|
|
28
|
+
//! - 只有计划里不含 Resumed 时才并行起席,串行臂的会话消失检测没有并发等价物
|
|
29
|
+
//! maturity: wired
|
|
30
|
+
//! ---
|
|
1
31
|
use super::common::*;
|
|
2
32
|
use super::selection::classify_restart_plan_with_resume_validation;
|
|
3
33
|
use super::*;
|
|
@@ -17,16 +47,31 @@ pub(crate) struct RestartPhaseTimer {
|
|
|
17
47
|
}
|
|
18
48
|
|
|
19
49
|
impl RestartPhaseTimer {
|
|
50
|
+
/// ---
|
|
51
|
+
/// purpose: 起一个阶段计时器
|
|
52
|
+
/// returns: 以当前单调时钟为起点的计时器
|
|
53
|
+
/// ---
|
|
20
54
|
pub(crate) fn start() -> Self {
|
|
21
55
|
Self {
|
|
22
56
|
started_at: std::time::Instant::now(),
|
|
23
57
|
}
|
|
24
58
|
}
|
|
25
59
|
|
|
60
|
+
/// ---
|
|
61
|
+
/// purpose: 取从起点到现在的毫秒数
|
|
62
|
+
/// returns: 毫秒数,溢出时取上限值
|
|
63
|
+
/// ---
|
|
26
64
|
pub(crate) fn elapsed_ms(&self) -> u64 {
|
|
27
65
|
u64::try_from(self.started_at.elapsed().as_millis()).unwrap_or(u64::MAX)
|
|
28
66
|
}
|
|
29
67
|
|
|
68
|
+
/// ---
|
|
69
|
+
/// purpose: 写一条带阶段名与已用毫秒数的事件
|
|
70
|
+
/// params:
|
|
71
|
+
/// kind: 事件名,restart.phase 或 launch.phase
|
|
72
|
+
/// phase: 阶段名
|
|
73
|
+
/// returns: 写事件失败被吞掉,不影响主流程
|
|
74
|
+
/// ---
|
|
30
75
|
pub(crate) fn emit(&self, workspace: &Path, kind: &'static str, phase: &'static str) {
|
|
31
76
|
let event_log = crate::event_log::EventLog::new(workspace);
|
|
32
77
|
let _ = event_log.write(
|
|
@@ -41,6 +86,15 @@ impl RestartPhaseTimer {
|
|
|
41
86
|
|
|
42
87
|
// ── lifecycle::restart —— 整队 Route B resume-or-fresh 重建 ──────────────────
|
|
43
88
|
|
|
89
|
+
/// ---
|
|
90
|
+
/// purpose: 整队重建的对外入口
|
|
91
|
+
/// params:
|
|
92
|
+
/// allow_fresh: 允许把不可 resume 的席位改跑全新会话
|
|
93
|
+
/// team: 指定团队,None 时按唯一性选
|
|
94
|
+
/// returns: 重建报告,含成功与失败席位,或四种拒绝之一
|
|
95
|
+
/// errors: 选不到 team 返回 TeamSelect,路径归一失败返回 StatePersist
|
|
96
|
+
/// contract_id: lifecycle.rebuild.restart_entry
|
|
97
|
+
/// ---
|
|
44
98
|
/// `restart(workspace, allow_fresh, team)`(`restart/orchestration.py:26`)。整队重建:
|
|
45
99
|
/// **先**算 resume 决策(Route B)+ `first_send_at` 严格校验(corrupt → hard refuse),
|
|
46
100
|
/// **再**做破坏性 teardown(关显示、建 session)、起后 leader rebind、adaptive 显示重建。
|
|
@@ -53,6 +107,14 @@ pub fn restart(
|
|
|
53
107
|
restart_with_session_convergence_deadline(workspace, allow_fresh, team, None)
|
|
54
108
|
}
|
|
55
109
|
|
|
110
|
+
/// ---
|
|
111
|
+
/// purpose: 带会话收敛等待上限的整队重建入口
|
|
112
|
+
/// params:
|
|
113
|
+
/// session_converge_deadline_ms: 等待会话收敛的上限,None 用默认
|
|
114
|
+
/// returns: 重建报告
|
|
115
|
+
/// errors: 同 restart
|
|
116
|
+
/// contract_id: lifecycle.rebuild.restart_entry
|
|
117
|
+
/// ---
|
|
56
118
|
pub fn restart_with_session_convergence_deadline(
|
|
57
119
|
workspace: &Path,
|
|
58
120
|
allow_fresh: bool,
|
|
@@ -106,6 +168,12 @@ fn resolve_restart_context(
|
|
|
106
168
|
})
|
|
107
169
|
}
|
|
108
170
|
|
|
171
|
+
/// ---
|
|
172
|
+
/// purpose: 带注入 transport 的整队重建入口
|
|
173
|
+
/// returns: 重建报告
|
|
174
|
+
/// errors: 透传实体实现的错误
|
|
175
|
+
/// contract_id: lifecycle.rebuild.restart_entry
|
|
176
|
+
/// ---
|
|
109
177
|
/// `restart` with an injected transport (tests: recording mock; prod: real TmuxBackend). The Route-B
|
|
110
178
|
/// resume/fresh worker spawn + start_coordinator are wired here over `transport`. (rt-host-a sweep:
|
|
111
179
|
/// was a stub returning RequirementUnmet at the spawn boundary — never spawned/resumed/started coordinator.)
|
|
@@ -118,6 +186,13 @@ pub(crate) fn restart_with_transport(
|
|
|
118
186
|
restart_with_transport_with_readiness_deadline(workspace, allow_fresh, team, transport, None)
|
|
119
187
|
}
|
|
120
188
|
|
|
189
|
+
/// ---
|
|
190
|
+
/// purpose: 带就绪等待上限的重建入口
|
|
191
|
+
/// params:
|
|
192
|
+
/// readiness_deadline_ms: 等待就绪的上限
|
|
193
|
+
/// returns: 重建报告;注意本入口把 RefusedResumeNotReady 重映射成 RefusedResumeAtomicity 并把原因记为会话捕获未收敛,两种拒绝在此入口不可分辨
|
|
194
|
+
/// errors: 透传实体实现的错误
|
|
195
|
+
/// ---
|
|
121
196
|
pub(crate) fn restart_with_transport_with_readiness_deadline(
|
|
122
197
|
workspace: &Path,
|
|
123
198
|
allow_fresh: bool,
|
|
@@ -158,6 +233,14 @@ pub(crate) fn restart_with_transport_with_readiness_deadline(
|
|
|
158
233
|
}
|
|
159
234
|
}
|
|
160
235
|
|
|
236
|
+
/// ---
|
|
237
|
+
/// purpose: 整队重建的实体实现
|
|
238
|
+
/// params:
|
|
239
|
+
/// session_converge_deadline_ms: 会话收敛等待上限
|
|
240
|
+
/// readiness_deadline_ms: 就绪等待上限
|
|
241
|
+
/// returns: 重建报告,或计划分类给出的拒绝结论
|
|
242
|
+
/// errors: 归一路径失败返回 StatePersist;无本地 team 上下文或 spec 缺失返回 TeamSelect
|
|
243
|
+
/// ---
|
|
161
244
|
pub(crate) fn restart_with_transport_with_session_convergence_deadline(
|
|
162
245
|
workspace: &Path,
|
|
163
246
|
allow_fresh: bool,
|
|
@@ -270,7 +353,6 @@ fn restart_with_selected_team_and_transport(
|
|
|
270
353
|
let spec_workspace = runtime_spec.parent().ok_or_else(|| {
|
|
271
354
|
LifecycleError::TeamSelect("active team spec workspace not found".to_string())
|
|
272
355
|
})?;
|
|
273
|
-
let safety = crate::lifecycle::launch::effective_runtime_config(&spec)?;
|
|
274
356
|
// Bug 1 (0.4.2 P0): the rebuilt spec is the single source of truth for the
|
|
275
357
|
// active roster. Any agent in state.agents that is NOT in the rebuilt
|
|
276
358
|
// spec is a stale leftover (role doc was deleted between sessions) and
|
|
@@ -526,7 +608,6 @@ fn restart_with_selected_team_and_transport(
|
|
|
526
608
|
&selected.team_key,
|
|
527
609
|
&session_name,
|
|
528
610
|
transport,
|
|
529
|
-
&safety,
|
|
530
611
|
tmux_endpoint_source,
|
|
531
612
|
&state,
|
|
532
613
|
)
|
|
@@ -551,12 +632,25 @@ fn restart_with_selected_team_and_transport(
|
|
|
551
632
|
if let Some(parallel_result) = parallel_result {
|
|
552
633
|
match parallel_result {
|
|
553
634
|
Ok(pspawn) => {
|
|
635
|
+
let raw_agent = state
|
|
636
|
+
.get("agents")
|
|
637
|
+
.and_then(|v| v.get(decision.agent_id.as_str()))
|
|
638
|
+
.cloned()
|
|
639
|
+
.unwrap_or(serde_json::Value::Null);
|
|
640
|
+
let rehydrated = rehydrate_agent_command_context_from_spec(
|
|
641
|
+
spec_workspace,
|
|
642
|
+
&decision.agent_id,
|
|
643
|
+
&raw_agent,
|
|
644
|
+
);
|
|
645
|
+
let launched_bypass = matches!(
|
|
646
|
+
rehydrated.get("dangerously_skip_permissions"),
|
|
647
|
+
Some(serde_json::Value::Bool(true))
|
|
648
|
+
);
|
|
554
649
|
apply_marked_respawn(
|
|
555
650
|
&selected.run_workspace,
|
|
556
651
|
&selected.team_key,
|
|
557
652
|
&mut state,
|
|
558
653
|
transport,
|
|
559
|
-
&safety,
|
|
560
654
|
&phase_timer,
|
|
561
655
|
decision,
|
|
562
656
|
&pspawn.spawn,
|
|
@@ -565,6 +659,7 @@ fn restart_with_selected_team_and_transport(
|
|
|
565
659
|
&mut successful_agents,
|
|
566
660
|
&mut failed_agents,
|
|
567
661
|
&mut fatal_resume_failure,
|
|
662
|
+
launched_bypass,
|
|
568
663
|
);
|
|
569
664
|
}
|
|
570
665
|
Err(error) => {
|
|
@@ -709,7 +804,7 @@ fn restart_with_selected_team_and_transport(
|
|
|
709
804
|
session_id,
|
|
710
805
|
session_live,
|
|
711
806
|
transport,
|
|
712
|
-
|
|
807
|
+
None,
|
|
713
808
|
layout_placement.as_ref(),
|
|
714
809
|
None,
|
|
715
810
|
tmux_endpoint_source,
|
|
@@ -737,6 +832,10 @@ fn restart_with_selected_team_and_transport(
|
|
|
737
832
|
}
|
|
738
833
|
};
|
|
739
834
|
let verify_start = std::time::Instant::now();
|
|
835
|
+
let launched_bypass = matches!(
|
|
836
|
+
agent.get("dangerously_skip_permissions"),
|
|
837
|
+
Some(serde_json::Value::Bool(true))
|
|
838
|
+
);
|
|
740
839
|
if let Err(error) = verify_spawned_agent_live(&decision.agent_id, &spawn, transport)
|
|
741
840
|
.and_then(|_| {
|
|
742
841
|
mark_agent_respawned(
|
|
@@ -745,7 +844,7 @@ fn restart_with_selected_team_and_transport(
|
|
|
745
844
|
decision.restart_mode,
|
|
746
845
|
&spawn,
|
|
747
846
|
transport,
|
|
748
|
-
|
|
847
|
+
launched_bypass,
|
|
749
848
|
)
|
|
750
849
|
})
|
|
751
850
|
{
|
|
@@ -787,7 +886,16 @@ fn restart_with_selected_team_and_transport(
|
|
|
787
886
|
.and_then(|agents| agents.get_mut(decision.agent_id.as_str()))
|
|
788
887
|
.and_then(serde_json::Value::as_object_mut)
|
|
789
888
|
{
|
|
790
|
-
|
|
889
|
+
// 0.5.66 bypass 单源:policy 从 agent 行字段派生。
|
|
890
|
+
let agent_provider = agent
|
|
891
|
+
.get("provider")
|
|
892
|
+
.and_then(serde_json::Value::as_str)
|
|
893
|
+
.and_then(crate::provider::wire::parse_canonical_provider)
|
|
894
|
+
.unwrap_or(crate::model::enums::Provider::Codex);
|
|
895
|
+
crate::lifecycle::launch::persist_effective_approval_policy_from_agent(
|
|
896
|
+
agent,
|
|
897
|
+
agent_provider,
|
|
898
|
+
);
|
|
791
899
|
}
|
|
792
900
|
// 0.5.32 (`.team/artifacts/restart-resumed-stale-activity-locate.md` §5):
|
|
793
901
|
// pair the state-side activity clear with a DB `agent_health` clear so
|
|
@@ -1958,7 +2066,7 @@ fn mark_agent_respawned(
|
|
|
1958
2066
|
restart_mode: StartMode,
|
|
1959
2067
|
spawn: &SpawnedAgentWindow,
|
|
1960
2068
|
transport: &dyn crate::transport::Transport,
|
|
1961
|
-
|
|
2069
|
+
launched_bypass: bool,
|
|
1962
2070
|
) -> Result<(), LifecycleError> {
|
|
1963
2071
|
let Some(agent) = state
|
|
1964
2072
|
.get_mut("agents")
|
|
@@ -2081,7 +2189,18 @@ fn mark_agent_respawned(
|
|
|
2081
2189
|
}
|
|
2082
2190
|
}
|
|
2083
2191
|
crate::lifecycle::launch::persist_command_plan_state(agent, &spawn.plan, &spawn.profile_launch);
|
|
2084
|
-
|
|
2192
|
+
// 0.5.66 bypass 单源:policy 从 agent 行字段派生,不再用全队 `DangerousApproval`。
|
|
2193
|
+
let agent_provider = agent
|
|
2194
|
+
.get("provider")
|
|
2195
|
+
.and_then(serde_json::Value::as_str)
|
|
2196
|
+
.and_then(crate::provider::wire::parse_canonical_provider)
|
|
2197
|
+
.unwrap_or(crate::model::enums::Provider::Codex);
|
|
2198
|
+
crate::lifecycle::launch::persist_effective_approval_policy_from_agent(agent, agent_provider);
|
|
2199
|
+
// 0.5.66 bypass 单源 §2.6:fresh spawn(restart)记录运行面 bypass 值。
|
|
2200
|
+
agent.insert(
|
|
2201
|
+
"as_launched_dangerously_skip_permissions".to_string(),
|
|
2202
|
+
serde_json::json!(launched_bypass),
|
|
2203
|
+
);
|
|
2085
2204
|
if let Some(placement) = spawn.layout_placement.as_ref() {
|
|
2086
2205
|
agent.insert(
|
|
2087
2206
|
"layout_window".to_string(),
|
|
@@ -2510,7 +2629,6 @@ fn run_bounded_parallel_worker_spawns(
|
|
|
2510
2629
|
team_key: &str,
|
|
2511
2630
|
session_name: &SessionName,
|
|
2512
2631
|
transport: &(dyn crate::transport::Transport),
|
|
2513
|
-
safety: &DangerousApproval,
|
|
2514
2632
|
tmux_endpoint_source: Option<&str>,
|
|
2515
2633
|
state: &serde_json::Value,
|
|
2516
2634
|
) -> Vec<Option<Result<ParallelSpawnResult, String>>> {
|
|
@@ -2589,7 +2707,7 @@ fn run_bounded_parallel_worker_spawns(
|
|
|
2589
2707
|
first_input.session_id.as_ref(),
|
|
2590
2708
|
first_session_live,
|
|
2591
2709
|
transport,
|
|
2592
|
-
|
|
2710
|
+
None,
|
|
2593
2711
|
first_input.layout_placement.as_ref(),
|
|
2594
2712
|
None,
|
|
2595
2713
|
tmux_endpoint_source,
|
|
@@ -2673,7 +2791,7 @@ fn run_bounded_parallel_worker_spawns(
|
|
|
2673
2791
|
input.session_id.as_ref(),
|
|
2674
2792
|
/* into_existing_session */ true,
|
|
2675
2793
|
transport,
|
|
2676
|
-
|
|
2794
|
+
None,
|
|
2677
2795
|
input.layout_placement.as_ref(),
|
|
2678
2796
|
None,
|
|
2679
2797
|
tmux_endpoint_source,
|
|
@@ -2716,7 +2834,6 @@ fn apply_marked_respawn(
|
|
|
2716
2834
|
team_key: &str,
|
|
2717
2835
|
state: &mut serde_json::Value,
|
|
2718
2836
|
transport: &(dyn crate::transport::Transport),
|
|
2719
|
-
safety: &DangerousApproval,
|
|
2720
2837
|
phase_timer: &RestartPhaseTimer,
|
|
2721
2838
|
decision: &RestartedAgent,
|
|
2722
2839
|
spawn: &SpawnedAgentWindow,
|
|
@@ -2725,6 +2842,7 @@ fn apply_marked_respawn(
|
|
|
2725
2842
|
successful_agents: &mut Vec<RestartedAgent>,
|
|
2726
2843
|
failed_agents: &mut Vec<RestartFailedAgent>,
|
|
2727
2844
|
fatal_resume_failure: &mut bool,
|
|
2845
|
+
launched_bypass: bool,
|
|
2728
2846
|
) {
|
|
2729
2847
|
let verify_start = std::time::Instant::now();
|
|
2730
2848
|
if let Err(error) =
|
|
@@ -2735,7 +2853,7 @@ fn apply_marked_respawn(
|
|
|
2735
2853
|
decision.restart_mode,
|
|
2736
2854
|
spawn,
|
|
2737
2855
|
transport,
|
|
2738
|
-
|
|
2856
|
+
launched_bypass,
|
|
2739
2857
|
)
|
|
2740
2858
|
})
|
|
2741
2859
|
{
|
|
@@ -2776,7 +2894,16 @@ fn apply_marked_respawn(
|
|
|
2776
2894
|
.and_then(|agents| agents.get_mut(decision.agent_id.as_str()))
|
|
2777
2895
|
.and_then(serde_json::Value::as_object_mut)
|
|
2778
2896
|
{
|
|
2779
|
-
|
|
2897
|
+
// 0.5.66 bypass 单源:policy 从 agent 行字段派生。
|
|
2898
|
+
let agent_provider = agent
|
|
2899
|
+
.get("provider")
|
|
2900
|
+
.and_then(serde_json::Value::as_str)
|
|
2901
|
+
.and_then(crate::provider::wire::parse_canonical_provider)
|
|
2902
|
+
.unwrap_or(crate::model::enums::Provider::Codex);
|
|
2903
|
+
crate::lifecycle::launch::persist_effective_approval_policy_from_agent(
|
|
2904
|
+
agent,
|
|
2905
|
+
agent_provider,
|
|
2906
|
+
);
|
|
2780
2907
|
}
|
|
2781
2908
|
let _ = crate::db::agent_health_capture::clear_agent_health_observation(
|
|
2782
2909
|
run_workspace,
|
|
@@ -2785,6 +2912,13 @@ fn apply_marked_respawn(
|
|
|
2785
2912
|
);
|
|
2786
2913
|
}
|
|
2787
2914
|
|
|
2915
|
+
/// ---
|
|
2916
|
+
/// purpose: 写一条 per-worker 的启动分段耗时事件
|
|
2917
|
+
/// params:
|
|
2918
|
+
/// source: 事件来源,launch 或 restart
|
|
2919
|
+
/// command_plan_ms: 命令拼装耗时,调用方给不出真实值时可能是占位 0
|
|
2920
|
+
/// returns: 写事件失败被吞掉
|
|
2921
|
+
/// ---
|
|
2788
2922
|
/// 0.5.38 Step 1 (`.team/artifacts/startup-latency-locate.md` §5): per-worker
|
|
2789
2923
|
/// timing tag so operators can pinpoint whether wall time is spent in
|
|
2790
2924
|
/// command plan compilation, transport spawn, pane verification, or the
|
|
@@ -2821,6 +2955,10 @@ pub(crate) fn write_worker_spawn_timing_event(
|
|
|
2821
2955
|
);
|
|
2822
2956
|
}
|
|
2823
2957
|
|
|
2958
|
+
/// ---
|
|
2959
|
+
/// purpose: 从 state 里取某席位的 provider wire 名
|
|
2960
|
+
/// returns: 取到的名字,缺失时为 fake
|
|
2961
|
+
/// ---
|
|
2824
2962
|
pub(crate) fn provider_wire_from_state<'a>(
|
|
2825
2963
|
state: &'a serde_json::Value,
|
|
2826
2964
|
agent_id: &str,
|
|
@@ -3068,6 +3206,11 @@ fn write_restart_resume_decision_event(
|
|
|
3068
3206
|
.map_err(|e| LifecycleError::StatePersist(e.to_string()))
|
|
3069
3207
|
}
|
|
3070
3208
|
|
|
3209
|
+
/// ---
|
|
3210
|
+
/// purpose: 列出本 workspace 里可重启的团队
|
|
3211
|
+
/// returns: 每个团队一条候选;没有活团队但顶层 state 有可重启形状时返回它自己
|
|
3212
|
+
/// errors: 读 runtime state 失败时返回 StatePersist
|
|
3213
|
+
/// ---
|
|
3071
3214
|
/// `restart_candidates(workspace)`(`restart/selection.py:12`)。从 snapshot + active
|
|
3072
3215
|
/// state 收集可重启 team。
|
|
3073
3216
|
pub(crate) fn restart_candidates(workspace: &Path) -> Result<Vec<RestartCandidate>, LifecycleError> {
|
|
@@ -3090,6 +3233,13 @@ pub(crate) fn restart_candidates(workspace: &Path) -> Result<Vec<RestartCandidat
|
|
|
3090
3233
|
.collect())
|
|
3091
3234
|
}
|
|
3092
3235
|
|
|
3236
|
+
/// ---
|
|
3237
|
+
/// purpose: 选出本次重启的目标团队
|
|
3238
|
+
/// params:
|
|
3239
|
+
/// team: 指定团队名,None 时按唯一性选
|
|
3240
|
+
/// returns: 选中的候选
|
|
3241
|
+
/// errors: 选不出或选中的 state 不具备可重启形状时返回 TeamSelect
|
|
3242
|
+
/// ---
|
|
3093
3243
|
/// `select_restart_state(workspace, team)`(`restart/selection.py:49`)。按 `--team` 或
|
|
3094
3244
|
/// 唯一性选一个;歧义/未找到 → `TeamSelect`。
|
|
3095
3245
|
pub(crate) fn select_restart_state(
|
|
@@ -3728,7 +3878,7 @@ tasks:
|
|
|
3728
3878
|
StartMode::Resumed,
|
|
3729
3879
|
&spawn,
|
|
3730
3880
|
&RespawnEpochTransport,
|
|
3731
|
-
|
|
3881
|
+
false,
|
|
3732
3882
|
)
|
|
3733
3883
|
.expect("mark respawned");
|
|
3734
3884
|
|