icon.ico is a WPF <Resource> embedded in the assembly, but the code
loaded it from the filesystem (AppContext.BaseDirectory) where no copy
exists -> FileNotFoundException, silently swallowed by the catch -> blank
tray icon. Load via pack:// resource stream instead. Also log the failure
to Debug output instead of swallowing it silently.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A message sent yesterday but processed today (e.g. by the next service
run) landed in today's daily note. The send time was captured in
received_at but only HH:MM reached the LLM; the date defaulted to
date.today(). Now today/weekday in the processor context are derived per
item from received_at, so "gestern"/"heute" resolve relative to when the
message was actually written. Adds day_context() helper and a regression
test (sent 2026-06-25, processed 2026-06-26 -> note 2026-06-25).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two thin .NET 10 shells around the Python CLI (tools/JournalBot.slnx):
- JournalBot.Service: Windows Service (LocalSystem), PeriodicTimer runs
`journal_bot ingest` every 15 min, logs to runtime/logs/service.log.
- JournalBot.Tray: WPF tray app, status banner + Historie/Log tabs +
Ingest/Process/Both buttons; runs `process` (needs user-session LM Studio).
- JournalBot.Shared: QueueItem DTO, BotRunner (subprocess, kills tree on
cancel), RuntimeReader (history/status/log); 7 xUnit tests.
Python side: QueueItem gains optional result fields (target_path,
written_entry, processed_at); complete() rewrites JSON atomically;
process_once records them so the GUI can show what was written where.
Install via scripts/{build-tools,install-service,install-tray}.ps1;
replaces the old install-task.ps1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>