diff --git a/src/ClaudeDo.Data/Migrations/20260825063230_AddPrimeActionKind.Designer.cs b/src/ClaudeDo.Data/Migrations/20260825063230_AddPrimeActionKind.Designer.cs
new file mode 100644
index 00000000..119a4524
--- /dev/null
+++ b/src/ClaudeDo.Data/Migrations/20260825063230_AddPrimeActionKind.Designer.cs
@@ -0,0 +1,968 @@
+//
+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("20260825063230_AddPrimeActionKind")]
+ partial class AddPrimeActionKind
+ {
+ ///
+ 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("AutoContinueOnUsageLimit")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("auto_continue_on_usage_limit");
+
+ b.Property("CentralWorktreeRoot")
+ .HasColumnType("TEXT")
+ .HasColumnName("central_worktree_root");
+
+ b.Property("DailyPrepMaxTasks")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(5)
+ .HasColumnName("daily_prep_max_tasks");
+
+ b.Property("DefaultClaudeInstructions")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("")
+ .HasColumnName("default_claude_instructions");
+
+ b.Property("DefaultMaxTurns")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(40)
+ .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("MaxParallelExecutions")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(1)
+ .HasColumnName("max_parallel_executions");
+
+ b.Property("MaxTurnsCeiling")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(80)
+ .HasColumnName("max_turns_ceiling");
+
+ b.Property("ModelPresets")
+ .HasColumnType("TEXT")
+ .HasColumnName("model_presets");
+
+ b.Property("NextTaskNumber")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(1)
+ .HasColumnName("next_task_number");
+
+ b.Property("RepoImportFolders")
+ .HasColumnType("TEXT")
+ .HasColumnName("repo_import_folders");
+
+ b.Property("ReportExcludedPaths")
+ .HasColumnType("TEXT")
+ .HasColumnName("report_excluded_paths");
+
+ b.Property("SessionSkills")
+ .HasColumnType("TEXT")
+ .HasColumnName("session_skills");
+
+ b.Property("StandupWeekday")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(3)
+ .HasColumnName("standup_weekday");
+
+ b.Property("UsageGateFiveHourPct")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(80)
+ .HasColumnName("usage_gate_five_hour_pct");
+
+ b.Property("UsageGateSevenDayPct")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(90)
+ .HasColumnName("usage_gate_seven_day_pct");
+
+ b.Property("UsageThrottleFiveHourHardPct")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(65)
+ .HasColumnName("usage_throttle_five_hour_hard_pct");
+
+ b.Property("UsageThrottleFiveHourSoftPct")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(50)
+ .HasColumnName("usage_throttle_five_hour_soft_pct");
+
+ b.Property("UsageThrottleSevenDayHardPct")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(65)
+ .HasColumnName("usage_throttle_seven_day_hard_pct");
+
+ b.Property("UsageThrottleSevenDaySoftPct")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(50)
+ .HasColumnName("usage_throttle_seven_day_soft_pct");
+
+ 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,
+ AutoContinueOnUsageLimit = false,
+ DailyPrepMaxTasks = 5,
+ DefaultClaudeInstructions = "",
+ DefaultMaxTurns = 40,
+ DefaultModel = "sonnet",
+ DefaultPermissionMode = "auto",
+ MaxParallelExecutions = 1,
+ MaxTurnsCeiling = 80,
+ NextTaskNumber = 1,
+ StandupWeekday = 3,
+ UsageGateFiveHourPct = 80,
+ UsageGateSevenDayPct = 90,
+ UsageThrottleFiveHourHardPct = 65,
+ UsageThrottleFiveHourSoftPct = 50,
+ UsageThrottleSevenDayHardPct = 65,
+ UsageThrottleSevenDaySoftPct = 50,
+ WorktreeAutoCleanupDays = 7,
+ WorktreeAutoCleanupEnabled = false,
+ WorktreeStrategy = "sibling"
+ });
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.DailyNoteEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("Date")
+ .HasColumnType("TEXT")
+ .HasColumnName("note_date");
+
+ b.Property("SortOrder")
+ .HasColumnType("INTEGER")
+ .HasColumnName("sort_order");
+
+ b.Property("Text")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Date");
+
+ b.ToTable("daily_notes", (string)null);
+ });
+
+ 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("MaxTurns")
+ .HasColumnType("INTEGER")
+ .HasColumnName("max_turns");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("SerializeOnFileOverlap")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("serialize_on_file_overlap");
+
+ b.Property("SessionSkills")
+ .HasColumnType("TEXT")
+ .HasColumnName("session_skills");
+
+ b.Property("SystemPrompt")
+ .HasColumnType("TEXT")
+ .HasColumnName("system_prompt");
+
+ b.Property("VerifyCommand")
+ .HasColumnType("TEXT")
+ .HasColumnName("verify_command");
+
+ 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("FindingsTracked")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("findings_tracked");
+
+ b.Property("IsManual")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_manual");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.Property("SortOrder")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(0)
+ .HasColumnName("sort_order");
+
+ b.Property("WorkingDir")
+ .HasColumnType("TEXT")
+ .HasColumnName("working_dir");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SortOrder")
+ .HasDatabaseName("idx_lists_sort");
+
+ b.ToTable("lists", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.PrimeScheduleEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("Days")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(31)
+ .HasColumnName("days_of_week");
+
+ b.Property("Enabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(true)
+ .HasColumnName("enabled");
+
+ b.Property("Kind")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("ping")
+ .HasColumnName("action_kind");
+
+ b.Property("LastRunAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("last_run_at");
+
+ b.Property("PromptOverride")
+ .HasColumnType("TEXT")
+ .HasColumnName("prompt_override");
+
+ b.Property("TimeOfDay")
+ .HasColumnType("TEXT")
+ .HasColumnName("time_of_day");
+
+ b.HasKey("Id");
+
+ b.ToTable("prime_schedules", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.SessionSkillEntity", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("TEXT")
+ .HasColumnName("name");
+
+ b.Property("AddedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("added_at");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("description");
+
+ b.Property("PinnedRef")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("pinned_ref");
+
+ b.Property("SourceUrl")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("source_url");
+
+ b.Property("Subpath")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("subpath");
+
+ b.HasKey("Name");
+
+ b.ToTable("session_skills", (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.TaskAttachmentEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("ByteSize")
+ .HasColumnType("INTEGER")
+ .HasColumnName("byte_size");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("FileName")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("file_name");
+
+ b.Property("TaskId")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("task_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TaskId")
+ .HasDatabaseName("idx_task_attachments_task_id");
+
+ b.ToTable("task_attachments", (string)null);
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("AgentPath")
+ .HasColumnType("TEXT")
+ .HasColumnName("agent_path");
+
+ b.Property("BlockedByTaskId")
+ .HasColumnType("TEXT")
+ .HasColumnName("blocked_by_task_id");
+
+ b.Property("CommitType")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("chore")
+ .HasColumnName("commit_type");
+
+ b.Property("CreatedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_at");
+
+ b.Property("CreatedBy")
+ .HasColumnType("TEXT")
+ .HasColumnName("created_by");
+
+ b.Property("DependsOnTaskId")
+ .HasColumnType("TEXT")
+ .HasColumnName("depends_on_task_id");
+
+ b.Property("Description")
+ .HasColumnType("TEXT")
+ .HasColumnName("description");
+
+ b.Property("FailureMaxTurns")
+ .HasColumnType("INTEGER")
+ .HasColumnName("failure_max_turns");
+
+ b.Property("FailureReason")
+ .HasColumnType("TEXT")
+ .HasColumnName("failure_reason");
+
+ b.Property("FailureTurnsUsed")
+ .HasColumnType("INTEGER")
+ .HasColumnName("failure_turns_used");
+
+ b.Property("FinishedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("finished_at");
+
+ b.Property("HandlerBaseCommit")
+ .HasColumnType("TEXT")
+ .HasColumnName("handler_base_commit");
+
+ b.Property("HandlerHeadCommit")
+ .HasColumnType("TEXT")
+ .HasColumnName("handler_head_commit");
+
+ b.Property("InteractiveSessionId")
+ .HasColumnType("TEXT")
+ .HasColumnName("interactive_session_id");
+
+ b.Property("IsManual")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(false)
+ .HasColumnName("is_manual");
+
+ 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("MaxTurns")
+ .HasColumnType("INTEGER")
+ .HasColumnName("max_turns");
+
+ b.Property("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("Notes")
+ .HasColumnType("TEXT")
+ .HasColumnName("notes");
+
+ b.Property("Number")
+ .HasColumnType("INTEGER")
+ .HasColumnName("number");
+
+ b.Property("ParentTaskId")
+ .HasColumnType("TEXT")
+ .HasColumnName("parent_task_id");
+
+ b.Property("PlanningFinalizedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("planning_finalized_at");
+
+ b.Property("PlanningPhase")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("none")
+ .HasColumnName("planning_phase");
+
+ b.Property("PlanningSessionId")
+ .HasColumnType("TEXT")
+ .HasColumnName("planning_session_id");
+
+ b.Property("PlanningSessionToken")
+ .HasColumnType("TEXT")
+ .HasColumnName("planning_session_token");
+
+ b.Property("Result")
+ .HasColumnType("TEXT")
+ .HasColumnName("result");
+
+ b.Property("ReviewFeedback")
+ .HasColumnType("TEXT")
+ .HasColumnName("review_feedback");
+
+ b.Property("RoadblockCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(0)
+ .HasColumnName("roadblock_count");
+
+ b.Property("ScheduledFor")
+ .HasColumnType("TEXT")
+ .HasColumnName("scheduled_for");
+
+ b.Property("ScopeGlobs")
+ .HasColumnType("TEXT")
+ .HasColumnName("scope_globs");
+
+ b.Property("SessionSkills")
+ .HasColumnType("TEXT")
+ .HasColumnName("session_skills");
+
+ 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.Property("UsageLimitAutoContinuedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("usage_limit_auto_continued_at");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BlockedByTaskId")
+ .HasDatabaseName("idx_tasks_blocked_by");
+
+ b.HasIndex("DependsOnTaskId")
+ .HasDatabaseName("idx_tasks_depends_on");
+
+ b.HasIndex("ListId")
+ .HasDatabaseName("idx_tasks_list_id");
+
+ b.HasIndex("Number")
+ .IsUnique()
+ .HasDatabaseName("idx_tasks_number");
+
+ b.HasIndex("ParentTaskId")
+ .HasDatabaseName("idx_tasks_parent_task_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("CacheReadTokens")
+ .HasColumnType("INTEGER")
+ .HasColumnName("cache_read_tokens");
+
+ b.Property("CacheWriteTokens")
+ .HasColumnType("INTEGER")
+ .HasColumnName("cache_write_tokens");
+
+ b.Property("ErrorMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("error_markdown");
+
+ b.Property("Errors")
+ .HasColumnType("TEXT")
+ .HasColumnName("errors");
+
+ 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("Model")
+ .HasColumnType("TEXT")
+ .HasColumnName("model");
+
+ b.Property("Prompt")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("prompt");
+
+ b.Property("ResultMarkdown")
+ .HasColumnType("TEXT")
+ .HasColumnName("result_markdown");
+
+ b.Property("ResultSubtype")
+ .HasColumnType("TEXT")
+ .HasColumnName("result_subtype");
+
+ 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("TerminalReason")
+ .HasColumnType("TEXT")
+ .HasColumnName("terminal_reason");
+
+ 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.WeekReportEntity", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT")
+ .HasColumnName("id");
+
+ b.Property("EndDate")
+ .HasColumnType("TEXT")
+ .HasColumnName("end_date");
+
+ b.Property("GeneratedAt")
+ .HasColumnType("TEXT")
+ .HasColumnName("generated_at");
+
+ b.Property("Markdown")
+ .IsRequired()
+ .HasColumnType("TEXT")
+ .HasColumnName("markdown");
+
+ b.Property("StartDate")
+ .HasColumnType("TEXT")
+ .HasColumnName("start_date");
+
+ b.HasKey("Id");
+
+ b.HasIndex("StartDate", "EndDate")
+ .IsUnique();
+
+ b.ToTable("week_reports", (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("MergeCommit")
+ .HasColumnType("TEXT")
+ .HasColumnName("merge_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("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.TaskAttachmentEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
+ .WithMany()
+ .HasForeignKey("TaskId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Task");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
+ .WithMany()
+ .HasForeignKey("BlockedByTaskId")
+ .OnDelete(DeleteBehavior.SetNull);
+
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
+ .WithMany()
+ .HasForeignKey("DependsOnTaskId")
+ .OnDelete(DeleteBehavior.SetNull);
+
+ b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
+ .WithMany("Tasks")
+ .HasForeignKey("ListId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Parent")
+ .WithMany("Children")
+ .HasForeignKey("ParentTaskId")
+ .OnDelete(DeleteBehavior.Restrict);
+
+ b.Navigation("List");
+
+ b.Navigation("Parent");
+ });
+
+ 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("ClaudeDo.Data.Models.ListEntity", b =>
+ {
+ b.Navigation("Config");
+
+ b.Navigation("Tasks");
+ });
+
+ modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
+ {
+ b.Navigation("Children");
+
+ b.Navigation("Runs");
+
+ b.Navigation("Subtasks");
+
+ b.Navigation("Worktree");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/ClaudeDo.Data/Migrations/20260825063230_AddPrimeActionKind.cs b/src/ClaudeDo.Data/Migrations/20260825063230_AddPrimeActionKind.cs
new file mode 100644
index 00000000..467bd2e3
--- /dev/null
+++ b/src/ClaudeDo.Data/Migrations/20260825063230_AddPrimeActionKind.cs
@@ -0,0 +1,29 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace ClaudeDo.Data.Migrations
+{
+ ///
+ public partial class AddPrimeActionKind : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "action_kind",
+ table: "prime_schedules",
+ type: "TEXT",
+ nullable: false,
+ defaultValue: "ping");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "action_kind",
+ table: "prime_schedules");
+ }
+ }
+}
diff --git a/src/ClaudeDo.Data/Migrations/ClaudeDoDbContextModelSnapshot.cs b/src/ClaudeDo.Data/Migrations/ClaudeDoDbContextModelSnapshot.cs
index 43e03444..e911bab8 100644
--- a/src/ClaudeDo.Data/Migrations/ClaudeDoDbContextModelSnapshot.cs
+++ b/src/ClaudeDo.Data/Migrations/ClaudeDoDbContextModelSnapshot.cs
@@ -336,6 +336,13 @@ namespace ClaudeDo.Data.Migrations
.HasDefaultValue(true)
.HasColumnName("enabled");
+ b.Property("Kind")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT")
+ .HasDefaultValue("ping")
+ .HasColumnName("action_kind");
+
b.Property("LastRunAt")
.HasColumnType("TEXT")
.HasColumnName("last_run_at");