feat(prompts): add editable system/planning/agent prompt files
Introduces ~/.todo-app/prompts/{system,planning,agent}.md as the canonical
location for prompt content. The settings modal exposes "Open in editor"
shortcuts for each, and TaskRunner merges system.md (always) and agent.md
(for "agent"-tagged tasks) into the effective system prompt alongside the
existing global/list/task layers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -404,14 +404,22 @@ public sealed class TaskRunner
|
||||
TaskEntity task, ListConfigEntity? listConfig, string? resumeSessionId, CancellationToken ct)
|
||||
{
|
||||
AppSettingsEntity global;
|
||||
bool isAgentTask;
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
{
|
||||
var settingsRepo = new AppSettingsRepository(ctx);
|
||||
global = await settingsRepo.GetAsync(ct);
|
||||
|
||||
var taskRepo = new TaskRepository(ctx);
|
||||
var tags = await taskRepo.GetEffectiveTagsAsync(task.Id, ct);
|
||||
isAgentTask = tags.Any(t => string.Equals(t.Name, "agent", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
var systemFile = PromptFiles.ReadOrNull(PromptKind.System);
|
||||
var agentFile = isAgentTask ? PromptFiles.ReadOrNull(PromptKind.Agent) : null;
|
||||
|
||||
var instructions = MergeInstructions(
|
||||
global.DefaultClaudeInstructions, listConfig?.SystemPrompt, task.SystemPrompt);
|
||||
systemFile, global.DefaultClaudeInstructions, listConfig?.SystemPrompt, task.SystemPrompt, agentFile);
|
||||
|
||||
return new ClaudeRunConfig(
|
||||
Model: task.Model ?? listConfig?.Model ?? global.DefaultModel,
|
||||
@@ -422,12 +430,11 @@ public sealed class TaskRunner
|
||||
PermissionMode: global.DefaultPermissionMode);
|
||||
}
|
||||
|
||||
public static string MergeInstructions(string? global, string? list, string? task)
|
||||
public static string MergeInstructions(params string?[] parts)
|
||||
{
|
||||
var parts = new List<string>(3);
|
||||
if (!string.IsNullOrWhiteSpace(global)) parts.Add(global.Trim());
|
||||
if (!string.IsNullOrWhiteSpace(list)) parts.Add(list.Trim());
|
||||
if (!string.IsNullOrWhiteSpace(task)) parts.Add(task.Trim());
|
||||
return string.Join("\n\n", parts);
|
||||
var trimmed = parts
|
||||
.Where(p => !string.IsNullOrWhiteSpace(p))
|
||||
.Select(p => p!.Trim());
|
||||
return string.Join("\n\n", trimmed);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user