feat(report): write weekly report as short bullets with haiku
This commit is contained in:
@@ -697,20 +697,21 @@ public static class PromptFiles
|
||||
""";
|
||||
|
||||
private const string WeeklyReportDefault = """
|
||||
You are generating a concise weekly standup report for a software developer,
|
||||
covering {start} to {end}.
|
||||
You are writing memory-jogger notes for a developer's weekly standup,
|
||||
covering {start} to {end}. They read them aloud in their own words, so write
|
||||
keywords, not sentences.
|
||||
|
||||
Rules:
|
||||
- Write the ENTIRE report in German.
|
||||
- Group by day. One "## <Wochentag>, <dd.MM.yyyy>" section per day that has
|
||||
- Write in German.
|
||||
- Group by day. One "## <Wochentag>, <dd.MM.>" heading per day that has
|
||||
activity (German weekday names). Omit days with no activity.
|
||||
- Within each day: 3–5 first-person, past-tense bullets ("- Habe X umgesetzt",
|
||||
"- Y behoben"). Merge related small work into one bullet.
|
||||
- Drop trivia: typo fixes, pure exploration, false starts, tooling/log noise.
|
||||
- Blend the developer's own notes and the derived activity into ONE deduplicated
|
||||
bullet list per day. The notes are authoritative — never omit or contradict them.
|
||||
- Name the project/repo when it adds clarity.
|
||||
- Output ONLY the dated sections. No preamble, no intro, no closing remarks.
|
||||
- Per day: 1–3 bullets, each at most ~6 words, noun style
|
||||
("- LagerApp: Etikettendruck gefixt", "- ClaudeDo Listen-Ordner"). No "Habe …".
|
||||
- One bullet per topic — merge everything about the same feature/bug.
|
||||
- Drop trivia: typo fixes, exploration, false starts, tooling/log noise.
|
||||
- Merge the developer's notes with the derived activity, deduplicated.
|
||||
The notes are authoritative — never omit or contradict them.
|
||||
- Output ONLY the day sections. No preamble, no summary, no closing remarks.
|
||||
|
||||
Two sections follow below: an activity log derived from Claude session history,
|
||||
and the developer's own notes. Base the report on both; the notes are
|
||||
|
||||
@@ -40,14 +40,12 @@ public sealed class WeekReportService
|
||||
public async Task<string> GenerateAsync(DateOnly start, DateOnly end, CancellationToken ct = default)
|
||||
{
|
||||
string[] excludes;
|
||||
string model;
|
||||
IReadOnlyList<Data.Models.DailyNoteEntity> noteRows;
|
||||
|
||||
await using (var ctx = await _dbFactory.CreateDbContextAsync(ct))
|
||||
{
|
||||
var settings = await new AppSettingsRepository(ctx).GetAsync(ct);
|
||||
excludes = ParseExcludes(settings.ReportExcludedPaths);
|
||||
model = string.IsNullOrWhiteSpace(settings.DefaultModel) ? "sonnet" : settings.DefaultModel;
|
||||
noteRows = await new DailyNoteRepository(ctx).ListBetweenAsync(start, end, ct);
|
||||
}
|
||||
|
||||
@@ -65,15 +63,13 @@ public sealed class WeekReportService
|
||||
else
|
||||
{
|
||||
var prompt = WeekReportPromptBuilder.Build(start, end, activity, notesByDay);
|
||||
// Guard against argument injection via the model setting: model aliases/ids are
|
||||
// alphanumerics, dashes and dots only.
|
||||
var safeModel = new string(model.Where(c => char.IsLetterOrDigit(c) || c is '-' or '.').ToArray());
|
||||
if (safeModel.Length == 0) safeModel = "sonnet";
|
||||
// Summarising notes into bullets doesn't need the user's default model.
|
||||
const string model = "haiku";
|
||||
IReadOnlyList<string> args =
|
||||
[
|
||||
"-p", "--output-format", "stream-json", "--verbose",
|
||||
"--permission-mode", PermissionModeResolver.Resolve(safeModel, "auto"),
|
||||
"--model", safeModel,
|
||||
"--permission-mode", PermissionModeResolver.Resolve(model, "auto"),
|
||||
"--model", model,
|
||||
];
|
||||
var result = await _claude.RunAsync(args, prompt, Path.GetTempPath(), _ => Task.CompletedTask, ct);
|
||||
if (!result.IsSuccess)
|
||||
|
||||
Reference in New Issue
Block a user