diff --git a/src/ClaudeDo.Localization/locales/de.json b/src/ClaudeDo.Localization/locales/de.json index 2504b9f3..89e117d7 100644 --- a/src/ClaudeDo.Localization/locales/de.json +++ b/src/ClaudeDo.Localization/locales/de.json @@ -130,6 +130,7 @@ "tasks": { "showCompletedTip": "Abgeschlossene anzeigen", "letClaudeTip": "Claude machen lassen", + "quickClaudeTip": "Schnelle Claude-Sitzung", "listSettingsTip": "Listeneinstellungen", "addPlaceholder": "Aufgabe hinzufügen…", "enterKey": "ENTER", diff --git a/src/ClaudeDo.Localization/locales/en.json b/src/ClaudeDo.Localization/locales/en.json index 3c9a44e1..840a421d 100644 --- a/src/ClaudeDo.Localization/locales/en.json +++ b/src/ClaudeDo.Localization/locales/en.json @@ -130,6 +130,7 @@ "tasks": { "showCompletedTip": "Show completed", "letClaudeTip": "Let Claude handle it", + "quickClaudeTip": "Quick Claude session", "listSettingsTip": "List settings", "addPlaceholder": "Add a task…", "enterKey": "ENTER", diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs index 60de8d06..1e8fe957 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs @@ -73,12 +73,25 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable [ObservableProperty] private bool _showNotesRow; [ObservableProperty] private bool _isMyDayList; [ObservableProperty] private bool _isLetClaudeVisible; + [ObservableProperty] private bool _isQuickClaudeVisible; public event EventHandler? LetClaudeHandleRequested; [RelayCommand] private void LetClaudeHandle() => LetClaudeHandleRequested?.Invoke(this, EventArgs.Empty); + // Opens a task-less ConPTY session directly in the current list's working dir. The shell owns + // Mission Control, so this just raises an event for it to act on (mirrors OpenConPtySessionRequested). + public event Action? OpenQuickClaudeSessionRequested; + + [RelayCommand] + private void OpenQuickClaudeSession() + { + var dir = _currentList?.WorkingDir; + if (string.IsNullOrWhiteSpace(dir) || !System.IO.Directory.Exists(dir)) return; + OpenQuickClaudeSessionRequested?.Invoke(dir); + } + internal Task? LoadTask { get; private set; } public Func? ShowUnfinishedPlanningModal { get; set; } @@ -221,7 +234,10 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable if (e.PropertyName == nameof(ListNavItemViewModel.Name)) HeaderTitle = vm.Name; else if (e.PropertyName == nameof(ListNavItemViewModel.WorkingDir)) + { IsLetClaudeVisible = vm.Kind == ListKind.User && !string.IsNullOrWhiteSpace(vm.WorkingDir); + IsQuickClaudeVisible = IsLetClaudeVisible; + } } public void LoadForList(ListNavItemViewModel? list) @@ -259,13 +275,14 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable ShowOpenLabel = false; ShowNotesRow = false; if (listChanged) SelectedTask = null; - if (list is null) { IsLetClaudeVisible = false; LoadTask = Task.CompletedTask; return; } + if (list is null) { IsLetClaudeVisible = false; IsQuickClaudeVisible = false; LoadTask = Task.CompletedTask; return; } HeaderTitle = list.Name; HeaderEyebrow = DateTime.Now.ToString("dddd · MMM dd", CultureInfo.InvariantCulture).ToUpperInvariant(); ShowNotesRow = list.Id == "smart:my-day"; IsMyDayList = list.Id == "smart:my-day"; IsLetClaudeVisible = list.Kind == ListKind.User && !string.IsNullOrWhiteSpace(list.WorkingDir); + IsQuickClaudeVisible = IsLetClaudeVisible; LoadTask = LoadForListAsync(list, ct, reusable); } diff --git a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs index ef34bfc5..651d2b63 100644 --- a/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/IslandsShellViewModel.cs @@ -242,6 +242,11 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable OpenMissionControl(); _ = MissionControl.OpenConPtySessionAsync(taskId); }; + Tasks.OpenQuickClaudeSessionRequested += dir => + { + OpenMissionControl(); + _ = MissionControl.OpenAdHocConPtySessionAsync(dir); + }; Tasks.OpenPlanningConPtyRequested += (taskId, resume) => { OpenMissionControl(); diff --git a/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml b/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml index d3c64411..59338f48 100644 --- a/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml +++ b/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml @@ -37,6 +37,10 @@ Command="{Binding LetClaudeHandleCommand}" ToolTip.Tip="{loc:Tr tasks.letClaudeTip}"> +