2026-04-05 Session: Add Planet AI Chat with sessions and sparkles button

What was done

  • Added a sparkles button to the main sidebar toolbar that opens a global Planet AI Chat window
  • Parameterized ArticleAIChatView to support both per-article and planet-wide modes
  • Created PlanetAIChatWindowController with NSSplitViewController for session sidebar
  • Refactored ArticleAIChatWindowManager to use NSWindowController + NSToolbar
  • Added AIChatToolbarState for AppKit/SwiftUI toolbar state synchronization
  • Implemented session management with persistence, migration from legacy chat file, and session title auto-naming
  • Fixed chat windows staying open when clicking article links (previously closed unexpectedly)
  • Iterated on window chrome: transparent titlebar, fullSizeContentView, unified compact toolbar style

Key decisions

  • Parameterized existing ArticleAIChatView instead of duplicating 5000+ lines — all tools (search_articles, list_planet_articles, read_article) already work cross-planet
  • Used NSSplitViewController for sessions sidebar rather than SwiftUI tabs — matches the app's existing window controller patterns
  • Planet-wide system prompt emphasizes using search_articles and list_planet_articles to discover content across all planets
  • Session titles auto-generate from first user message (truncated to 40 chars)

Files changed

  • Planet/Views/Articles/ArticleAIChatView.swift — replaced @ObservedObject article with optional articleRef, added planet-wide mode, session ID, toolbar state sync, planet summary context, sending animation
  • Planet/Views/Articles/PlanetAIChatWindowController.swift — new: NSWindowController with NSSplitViewController, NSToolbar, AIChatToolbarState, AIChatProviderToolbarItem
  • Planet/Views/Articles/PlanetAIChatSessionsView.swift — new: session model, PlanetAIChatSessionStore, sidebar/content views, environment key
  • Planet/Views/Articles/ArticleAIChatWindowManager.swift — refactored to use NSWindowController + NSToolbar pattern
  • Planet/Views/Articles/ArticleAIOnDeviceTools.swift — made articleID optional in OnDeviceToolContext and factory
  • Planet/Views/Articles/ChatInputField.swift — added configurable placeholder parameter
  • Planet/Views/Sidebar/PlanetSidebarView.swift — added sparkles toolbar button with AI readiness checks
  • Planet/PlanetAppDelegate.swift — added openPlanetAIChatWindow() and planetAIChatWindowController
  • Planet/Helper/Extensions.swift — added settingsAILastChatSessionID key