diff --git a/.gitignore b/.gitignore
index 9fadc0a..54868af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,8 @@ artifacts/
# Avalonia / XAML designer
*.designer.cs
+# ...but EF Core migration Designer files are real source and must be tracked
+!**/Migrations/*.Designer.cs
# Project-specific
*.db
diff --git a/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.Designer.cs b/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.Designer.cs
new file mode 100644
index 0000000..8474e6f
--- /dev/null
+++ b/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.Designer.cs
@@ -0,0 +1,482 @@
+//
+using System;
+using ClaudeDo.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace ClaudeDo.Data.Migrations
+{
+ [DbContext(typeof(ClaudeDoDbContext))]
+ [Migration("20260416064948_InitialCreate")]
+ partial class InitialCreate
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
+ {
+ b.Property("ListId")
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.HasKey("ListId");
+
+ b.ToTable("list_config", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("DefaultCommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("default_commit_type");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.Property("WorkingDir")
+ .HasColumnType("TEXT")
+ .HasColumnName("working_dir");
+
+ b.HasKey("Id");
+
+ b.ToTable("lists", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("Completed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("completed");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("OrderNum")
+ .HasColumnType("INTEGER")
+ .HasColumnName("order_num");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_subtasks_task_id");
+
+ b.ToTable("subtasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TagEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasColumnName("id");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("tags", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = 1L,
+ Name = "agent"
+ },
+ new
+ {
+ Id = 2L,
+ Name = "manual"
+ });
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("CommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("commit_type");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("Description")
+ .HasColumnType("TEXT")
+ .HasColumnName("description");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("ListId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("Result")
+ .HasColumnType("TEXT")
+ .HasColumnName("result");
+
+ b.Property("ScheduledFor")
+ .HasColumnType("TEXT")
+ .HasColumnName("scheduled_for");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("status");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ListId")
+ .HasDatabaseName("idx_tasks_list_id");
+
+ b.HasIndex("Status")
+ .HasDatabaseName("idx_tasks_status");
+
+ b.ToTable("tasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("ErrorMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("error_markdown");
+
+ b.Property("ExitCode")
+ .HasColumnType("INTEGER")
+ .HasColumnName("exit_code");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("IsRetry")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_retry");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Prompt")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("prompt");
+
+ b.Property("ResultMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("result_markdown");
+
+ b.Property("RunNumber")
+ .HasColumnType("INTEGER")
+ .HasColumnName("run_number");
+
+ b.Property("SessionId")
+ .HasColumnType("TEXT")
+ .HasColumnName("session_id");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("StructuredOutputJson")
+ .HasColumnType("TEXT")
+ .HasColumnName("structured_output");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("TokensIn")
+ .HasColumnType("INTEGER")
+ .HasColumnName("tokens_in");
+
+ b.Property("TokensOut")
+ .HasColumnType("INTEGER")
+ .HasColumnName("tokens_out");
+
+ b.Property("TurnCount")
+ .HasColumnType("INTEGER")
+ .HasColumnName("turn_count");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_task_runs_task_id");
+
+ b.ToTable("task_runs", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
+ {
+ b.Property("TaskId")
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("BaseCommit")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("base_commit");
+
+ b.Property("BranchName")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("branch_name");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("DiffStat")
+ .HasColumnType("TEXT")
+ .HasColumnName("diff_stat");
+
+ b.Property("HeadCommit")
+ .HasColumnType("TEXT")
+ .HasColumnName("head_commit");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("path");
+
+ b.Property("State")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("active")
+ .HasColumnName("state");
+
+ b.HasKey("TaskId");
+
+ b.ToTable("worktrees", (string)null);
+ });
+
+ modelBuilder.Entity("list_tags", b =>
+ {
+ b.Property("list_id")
+ .HasColumnType("TEXT");
+
+ b.Property("tag_id")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("list_id", "tag_id");
+
+ b.HasIndex("tag_id");
+
+ b.ToTable("list_tags", (string)null);
+ });
+
+ modelBuilder.Entity("task_tags", b =>
+ {
+ b.Property("task_id")
+ .HasColumnType("TEXT");
+
+ b.Property("tag_id")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("task_id", "tag_id");
+
+ b.HasIndex("tag_id");
+
+ b.ToTable("task_tags", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
+ .WithOne("Config")
+ .HasForeignKey("ClaudeDo.Data.Models.ListConfigEntity", "ListId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("List");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithMany("Subtasks")
+ .HasForeignKey("TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
+ .WithMany("Tasks")
+ .HasForeignKey("ListId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("List");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithMany("Runs")
+ .HasForeignKey("TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithOne("Worktree")
+ .HasForeignKey("ClaudeDo.Data.Models.WorktreeEntity", "TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("list_tags", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", null)
+ .WithMany()
+ .HasForeignKey("list_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
+ .WithMany()
+ .HasForeignKey("tag_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("task_tags", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
+ .WithMany()
+ .HasForeignKey("tag_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
+ .WithMany()
+ .HasForeignKey("task_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Navigation("Config");
+
+ b.Navigation("Tasks");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Navigation("Runs");
+
+ b.Navigation("Subtasks");
+
+ b.Navigation("Worktree");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.Designer.cs b/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.Designer.cs
new file mode 100644
index 0000000..b8fa6b6
--- /dev/null
+++ b/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.Designer.cs
@@ -0,0 +1,498 @@
+//
+using System;
+using ClaudeDo.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace ClaudeDo.Data.Migrations
+{
+ [DbContext(typeof(ClaudeDoDbContext))]
+ [Migration("20260420075929_AddTaskFlagsAndNotes")]
+ partial class AddTaskFlagsAndNotes
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
+ {
+ b.Property("ListId")
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.HasKey("ListId");
+
+ b.ToTable("list_config", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("DefaultCommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("default_commit_type");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.Property("WorkingDir")
+ .HasColumnType("TEXT")
+ .HasColumnName("working_dir");
+
+ b.HasKey("Id");
+
+ b.ToTable("lists", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("Completed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("completed");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("OrderNum")
+ .HasColumnType("INTEGER")
+ .HasColumnName("order_num");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_subtasks_task_id");
+
+ b.ToTable("subtasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TagEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasColumnName("id");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("tags", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = 1L,
+ Name = "agent"
+ },
+ new
+ {
+ Id = 2L,
+ Name = "manual"
+ });
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("CommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("commit_type");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("Description")
+ .HasColumnType("TEXT")
+ .HasColumnName("description");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("IsMyDay")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_my_day");
+
+ b.Property("IsStarred")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_starred");
+
+ b.Property("ListId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("Notes")
+ .HasColumnType("TEXT")
+ .HasColumnName("notes");
+
+ b.Property("Result")
+ .HasColumnType("TEXT")
+ .HasColumnName("result");
+
+ b.Property("ScheduledFor")
+ .HasColumnType("TEXT")
+ .HasColumnName("scheduled_for");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("status");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ListId")
+ .HasDatabaseName("idx_tasks_list_id");
+
+ b.HasIndex("Status")
+ .HasDatabaseName("idx_tasks_status");
+
+ b.ToTable("tasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("ErrorMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("error_markdown");
+
+ b.Property("ExitCode")
+ .HasColumnType("INTEGER")
+ .HasColumnName("exit_code");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("IsRetry")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_retry");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Prompt")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("prompt");
+
+ b.Property("ResultMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("result_markdown");
+
+ b.Property("RunNumber")
+ .HasColumnType("INTEGER")
+ .HasColumnName("run_number");
+
+ b.Property("SessionId")
+ .HasColumnType("TEXT")
+ .HasColumnName("session_id");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("StructuredOutputJson")
+ .HasColumnType("TEXT")
+ .HasColumnName("structured_output");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("TokensIn")
+ .HasColumnType("INTEGER")
+ .HasColumnName("tokens_in");
+
+ b.Property("TokensOut")
+ .HasColumnType("INTEGER")
+ .HasColumnName("tokens_out");
+
+ b.Property("TurnCount")
+ .HasColumnType("INTEGER")
+ .HasColumnName("turn_count");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_task_runs_task_id");
+
+ b.ToTable("task_runs", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
+ {
+ b.Property("TaskId")
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("BaseCommit")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("base_commit");
+
+ b.Property("BranchName")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("branch_name");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("DiffStat")
+ .HasColumnType("TEXT")
+ .HasColumnName("diff_stat");
+
+ b.Property("HeadCommit")
+ .HasColumnType("TEXT")
+ .HasColumnName("head_commit");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("path");
+
+ b.Property("State")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("active")
+ .HasColumnName("state");
+
+ b.HasKey("TaskId");
+
+ b.ToTable("worktrees", (string)null);
+ });
+
+ modelBuilder.Entity("list_tags", b =>
+ {
+ b.Property("list_id")
+ .HasColumnType("TEXT");
+
+ b.Property("tag_id")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("list_id", "tag_id");
+
+ b.HasIndex("tag_id");
+
+ b.ToTable("list_tags", (string)null);
+ });
+
+ modelBuilder.Entity("task_tags", b =>
+ {
+ b.Property("task_id")
+ .HasColumnType("TEXT");
+
+ b.Property("tag_id")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("task_id", "tag_id");
+
+ b.HasIndex("tag_id");
+
+ b.ToTable("task_tags", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
+ .WithOne("Config")
+ .HasForeignKey("ClaudeDo.Data.Models.ListConfigEntity", "ListId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("List");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithMany("Subtasks")
+ .HasForeignKey("TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
+ .WithMany("Tasks")
+ .HasForeignKey("ListId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("List");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithMany("Runs")
+ .HasForeignKey("TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithOne("Worktree")
+ .HasForeignKey("ClaudeDo.Data.Models.WorktreeEntity", "TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("list_tags", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", null)
+ .WithMany()
+ .HasForeignKey("list_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
+ .WithMany()
+ .HasForeignKey("tag_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("task_tags", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
+ .WithMany()
+ .HasForeignKey("tag_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
+ .WithMany()
+ .HasForeignKey("task_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Navigation("Config");
+
+ b.Navigation("Tasks");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Navigation("Runs");
+
+ b.Navigation("Subtasks");
+
+ b.Navigation("Worktree");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/ClaudeDo.Data/Migrations/20260421113614_AddAppSettings.Designer.cs b/src/ClaudeDo.Data/Migrations/20260421113614_AddAppSettings.Designer.cs
new file mode 100644
index 0000000..a03d20e
--- /dev/null
+++ b/src/ClaudeDo.Data/Migrations/20260421113614_AddAppSettings.Designer.cs
@@ -0,0 +1,572 @@
+//
+using System;
+using ClaudeDo.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace ClaudeDo.Data.Migrations
+{
+ [DbContext(typeof(ClaudeDoDbContext))]
+ [Migration("20260421113614_AddAppSettings")]
+ partial class AddAppSettings
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.AppSettingsEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("INTEGER")
+ .HasColumnName("id");
+
+ b.Property("CentralWorktreeRoot")
+ .HasColumnType("TEXT")
+ .HasColumnName("central_worktree_root");
+
+ b.Property("DefaultClaudeInstructions")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("")
+ .HasColumnName("default_claude_instructions");
+
+ b.Property("DefaultMaxTurns")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(30)
+ .HasColumnName("default_max_turns");
+
+ b.Property("DefaultModel")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("sonnet")
+ .HasColumnName("default_model");
+
+ b.Property("DefaultPermissionMode")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("bypassPermissions")
+ .HasColumnName("default_permission_mode");
+
+ b.Property("WorktreeAutoCleanupDays")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(7)
+ .HasColumnName("worktree_auto_cleanup_days");
+
+ b.Property("WorktreeAutoCleanupEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("worktree_auto_cleanup_enabled");
+
+ b.Property("WorktreeStrategy")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("sibling")
+ .HasColumnName("worktree_strategy");
+
+ b.HasKey("Id");
+
+ b.ToTable("app_settings", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = 1,
+ DefaultClaudeInstructions = "",
+ DefaultMaxTurns = 30,
+ DefaultModel = "sonnet",
+ DefaultPermissionMode = "bypassPermissions",
+ WorktreeAutoCleanupDays = 7,
+ WorktreeAutoCleanupEnabled = false,
+ WorktreeStrategy = "sibling"
+ });
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
+ {
+ b.Property("ListId")
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.HasKey("ListId");
+
+ b.ToTable("list_config", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("DefaultCommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("default_commit_type");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.Property("WorkingDir")
+ .HasColumnType("TEXT")
+ .HasColumnName("working_dir");
+
+ b.HasKey("Id");
+
+ b.ToTable("lists", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("Completed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("completed");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("OrderNum")
+ .HasColumnType("INTEGER")
+ .HasColumnName("order_num");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_subtasks_task_id");
+
+ b.ToTable("subtasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TagEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasColumnName("id");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("tags", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = 1L,
+ Name = "agent"
+ },
+ new
+ {
+ Id = 2L,
+ Name = "manual"
+ });
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("CommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("commit_type");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("Description")
+ .HasColumnType("TEXT")
+ .HasColumnName("description");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("IsMyDay")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_my_day");
+
+ b.Property("IsStarred")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_starred");
+
+ b.Property("ListId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("Notes")
+ .HasColumnType("TEXT")
+ .HasColumnName("notes");
+
+ b.Property("Result")
+ .HasColumnType("TEXT")
+ .HasColumnName("result");
+
+ b.Property("ScheduledFor")
+ .HasColumnType("TEXT")
+ .HasColumnName("scheduled_for");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("status");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ListId")
+ .HasDatabaseName("idx_tasks_list_id");
+
+ b.HasIndex("Status")
+ .HasDatabaseName("idx_tasks_status");
+
+ b.ToTable("tasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("ErrorMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("error_markdown");
+
+ b.Property("ExitCode")
+ .HasColumnType("INTEGER")
+ .HasColumnName("exit_code");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("IsRetry")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_retry");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Prompt")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("prompt");
+
+ b.Property("ResultMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("result_markdown");
+
+ b.Property("RunNumber")
+ .HasColumnType("INTEGER")
+ .HasColumnName("run_number");
+
+ b.Property("SessionId")
+ .HasColumnType("TEXT")
+ .HasColumnName("session_id");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("StructuredOutputJson")
+ .HasColumnType("TEXT")
+ .HasColumnName("structured_output");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("TokensIn")
+ .HasColumnType("INTEGER")
+ .HasColumnName("tokens_in");
+
+ b.Property("TokensOut")
+ .HasColumnType("INTEGER")
+ .HasColumnName("tokens_out");
+
+ b.Property("TurnCount")
+ .HasColumnType("INTEGER")
+ .HasColumnName("turn_count");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_task_runs_task_id");
+
+ b.ToTable("task_runs", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
+ {
+ b.Property("TaskId")
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("BaseCommit")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("base_commit");
+
+ b.Property("BranchName")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("branch_name");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("DiffStat")
+ .HasColumnType("TEXT")
+ .HasColumnName("diff_stat");
+
+ b.Property("HeadCommit")
+ .HasColumnType("TEXT")
+ .HasColumnName("head_commit");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("path");
+
+ b.Property("State")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("active")
+ .HasColumnName("state");
+
+ b.HasKey("TaskId");
+
+ b.ToTable("worktrees", (string)null);
+ });
+
+ modelBuilder.Entity("list_tags", b =>
+ {
+ b.Property("list_id")
+ .HasColumnType("TEXT");
+
+ b.Property("tag_id")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("list_id", "tag_id");
+
+ b.HasIndex("tag_id");
+
+ b.ToTable("list_tags", (string)null);
+ });
+
+ modelBuilder.Entity("task_tags", b =>
+ {
+ b.Property("task_id")
+ .HasColumnType("TEXT");
+
+ b.Property("tag_id")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("task_id", "tag_id");
+
+ b.HasIndex("tag_id");
+
+ b.ToTable("task_tags", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
+ .WithOne("Config")
+ .HasForeignKey("ClaudeDo.Data.Models.ListConfigEntity", "ListId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("List");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithMany("Subtasks")
+ .HasForeignKey("TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
+ .WithMany("Tasks")
+ .HasForeignKey("ListId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("List");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithMany("Runs")
+ .HasForeignKey("TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithOne("Worktree")
+ .HasForeignKey("ClaudeDo.Data.Models.WorktreeEntity", "TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("list_tags", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", null)
+ .WithMany()
+ .HasForeignKey("list_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
+ .WithMany()
+ .HasForeignKey("tag_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("task_tags", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
+ .WithMany()
+ .HasForeignKey("tag_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
+ .WithMany()
+ .HasForeignKey("task_id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Navigation("Config");
+
+ b.Navigation("Tasks");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Navigation("Runs");
+
+ b.Navigation("Subtasks");
+
+ b.Navigation("Worktree");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/ClaudeDo.Data/Migrations/20260422120000_AddTaskSortOrder.Designer.cs b/src/ClaudeDo.Data/Migrations/20260422120000_AddTaskSortOrder.Designer.cs
new file mode 100644
index 0000000..5bf2020
--- /dev/null
+++ b/src/ClaudeDo.Data/Migrations/20260422120000_AddTaskSortOrder.Designer.cs
@@ -0,0 +1,581 @@
+//
+using System;
+using ClaudeDo.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace ClaudeDo.Data.Migrations
+{
+ [DbContext(typeof(ClaudeDoDbContext))]
+ [Migration("20260422120000_AddTaskSortOrder")]
+ partial class AddTaskSortOrder
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.AppSettingsEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("INTEGER")
+ .HasColumnName("id");
+
+ b.Property("CentralWorktreeRoot")
+ .HasColumnType("TEXT")
+ .HasColumnName("central_worktree_root");
+
+ b.Property("DefaultClaudeInstructions")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("")
+ .HasColumnName("default_claude_instructions");
+
+ b.Property("DefaultMaxTurns")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(30)
+ .HasColumnName("default_max_turns");
+
+ b.Property("DefaultModel")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("sonnet")
+ .HasColumnName("default_model");
+
+ b.Property("DefaultPermissionMode")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("bypassPermissions")
+ .HasColumnName("default_permission_mode");
+
+ b.Property("WorktreeAutoCleanupDays")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(7)
+ .HasColumnName("worktree_auto_cleanup_days");
+
+ b.Property("WorktreeAutoCleanupEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("worktree_auto_cleanup_enabled");
+
+ b.Property("WorktreeStrategy")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("sibling")
+ .HasColumnName("worktree_strategy");
+
+ b.HasKey("Id");
+
+ b.ToTable("app_settings", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = 1,
+ DefaultClaudeInstructions = "",
+ DefaultMaxTurns = 30,
+ DefaultModel = "sonnet",
+ DefaultPermissionMode = "bypassPermissions",
+ WorktreeAutoCleanupDays = 7,
+ WorktreeAutoCleanupEnabled = false,
+ WorktreeStrategy = "sibling"
+ });
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
+ {
+ b.Property("ListId")
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.HasKey("ListId");
+
+ b.ToTable("list_config", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("DefaultCommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("default_commit_type");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.Property("WorkingDir")
+ .HasColumnType("TEXT")
+ .HasColumnName("working_dir");
+
+ b.HasKey("Id");
+
+ b.ToTable("lists", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("Completed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("completed");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("OrderNum")
+ .HasColumnType("INTEGER")
+ .HasColumnName("order_num");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_subtasks_task_id");
+
+ b.ToTable("subtasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TagEntity", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasColumnName("id");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("tags", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = 1L,
+ Name = "agent"
+ },
+ new
+ {
+ Id = 2L,
+ Name = "manual"
+ });
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("CommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("commit_type");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("Description")
+ .HasColumnType("TEXT")
+ .HasColumnName("description");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("IsMyDay")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_my_day");
+
+ b.Property("IsStarred")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_starred");
+
+ b.Property("ListId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("list_id");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("Notes")
+ .HasColumnType("TEXT")
+ .HasColumnName("notes");
+
+ b.Property("Result")
+ .HasColumnType("TEXT")
+ .HasColumnName("result");
+
+ b.Property("ScheduledFor")
+ .HasColumnType("TEXT")
+ .HasColumnName("scheduled_for");
+
+ b.Property("SortOrder")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(0)
+ .HasColumnName("sort_order");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("status");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ListId")
+ .HasDatabaseName("idx_tasks_list_id");
+
+ b.HasIndex("Status")
+ .HasDatabaseName("idx_tasks_status");
+
+ b.HasIndex("ListId", "SortOrder")
+ .HasDatabaseName("idx_tasks_list_sort");
+
+ b.ToTable("tasks", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("ErrorMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("error_markdown");
+
+ b.Property("ExitCode")
+ .HasColumnType("INTEGER")
+ .HasColumnName("exit_code");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("IsRetry")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_retry");
+
+ b.Property("LogPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("log_path");
+
+ b.Property("Prompt")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("prompt");
+
+ b.Property("ResultMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("result_markdown");
+
+ b.Property("RunNumber")
+ .HasColumnType("INTEGER")
+ .HasColumnName("run_number");
+
+ b.Property("SessionId")
+ .HasColumnType("TEXT")
+ .HasColumnName("session_id");
+
+ b.Property("StartedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("started_at");
+
+ b.Property("StructuredOutputJson")
+ .HasColumnType("TEXT")
+ .HasColumnName("structured_output");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.Property("TokensIn")
+ .HasColumnType("INTEGER")
+ .HasColumnName("tokens_in");
+
+ b.Property