Adds a 'New session' header button in Mission Control that opens a folder picker and starts a task-less embedded ConPTY session in the chosen directory. ConPtyPaneViewModel TaskId is now nullable (ad-hoc panes have no task and are never deduped) with a CreateAdHoc factory; the view does the picking, the VM stays picker-agnostic.
60 lines
2.4 KiB
C#
60 lines
2.4 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using ClaudeDo.Ui.Services;
|
|
|
|
namespace ClaudeDo.Ui.ViewModels.MissionControl;
|
|
|
|
/// <summary>
|
|
/// Command Center pane hosting an embedded ConPTY terminal for either one task's interactive
|
|
/// Claude session, or an ad-hoc/free session in a user-chosen directory (no task, <see cref="TaskId"/>
|
|
/// is null — ad-hoc panes are never deduped, unlike task-based ones). Distinct from the streamed-log
|
|
/// <see cref="ClaudeDo.Ui.ViewModels.Islands.TaskMonitorViewModel"/> pane; the two coexist until
|
|
/// the streaming interactive stack is removed.
|
|
/// </summary>
|
|
public sealed partial class ConPtyPaneViewModel : ViewModelBase, IMissionControlPane, IDisposable
|
|
{
|
|
public string? TaskId { get; }
|
|
|
|
[ObservableProperty] private string _displayTitle;
|
|
|
|
public InteractiveTerminalViewModel Terminal { get; } = new();
|
|
|
|
/// <summary>Raised when the terminal failed to start — the host surfaces this via the footer error strip.</summary>
|
|
public event Action<string>? ErrorReported;
|
|
|
|
/// <summary>Set by the host (Mission Control) to remove this pane from its collection.</summary>
|
|
public Action<ConPtyPaneViewModel>? CloseRequested { get; set; }
|
|
|
|
/// <summary>Task-based pane — dedup'd by <see cref="TaskId"/>. Pass null for an ad-hoc pane
|
|
/// (no task, never deduped); prefer <see cref="CreateAdHoc"/> at ad-hoc call sites.</summary>
|
|
public ConPtyPaneViewModel(string? taskId, string displayTitle, TerminalLaunchDescriptor descriptor)
|
|
{
|
|
TaskId = taskId;
|
|
_displayTitle = displayTitle;
|
|
Terminal.PropertyChanged += OnTerminalPropertyChanged;
|
|
Terminal.Start(descriptor);
|
|
}
|
|
|
|
/// <summary>Ad-hoc pane — no task, no dedup.</summary>
|
|
public static ConPtyPaneViewModel CreateAdHoc(string displayTitle, TerminalLaunchDescriptor descriptor)
|
|
=> new(null, displayTitle, descriptor);
|
|
|
|
private void OnTerminalPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
{
|
|
if (e.PropertyName == nameof(InteractiveTerminalViewModel.StartError) && Terminal.StartError is { Length: > 0 } error)
|
|
ErrorReported?.Invoke(error);
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void Close() => CloseRequested?.Invoke(this);
|
|
|
|
public void Dispose()
|
|
{
|
|
Terminal.PropertyChanged -= OnTerminalPropertyChanged;
|
|
Terminal.Kill();
|
|
Terminal.Dispose();
|
|
}
|
|
}
|