diff --git a/src/ClaudeDo.Ui/Services/PtyTerminalSession.cs b/src/ClaudeDo.Ui/Services/PtyTerminalSession.cs
index 82980292..597469df 100644
--- a/src/ClaudeDo.Ui/Services/PtyTerminalSession.cs
+++ b/src/ClaudeDo.Ui/Services/PtyTerminalSession.cs
@@ -137,6 +137,42 @@ public sealed class PtyTerminalSession : IDisposable
}
}
+ ///
+ /// Inserts at the cursor without submitting it — the drop-a-file-path
+ /// case. Same write seam as , just without the Enter.
+ ///
+ public async Task SendTextAsync(string text)
+ {
+ if (_control is not { } control || !IsRunning || string.IsNullOrEmpty(text)) return false;
+ try
+ {
+ await SendRawAsync(control, text);
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Pastes the clipboard into the session. wires paste to the
+ /// right-click menu only, so Ctrl+V otherwise reaches the child as a raw control byte and does
+ /// nothing. Goes through the emulator's own rather than
+ /// writing the clipboard text raw, because that is what honours bracketed-paste mode — without
+ /// it a multi-line paste is read line by line and submits on the first newline.
+ ///
+ public async Task PasteAsync()
+ {
+ if (_control is not { } control || !IsRunning) return;
+ try
+ {
+ if (s_terminalViewField?.GetValue(control) is TerminalView view)
+ await view.PasteAsync();
+ }
+ catch (Exception) { /* best-effort, same as SendLineAsync */ }
+ }
+
// Long enough that the two writes can't be read as one chunk by the child's stdin reader.
private static readonly TimeSpan SubmitDelay = TimeSpan.FromMilliseconds(150);
diff --git a/src/ClaudeDo.Ui/ViewModels/InteractiveTerminalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/InteractiveTerminalViewModel.cs
index ca72e00c..b0fed886 100644
--- a/src/ClaudeDo.Ui/ViewModels/InteractiveTerminalViewModel.cs
+++ b/src/ClaudeDo.Ui/ViewModels/InteractiveTerminalViewModel.cs
@@ -136,6 +136,14 @@ public sealed partial class InteractiveTerminalViewModel : ViewModelBase, IDispo
/// type into (or the write seam is gone).
public Task SendLineAsync(string text) => _session.SendLineAsync(text);
+ /// Inserts text at the cursor without submitting — see
+ /// (dropped file paths).
+ public Task SendTextAsync(string text) => _session.SendTextAsync(text);
+
+ /// Pastes the clipboard into the session (Ctrl+V) — see
+ /// .
+ public Task PasteAsync() => _session.PasteAsync();
+
public void Kill() => _session.Kill();
public void Dispose()
diff --git a/src/ClaudeDo.Ui/Views/InteractiveTerminalView.axaml b/src/ClaudeDo.Ui/Views/InteractiveTerminalView.axaml
index 8277ddbb..520972aa 100644
--- a/src/ClaudeDo.Ui/Views/InteractiveTerminalView.axaml
+++ b/src/ClaudeDo.Ui/Views/InteractiveTerminalView.axaml
@@ -4,7 +4,8 @@
xmlns:term="using:Iciclecreek.Terminal"
x:Class="ClaudeDo.Ui.Views.InteractiveTerminalView"
x:DataType="vm:InteractiveTerminalViewModel"
- x:Name="Root">
+ x:Name="Root"
+ DragDrop.AllowDrop="True">