feat(data): add ImportTickets prime kind, ticket fallback list and import prompt
This commit is contained in:
@@ -81,6 +81,9 @@ public class AppSettingsEntityConfiguration : IEntityTypeConfiguration<AppSettin
|
||||
builder.Property(s => s.ListHandlerMaxHandoffs)
|
||||
.HasColumnName("list_handler_max_handoffs").IsRequired().HasDefaultValue(4);
|
||||
|
||||
builder.Property(s => s.TicketFallbackListId)
|
||||
.HasColumnName("ticket_fallback_list_id");
|
||||
|
||||
builder.HasData(new AppSettingsEntity { Id = AppSettingsEntity.SingletonId });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,14 @@ public class PrimeScheduleEntityConfiguration : IEntityTypeConfiguration<PrimeSc
|
||||
=> v == PrimeActionKind.Ping ? "ping"
|
||||
: v == PrimeActionKind.FillMyDay ? "fill_my_day"
|
||||
: v == PrimeActionKind.Custom ? "custom"
|
||||
: v == PrimeActionKind.ImportTickets ? "import_tickets"
|
||||
: throw new ArgumentOutOfRangeException(nameof(v));
|
||||
|
||||
private static PrimeActionKind KindFromString(string v)
|
||||
=> v == "ping" ? PrimeActionKind.Ping
|
||||
: v == "fill_my_day" ? PrimeActionKind.FillMyDay
|
||||
: v == "custom" ? PrimeActionKind.Custom
|
||||
: v == "import_tickets" ? PrimeActionKind.ImportTickets
|
||||
: throw new ArgumentOutOfRangeException(nameof(v));
|
||||
|
||||
private static readonly ValueConverter<PrimeActionKind, string> KindConverter =
|
||||
|
||||
+1160
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ClaudeDo.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddTicketFallbackList : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "ticket_fallback_list_id",
|
||||
table: "app_settings",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "app_settings",
|
||||
keyColumn: "id",
|
||||
keyValue: 1,
|
||||
column: "ticket_fallback_list_id",
|
||||
value: null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ticket_fallback_list_id",
|
||||
table: "app_settings");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,6 +132,10 @@ namespace ClaudeDo.Data.Migrations
|
||||
.HasDefaultValue(3)
|
||||
.HasColumnName("standup_weekday");
|
||||
|
||||
b.Property<string>("TicketFallbackListId")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("ticket_fallback_list_id");
|
||||
|
||||
b.Property<int>("UsageGateFiveHourPct")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER")
|
||||
|
||||
@@ -83,4 +83,8 @@ public sealed class AppSettingsEntity
|
||||
// 4 = two full wait/merge cycles, the long-standing default. Raise it for a run meant to keep
|
||||
// going for hours. It exists to bound runaway handoff loops, so it must stay >= 1.
|
||||
public int ListHandlerMaxHandoffs { get; set; } = 4;
|
||||
|
||||
// List that receives imported ticket items Claude could not place (import_ticket without a
|
||||
// list). Null = such items are skipped. No FK: a deleted list simply reads as unset at import.
|
||||
public string? TicketFallbackListId { get; set; }
|
||||
}
|
||||
|
||||
@@ -8,5 +8,7 @@ public enum PrimeActionKind
|
||||
/// <summary>Run the daily prep prompt and let Claude fill MyDay.</summary>
|
||||
FillMyDay,
|
||||
/// <summary>Run the schedule's own prompt with the ClaudeDo MCP tools available.</summary>
|
||||
Custom
|
||||
Custom,
|
||||
/// <summary>Import the assigned ticket-system items into lists by content, then fill MyDay.</summary>
|
||||
ImportTickets
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Text.RegularExpressions;
|
||||
|
||||
namespace ClaudeDo.Data;
|
||||
|
||||
public enum PromptKind { System, Planning, PlanningInitial, Retry, DailyPrep, WeeklyReport, ImprovementChild, Refine, MergeHelperTriage, MergeHelperWait, MergeHelperMerge, MergeHelperInitial, MergeHelperHandoff, PowerUseAddendum }
|
||||
public enum PromptKind { System, Planning, PlanningInitial, Retry, DailyPrep, WeeklyReport, ImprovementChild, Refine, MergeHelperTriage, MergeHelperWait, MergeHelperMerge, MergeHelperInitial, MergeHelperHandoff, PowerUseAddendum, TicketImport }
|
||||
|
||||
/// <summary>
|
||||
/// How a prompt kind's on-disk override (if any) relates to the bundled default.
|
||||
@@ -45,6 +45,7 @@ public static class PromptFiles
|
||||
PromptKind.MergeHelperInitial => "merge-helper-initial.md",
|
||||
PromptKind.MergeHelperHandoff => "merge-helper-handoff.md",
|
||||
PromptKind.PowerUseAddendum => "power-use.md",
|
||||
PromptKind.TicketImport => "ticket-import.md",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind))
|
||||
};
|
||||
|
||||
@@ -223,6 +224,7 @@ public static class PromptFiles
|
||||
PromptKind.MergeHelperInitial => MergeHelperInitialDefault,
|
||||
PromptKind.MergeHelperHandoff => MergeHelperHandoffDefault,
|
||||
PromptKind.PowerUseAddendum => PowerUseAddendumDefault,
|
||||
PromptKind.TicketImport => TicketImportDefault,
|
||||
_ => ""
|
||||
};
|
||||
|
||||
@@ -385,6 +387,22 @@ public static class PromptFiles
|
||||
(build + tests) before you stop.
|
||||
""";
|
||||
|
||||
private const string TicketImportDefault = """
|
||||
You are sorting my assigned items from the company ticket system into my ClaudeDo lists.
|
||||
|
||||
1. Call mcp__claudedo__get_ticket_import_candidates. If available is false, say why and stop.
|
||||
If items is empty, say so and stop.
|
||||
2. For every item, pick the list whose purpose fits the item's CONTENT — its title, its
|
||||
parent and its project. A list's ticketProject is only a hint: one ticket project can
|
||||
hold work for several repositories, and several lists can share one project.
|
||||
3. Import each item exactly once with mcp__claudedo__import_ticket(ticketId, list).
|
||||
If no list clearly fits, omit list — the item then goes to the fallback list.
|
||||
Never force a weak match just to avoid the fallback.
|
||||
4. Do not create, edit or move anything else.
|
||||
5. Finish with a short summary: imported items per list, items that went to the fallback
|
||||
list, and skipped items with their reason.
|
||||
""";
|
||||
|
||||
private const string DailyPrepDefault = """
|
||||
You are preparing my workday for {date}.
|
||||
|
||||
|
||||
@@ -127,4 +127,12 @@ public sealed class AppSettingsRepository
|
||||
row.RepoImportFolders = list.Count == 0 ? null : JsonSerializer.Serialize(list);
|
||||
await _context.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
/// <summary>Writes only the ticket fallback list; blank clears it.</summary>
|
||||
public async Task SetTicketFallbackListIdAsync(string? listId, CancellationToken ct = default)
|
||||
{
|
||||
var row = await GetOrCreateTrackedRowAsync(ct);
|
||||
row.TicketFallbackListId = string.IsNullOrWhiteSpace(listId) ? null : listId.Trim();
|
||||
await _context.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user