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. A task /// that has never run, or whose worktree was just created fresh, gets a fresh-start spec /// (no --resume); an existing worktree with a persisted SessionId gets --resume. 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 every distinct existing repo dir via --add-dir. listId scopes the brief label /// and the cwd to that list; null means all lists (cwd = first existing repo dir). Throws /// InvalidOperationException if taskIds is empty or no task has an existing working directory. Task BuildForMergeHelperAsync(IReadOnlyList taskIds, string? listId, CancellationToken ct); }