refactor(interactive): remove streaming interactive stack (superseded by ConPTY)

The embedded ConPTY terminal replaced the in-app streaming interactive session, so
delete the dead stack: StreamingClaudeSession, InteractiveSessionService,
ProcessClaudeStreamTransport, IClaudeStreamTransport, ILiveSession, LiveSessionRegistry,
IdleSessionReaper (+ WorkerConfig.InteractiveIdleTimeoutMinutes), the WorkerHub
interactive methods + HubBroadcaster events, IWorkerClient interactive members, the
TaskMonitorViewModel composer + SessionTerminalView composer markup, and the old
'Run interactively' entry. AskUser/PendingQuestionRegistry, the autonomous path,
planning, ResumeTaskInTerminal, and all ConPTY code are kept. Localization pruned.
This commit is contained in:
mika kuns
2026-07-23 16:47:16 +02:00
parent d8194ad57e
commit c412a84fdf
40 changed files with 23 additions and 2338 deletions
@@ -263,83 +263,6 @@
Command="{Binding RejectReviewCommand}" />
</Grid>
<!-- Interactive composer + queued strip — chat with a live in-app session -->
<StackPanel DockPanel.Dock="Bottom" Orientation="Vertical">
<!-- Queued messages strip -->
<Border IsVisible="{Binding Monitor.HasQueuedMessages}"
BorderBrush="{DynamicResource LineBrush}"
BorderThickness="0,1,0,0"
Padding="12,4">
<StackPanel Spacing="2">
<TextBlock Classes="meta"
Text="{loc:Tr session.composer.queued}"
Foreground="{DynamicResource TextMuteBrush}" />
<ItemsControl ItemsSource="{Binding Monitor.QueuedMessages}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:QueuedMessageViewModel">
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,1">
<TextBlock Grid.Column="0"
Text="⧗"
Foreground="{DynamicResource TextMuteBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
VerticalAlignment="Center"
Margin="0,0,6,0" />
<TextBlock Grid.Column="1"
Text="{Binding Text}"
Foreground="{DynamicResource TextDimBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center" />
<Button Grid.Column="2"
Classes="title-ctrl"
Command="{Binding RemoveCommand}"
ToolTip.Tip="{loc:Tr session.composer.unqueue}"
Margin="4,0,0,0">
<PathIcon Data="{StaticResource Icon.WinClose}" Width="8" Height="8"/>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
<!-- Composer input row -->
<Grid IsVisible="{Binding Monitor.IsInteractiveLive}"
ColumnDefinitions="Auto,*,Auto,Auto"
Margin="12,2,12,8">
<TextBlock Grid.Column="0" Text="&#x276F;"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
Foreground="{DynamicResource AccentBrush}"
VerticalAlignment="Center" Margin="0,0,8,0" />
<TextBox Grid.Column="1"
Classes="review-prompt"
Text="{Binding Monitor.ComposerDraft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
AcceptsReturn="False"
TextWrapping="Wrap"
MaxHeight="160"
PlaceholderText="{loc:Tr session.composer.placeholder}"
VerticalContentAlignment="Center"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}">
<TextBox.KeyBindings>
<KeyBinding Gesture="Enter" Command="{Binding Monitor.SubmitComposerCommand}" />
</TextBox.KeyBindings>
</TextBox>
<Button Grid.Column="2" Classes="prompt-action"
VerticalAlignment="Center" Margin="12,0,0,0"
Command="{Binding Monitor.InterruptInteractiveCommand}"
ToolTip.Tip="{loc:Tr session.composer.interrupt}">
<PathIcon Data="{StaticResource Icon.Stop}" Width="10" Height="10"/>
</Button>
<Button Grid.Column="3" Classes="prompt-action accent" Content="[Send]"
VerticalAlignment="Center" Margin="4,0,0,0"
Command="{Binding Monitor.SubmitComposerCommand}" />
</Grid>
</StackPanel>
<ScrollViewer Name="LogScroll"
VerticalScrollBarVisibility="Visible"
AllowAutoHide="False"
@@ -50,79 +50,6 @@
</Border>
</Grid>
<!-- ── Queued strip + Composer bar ── -->
<StackPanel DockPanel.Dock="Bottom" Orientation="Vertical">
<!-- Queued messages strip -->
<Border IsVisible="{Binding #Root.HasQueuedMessages}"
Background="{DynamicResource Surface2Brush}"
BorderBrush="{DynamicResource LineBrush}"
BorderThickness="0,0,0,1"
Padding="8,4">
<StackPanel Spacing="2">
<TextBlock Classes="meta"
Text="{loc:Tr session.composer.queued}"
Foreground="{DynamicResource TextMuteBrush}" />
<ItemsControl ItemsSource="{Binding #Root.QueuedMessages}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:QueuedMessageViewModel">
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,1">
<TextBlock Grid.Column="0"
Text="⧗"
Foreground="{DynamicResource TextMuteBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
VerticalAlignment="Center"
Margin="0,0,6,0" />
<TextBlock Grid.Column="1"
Text="{Binding Text}"
Foreground="{DynamicResource TextDimBrush}"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center" />
<Button Grid.Column="2"
Classes="title-ctrl"
Command="{Binding RemoveCommand}"
ToolTip.Tip="{loc:Tr session.composer.unqueue}"
Margin="4,0,0,0">
<PathIcon Data="{StaticResource Icon.WinClose}" Width="8" Height="8"/>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
<!-- Composer input row -->
<Border IsVisible="{Binding #Root.IsComposerVisible}"
Background="{DynamicResource Surface2Brush}"
BorderBrush="{DynamicResource LineBrush}"
BorderThickness="0,1,0,0"
Padding="6,5">
<Grid ColumnDefinitions="*,Auto,Auto">
<TextBox Grid.Column="0"
Text="{Binding #Root.ComposerText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
PlaceholderText="{Binding #Root.ComposerPlaceholder}"
AcceptsReturn="False">
<TextBox.KeyBindings>
<KeyBinding Gesture="Enter" Command="{Binding #Root.SubmitCommand}"/>
</TextBox.KeyBindings>
</TextBox>
<Button Grid.Column="1"
Margin="6,0,0,0"
Classes="title-ctrl"
Command="{Binding #Root.InterruptCommand}"
ToolTip.Tip="{loc:Tr session.composer.interrupt}">
<PathIcon Data="{StaticResource Icon.Stop}" Width="10" Height="10"/>
</Button>
<Button Grid.Column="2"
Margin="6,0,0,0"
Content="{loc:Tr session.composer.send}"
Command="{Binding #Root.SubmitCommand}"/>
</Grid>
</Border>
</StackPanel>
<!-- ── Log output ── -->
<ScrollViewer Name="LogScroll"
VerticalScrollBarVisibility="Visible"
@@ -1,9 +1,7 @@
using System.Collections;
using System.Collections.Specialized;
using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Data;
namespace ClaudeDo.Ui.Views.Islands;
@@ -19,33 +17,12 @@ public partial class SessionTerminalView : UserControl
AvaloniaProperty.Register<SessionTerminalView, bool>(nameof(IsDone));
public static readonly StyledProperty<bool> IsFailedProperty =
AvaloniaProperty.Register<SessionTerminalView, bool>(nameof(IsFailed));
public static readonly StyledProperty<bool> IsComposerVisibleProperty =
AvaloniaProperty.Register<SessionTerminalView, bool>(nameof(IsComposerVisible), defaultValue: false);
public static readonly StyledProperty<string?> ComposerTextProperty =
AvaloniaProperty.Register<SessionTerminalView, string?>(nameof(ComposerText), defaultBindingMode: BindingMode.TwoWay);
public static readonly StyledProperty<ICommand?> SubmitCommandProperty =
AvaloniaProperty.Register<SessionTerminalView, ICommand?>(nameof(SubmitCommand));
public static readonly StyledProperty<ICommand?> InterruptCommandProperty =
AvaloniaProperty.Register<SessionTerminalView, ICommand?>(nameof(InterruptCommand));
public static readonly StyledProperty<string?> ComposerPlaceholderProperty =
AvaloniaProperty.Register<SessionTerminalView, string?>(nameof(ComposerPlaceholder));
public static readonly StyledProperty<System.Collections.IEnumerable?> QueuedMessagesProperty =
AvaloniaProperty.Register<SessionTerminalView, System.Collections.IEnumerable?>(nameof(QueuedMessages));
public static readonly StyledProperty<bool> HasQueuedMessagesProperty =
AvaloniaProperty.Register<SessionTerminalView, bool>(nameof(HasQueuedMessages), defaultValue: false);
public IEnumerable? Entries { get => GetValue(EntriesProperty); set => SetValue(EntriesProperty, value); }
public string? Label { get => GetValue(LabelProperty); set => SetValue(LabelProperty, value); }
public bool IsRunning { get => GetValue(IsRunningProperty); set => SetValue(IsRunningProperty, value); }
public bool IsDone { get => GetValue(IsDoneProperty); set => SetValue(IsDoneProperty, value); }
public bool IsFailed { get => GetValue(IsFailedProperty); set => SetValue(IsFailedProperty, value); }
public bool IsComposerVisible { get => GetValue(IsComposerVisibleProperty); set => SetValue(IsComposerVisibleProperty, value); }
public string? ComposerText { get => GetValue(ComposerTextProperty); set => SetValue(ComposerTextProperty, value); }
public ICommand? SubmitCommand { get => GetValue(SubmitCommandProperty); set => SetValue(SubmitCommandProperty, value); }
public ICommand? InterruptCommand { get => GetValue(InterruptCommandProperty); set => SetValue(InterruptCommandProperty, value); }
public string? ComposerPlaceholder { get => GetValue(ComposerPlaceholderProperty); set => SetValue(ComposerPlaceholderProperty, value); }
public System.Collections.IEnumerable? QueuedMessages { get => GetValue(QueuedMessagesProperty); set => SetValue(QueuedMessagesProperty, value); }
public bool HasQueuedMessages { get => GetValue(HasQueuedMessagesProperty); set => SetValue(HasQueuedMessagesProperty, value); }
private INotifyCollectionChanged? _subscribedCollection;
@@ -49,8 +49,6 @@
<MenuItem Header="{loc:Tr tasks.ctxMarkCancelled}" Tag="Cancelled" Click="OnSetStatusClick"/>
</MenuItem>
<Separator/>
<MenuItem Header="{loc:Tr tasks.ctxRunInteractively}"
Click="OnRunInteractivelyClick"/>
<MenuItem Header="{loc:Tr tasks.ctxOpenConPtySession}"
Click="OnOpenConPtySessionClick"/>
<MenuItem Header="{loc:Tr tasks.ctxPickUpInTerminal}"
@@ -61,12 +61,6 @@ public partial class TaskRowView : UserControl
await vm.OpenPlanningSessionCommand.ExecuteAsync(row);
}
private async void OnRunInteractivelyClick(object? sender, RoutedEventArgs e)
{
if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
await vm.RunInteractivelyCommand.ExecuteAsync(row);
}
private void OnOpenConPtySessionClick(object? sender, RoutedEventArgs e)
{
if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
@@ -107,14 +107,7 @@
Label="{Binding DisplayTitle}"
IsRunning="{Binding IsRunning}"
IsDone="{Binding IsDone}"
IsFailed="{Binding IsFailed}"
IsComposerVisible="{Binding IsInteractiveLive}"
ComposerText="{Binding ComposerDraft, Mode=TwoWay}"
SubmitCommand="{Binding SubmitComposerCommand}"
InterruptCommand="{Binding InterruptInteractiveCommand}"
ComposerPlaceholder="{loc:Tr session.composer.placeholder}"
QueuedMessages="{Binding QueuedMessages}"
HasQueuedMessages="{Binding HasQueuedMessages}" />
IsFailed="{Binding IsFailed}" />
</DockPanel>
</Border>