internal static partial class Program { static FragmentService NewService() { IFragmentRepository repo = new InMemoryFragmentRepository(); return new FragmentService(repo); } static Entry NewEntry() { var dbService = new JournalDatabaseService(new JournalConfigService()); var session = new DatabaseSessionService(dbService); return new Entry( NewService(), new EntrySearchService(), new VaultStorageService(new VaultCryptoService()), dbService, session, new JournalConfigService(), new DisabledAiService("none"), new DisabledSpeechBridgeService("none"), new EntryFileService(new DiskEntryFileRepository()), new ListService(new SqliteListRepository(session)), new TodoService(new SqliteTodoRepository(session)), new CommandLogger()); } static IJournalDatabaseService NewDatabaseService() => new JournalDatabaseService(new JournalConfigService()); static Dictionary ReadVaultEntryTexts(string vaultPath, string password) { var crypto = new VaultCryptoService(); var encrypted = File.ReadAllBytes(vaultPath); var zipBytes = crypto.DecryptData(encrypted, password); using var stream = new MemoryStream(zipBytes); using var archive = new ZipArchive(stream, ZipArchiveMode.Read); var result = new Dictionary(StringComparer.Ordinal); foreach (var entry in archive.Entries) { if (string.IsNullOrEmpty(entry.Name)) continue; using var reader = new StreamReader(entry.Open()); result[entry.Name] = reader.ReadToEnd(); } return result; } static byte[] CreateZipBytes(Dictionary files) { using var stream = new MemoryStream(); using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true)) { foreach (var (name, content) in files) { var entry = archive.CreateEntry(name); using var writer = new StreamWriter(entry.Open()); writer.Write(content); } } return stream.ToArray(); } static void WriteSearchFixtureFiles(string root) { File.WriteAllText(Path.Combine(root, "2026-02-01.md"), """ Date: 2026-02-01 ## Summary Alpha common ## Reflection focus area - [x] med taken !TRIGGER #stress fragment one """); File.WriteAllText(Path.Combine(root, "2026-02-05.md"), """ Date: 2026-02-05 ## Summary Beta common ## Reflection other notes - [ ] drink water !NOTE #daily fragment two """); File.WriteAllText(Path.Combine(root, "2026-03-01.md"), """ Date: 2026-03-01 ## Summary Gamma unique ## Reflection nothing related !NOTE #other fragment three """); } static (int ExitCode, string Stdout, string Stderr) CaptureConsole(Func action) { var originalOut = Console.Out; var originalError = Console.Error; using var stdout = new StringWriter(); using var stderr = new StringWriter(); try { Console.SetOut(stdout); Console.SetError(stderr); var exitCode = action(); return (exitCode, stdout.ToString(), stderr.ToString()); } finally { Console.SetOut(originalOut); Console.SetError(originalError); } } static JournalConfig BuildAiConfig(string sidecarScriptPath, int timeoutMs) { var baseConfig = new JournalConfigService().Current; var pythonExe = Environment.GetEnvironmentVariable("JOURNAL_PYTHON_EXE"); if (string.IsNullOrWhiteSpace(pythonExe)) pythonExe = "python"; return baseConfig with { AiProvider = "python-sidecar", PythonExecutable = pythonExe, PythonAiSidecarPath = sidecarScriptPath, AiSidecarTimeoutMs = timeoutMs }; } static async Task> LoadTransportFixturesAsync() { var path = Path.Combine(AppContext.BaseDirectory, "Fixtures", "transport_cases.json"); if (!File.Exists(path)) throw new FileNotFoundException($"Transport fixture file not found: {path}"); var json = await File.ReadAllTextAsync(path); return JsonSerializer.Deserialize>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? []; } static JsonValueKind ParseValueKind(string value) => value.Trim().ToLowerInvariant() switch { "array" => JsonValueKind.Array, "object" => JsonValueKind.Object, "null" => JsonValueKind.Null, "string" => JsonValueKind.String, "number" => JsonValueKind.Number, "true" => JsonValueKind.True, "false" => JsonValueKind.False, _ => throw new InvalidOperationException($"Unsupported JsonValueKind '{value}' in transport fixture.") }; static void Assert(bool condition, string message) { if (!condition) throw new InvalidOperationException(message); } }