1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! In-project session preparation and the resume-path compiled-prompt refresh.
//!
//! Why: split out of `lifecycle.rs` (#4752), which sits at its frozen SLOC
//! budget. Both items here answer one question — "what must be on disk before
//! this session's process starts?" — so they belong together rather than
//! padding the lifecycle state machine.
//! What: [`prepare_inproject_session`] (the #1913 preparation call the
//! in-project spawn paths make directly) and
//! [`refresh_resume_compiled_prompt`] (the #4752 fatal compiled-prompt
//! write the resume path needs because it never runs `prepare_session*`).
//! Test: `prepare_inproject_session_writes_statusline`,
//! `prepare_inproject_session_emits_stage_events_in_order`,
//! `refresh_resume_compiled_prompt_writes_the_project_local_file`,
//! `refresh_resume_compiled_prompt_reports_an_actionable_failure`.
use ;
use crateManagedSessionId;
/// Run the session-preparation pipeline for an in-project worktree, logging
/// (never propagating) any failure.
///
/// Why (#1913): [`spawn_managed_inproject`] has no clone step to wrap this call
/// in — unlike `spawn_managed`'s clone branch and `spawn_managed_local`, which
/// both get preparation "for free" as part of `WorkspaceProvisioner::provision_in`
/// — so it must invoke [`crate::core::session_launch::prepare_session_with_repo_url`]
/// directly. Extracted to a named, `fw`-parameterised function (rather than
/// inlined) so it is unit-testable against a hermetic [`crate::core::paths::FrameworkPaths::under`]
/// tempdir without touching the operator's real `~/.trusty-mpm`/`~/.claude`.
/// What: calls `prepare_session_for_managed(fw, worktree, Some(repo_url),
/// session_id)` — #4832 threads the id so the compiled prompt lands in this
/// session's own directory rather than the unmanaged `local` bucket.
/// On success, logs the deployed-agent count AND the deployed-skill count
/// (`report.skill_deploy.deployed.len()` — #1917; previously only the agent
/// count was logged, so a skill-deploy no-op was invisible here too). On
/// failure, logs a `tracing::warn!` and returns — mirroring
/// `WorkspaceProvisioner::provision_in`'s non-fatal handling of the identical
/// call, so a prep failure never blocks the session from spawning.
/// Test: `prepare_inproject_session_writes_statusline` in this module's `tests`
/// submodule.
pub
/// Refresh the project's compiled PM prompt on the RESUME path.
///
/// Why (#4752): `resume_managed` never calls `prepare_session*` on its healthy
/// path (`resume_self_heal` → `ensure_status_line` → `ensure_deployment_complete`
/// → `spawn_resume`), so without this a resumed session would run against
/// whatever the last start wrote — or nothing at all. Composing through the
/// SAME seam the spawn uses means the bytes written here are the bytes
/// `spawn_resume` is about to pass to `--append-system-prompt-file`.
/// What: composes the project-resolved prompt, writes it to
/// [`crate::core::instruction_pipeline::compiled_prompt_path`], and on failure
/// returns the operator-facing message from
/// [`crate::core::instruction_pipeline::instructions_failure_message`] —
/// the caller refuses the resume with it.
/// Test: `refresh_resume_compiled_prompt_writes_the_project_local_file`,
/// `refresh_resume_compiled_prompt_reports_an_actionable_failure`.
pub