feat(tasks): mark tasks and lists as manual
Reminders written down as todos had no home: every task looked like Claude work. A manual task now shows a MANUAL badge and hides send-to-queue, refine and the planning session; the queue picker, daily prep and the list handler all skip it, with a TaskStateService guard so the MCP surface and hub cannot start one either. Opening a hand-driven ConPTY session stays available on purpose. A list can be marked manual in its settings, which makes tasks created there (UI and MCP add_task) start out manual. Toggle per task from its context menu.
This commit is contained in:
@@ -427,6 +427,8 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
|
||||
if (string.IsNullOrWhiteSpace(NewTaskTitle) || _currentList?.Kind != ListKind.User) return;
|
||||
var listId = _currentList.Id["user:".Length..];
|
||||
await using var db = await _dbFactory.CreateDbContextAsync();
|
||||
// A manual list holds reminders, so tasks created in it start out manual.
|
||||
var listIsManual = await db.Lists.Where(l => l.Id == listId).Select(l => l.IsManual).FirstOrDefaultAsync();
|
||||
var entity = new TaskEntity
|
||||
{
|
||||
Id = Guid.NewGuid().ToString("N"),
|
||||
@@ -434,6 +436,7 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
|
||||
Title = NewTaskTitle.Trim(),
|
||||
Status = TaskStatus.Idle,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
IsManual = listIsManual,
|
||||
};
|
||||
await new TaskRepository(db).AddAsync(entity);
|
||||
var row = TaskRowViewModel.FromEntity(entity);
|
||||
@@ -622,6 +625,23 @@ public sealed partial class TasksIslandViewModel : ViewModelBase, IDisposable
|
||||
TasksChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>Flips a task between "Claude can run this" and "manual reminder". A manual task
|
||||
/// hides every hand-off affordance and is skipped by the queue picker and daily prep.</summary>
|
||||
[RelayCommand]
|
||||
private async Task ToggleManualAsync(TaskRowViewModel? row)
|
||||
{
|
||||
if (row is null) return;
|
||||
row.IsManual = !row.IsManual;
|
||||
await using var db = await _dbFactory.CreateDbContextAsync();
|
||||
var entity = await db.Tasks.FirstOrDefaultAsync(t => t.Id == row.Id);
|
||||
if (entity != null)
|
||||
{
|
||||
entity.IsManual = row.IsManual;
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
TasksChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task AddToMyDayAsync(TaskRowViewModel? row)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user