using ClaudeDo.Worker.Planning; namespace ClaudeDo.Worker.Runner; public interface IInteractiveLaunchSpecService { /// Maps an already-prepared planning START context (worktree + prompt files + token, /// produced by PlanningSessionManager.StartAsync) into a LaunchSpec for an embedded ConPTY /// planning session — same planning CLI args as the wt launcher, planning env carried in Env. LaunchSpec BuildPlanningStart(PlanningSessionStartContext ctx); /// Maps a planning RESUME context (from PlanningSessionManager.ResumeAsync) into a /// LaunchSpec for an embedded ConPTY planning session (--permission-mode plan --resume). LaunchSpec BuildPlanningResume(PlanningSessionResumeContext ctx); /// Builds a LaunchSpec for opening an interactive session in a task's worktree. /// Throws KeyNotFoundException if the task doesn't exist, InvalidOperationException /// if it's Running/Queued. If the task has no usable worktree yet, one is created on /// demand (same mechanism as an autonomous run) provided the task's list has a working /// directory pointing at a git repo -- otherwise throws InvalidOperationException. Resumes /// (--resume) this task's own last interactive session (TaskEntity.InteractiveSessionId) if /// it has one, else the latest autonomous run's session; a task that has never run either /// way, or whose worktree was just created fresh, gets a fresh-start spec instead -- pre- /// assigned a new session id via --session-id and persisted to InteractiveSessionId before /// launch, so a closed/aborted session can be resumed next time. Task BuildForTaskAsync(string taskId, CancellationToken ct); /// Builds a LaunchSpec for an ad-hoc interactive session in an arbitrary directory -- /// no task, no worktree, no session-skills seeding. Throws InvalidOperationException if the /// directory doesn't exist. Task BuildForDirectoryAsync(string directory, CancellationToken ct); /// Builds a LaunchSpec for an embedded ConPTY "merge helper" session that drives the /// given tasks to a merged/Done state via the mcp__claudedo__* tools. Writes a per-session /// system prompt + task brief under ~/.todo-app/merge-helper-sessions/<guid> and exposes /// that dir plus the list's repo dir via --add-dir. cwd is the list's working directory. /// Throws KeyNotFoundException if the list doesn't exist; InvalidOperationException if /// taskIds is empty or the list has no existing working directory. Task BuildForMergeHelperAsync(IReadOnlyList taskIds, string listId, CancellationToken ct); /// Creates the ClaudeDo task that hosts a list-handler run (Mission Control's /// "Let Claude handle it") and stamps the list repo's current HEAD as the review range's /// base commit (see TaskEntity.HandlerBaseCommit). Returns the new task's id. Throws /// KeyNotFoundException if the list doesn't exist; InvalidOperationException if taskIds /// is empty or the list has no existing working directory. Task CreateMergeHelperTaskAsync( IReadOnlyList taskIds, string listId, string title, string descriptionHeader, CancellationToken ct); /// Builds a LaunchSpec for the fresh ConPTY session a merge-helper run hands off to /// once Phase 2 (enhance) is done -- reuses the SAME handler task id (no new task, HandlerBaseCommit /// untouched) and the unmodified merge-helper system prompt, writing only a fresh handoff kickoff /// naming the surviving tasks. Throws KeyNotFoundException if the task/list doesn't exist; /// InvalidOperationException if survivingTaskIds is empty or the list has no working directory. Task BuildForMergeHelperHandoffAsync( string taskId, IReadOnlyList survivingTaskIds, CancellationToken ct); }