touchCacheEntry() now returns a new object via spread instead of mutating
the entry in-place. CacheManager.replaceCards() likewise creates a new entry
object instead of mutating existing fields. Update tests to assert the new
immutable semantics (returned value differs from input by reference).
https://claude.ai/code/session_016QvEfqw6YZ3RjwBHrJ4w8S
Reject '..' and '.' segments in normalizeVaultPath to prevent
exportFolder from escaping the vault root directory.
Change-Id: Ib4da19f9d0aa1236a3b77b6f2cc722fcff408131
Implement SSE streaming for API backends that support it (OpenAI Chat
Completions and Anthropic Messages). During generation the view shows
a live streaming preview with accumulated text. Adds a streaming toggle
in settings (enabled by default). Non-streaming-capable formats (Gemini,
OpenAI Responses) and CLI backends continue using the existing path.
Change-Id: I3361a5ca5aec3e25a7d16e4fb585185f6fc0695e