- Detect plantuml/mermaid code fences and render as diagrams
- PlantUML: POST to localhost:8080/svg for SVG output
- Mermaid: GET to localhost:8081/img/ with base64 for JPEG output
(SVG not usable - Qt doesn't support foreignObject)
- Cache rendered diagrams by content hash
- Toggle between source code and rendered image view
- Copy button for source text or image data
- Fall back to source display on render errors
- Add ClipboardHelper for image clipboard support
- Clear diagram cache on session reset
- Rewrite README.md with accurate 9P-based architecture
- Remove all D-Bus dependencies:
- Update dolphin/ollie-ask to use ollie-9p rdwr generate
- Update kate/ollie_ghost.cpp to use ollie-9p rdwr complete
- Remove QDBusInterface from ollie_ghost.h
- Fix OllieGhostProvider constructor in ollie_kate.cpp
- Remove D-Bus comments from gui/main.cpp and kate/ollie_kate.cpp
- Remove QtDBus from CMakeLists.txt (KF5 and KF6)
- Delete D-Bus test scripts test-e2e.sh and test-peers.sh
- Clarify no system tray component exists
- Update build/install instructions with just commands
The C++ connection mapping activeSessionIdChanged to chatModel->reset()
raced against the QML onActiveSessionIdChanged handler which does the
actual reload (reset → readLogForSession → appendData → trimFront).
When the C++ slot fired after the QML handler, it cleared the freshly
loaded chat data.
Remove the redundant C++ connection — the QML handler owns the full
reset+reload sequence and sequences the 9P log read correctly.
Kill the entire D-Bus rendering pipeline. The GUI now uses plan9port's
9p command as a subprocess for all server communication:
- Chat streaming: persistent 'read chat' process, readyReadStandardOutput
delivers tokens directly to QML (no polling, no signals, no offsets)
- State: 'read statewait' process, restarts on each state change
- Session list: 'read session/idx' one-shot
- Submit/stop/kill: 'write prompt/ctl' one-shot
The QML is stripped to fundamentals: session list + monospace streaming
text (last 8KB tail) + input field. No ChatBlockModel, no ThemeManager,
no OllieDBusClient, no syntax highlighting, no markdown rendering.
This eliminates the multi-second GUI freezes caused by:
- QTextDocument relayout on 200KB+ accumulated text
- loadEarlier cascade creating hundreds of delegates
- KSyntaxHighlighting::Repository blocking init
- Offset mismatch triggering synchronous D-Bus calls
Features will be re-added incrementally on this proven foundation.
D-Bus retained only for plasmoid/tray/KRunner (desktop integration).
- Expose GuiActivator as "activator" context property
- Add Ctrl+N shortcut to open a new window (both KF5 and KF6)
- Add per-session draft text persistence to main-kf5.qml
(KF6 ChatPane.qml already had this from previous commit)
Running ollie-gui a second time now opens a new window in the
existing process (via NewWindow D-Bus method) instead of just
raising the existing window. The single-instance guard remains.
Each window gets its own ChatBlockModel via QML instantiation
(ChatPane.qml), so windows can display independent sessions.
Full split-pane implementation:
- Ctrl+\ splits focused pane (BSP tree layout, alternating h/v)
- Ctrl+W closes focused pane (collapses parent split)
- Sloppy focus: pane focuses when mouse stops moving (100ms)
- Drag header to another pane to swap sessions
- Multi-line TextArea prompt with emoji shortcode completion
- Each pane has own ChatBlockModel and D-Bus signal filtering
- Auto-relayout on window resize
Major refactor: extracted chat UI into ChatPane.qml (self-contained
with own ChatBlockModel, D-Bus signal filtering, prompt input).
Main content area is now a SplitView with dynamic pane creation.
Auto-layout: splits horizontal if window wider than tall.
Sidebar click updates the focused pane session.
New OllieDBusClient methods: getChat, getConfig, getState (per-session).
New signal: chatAppended (emitted for all sessions, not just active).
- Add configurable close-to-tray (Settings > System Tray)
- QSystemTrayIcon with show/hide toggle and quit action
- closeToTray property persisted in theme.conf
- Window hides instead of quitting when enabled
- Fix session rename being interrupted by state changes
- onStateChanged no longer calls refreshSessions()
- State updates in-place via sessionStateUpdated signal
- Delegates track state locally, preserving rename TextField
Replace flat TextArea chat view with structured ListView:
- ChatBlockModel parses raw chat text into typed blocks (user,
assistant, reasoning, call, tool, error, info)
- Sub-blocks parsed from markdown: prose, fenced code, diffs
- Code blocks rendered with KSyntaxHighlighting (auto light/dark theme)
- Diff blocks with red/green line coloring
- Copy button on code and diff blocks
- File paths linkified and clickable (opens with xdg-open)
- Reasoning/call/tool blocks collapsible (click to expand)
- User blocks highlighted with subtle accent background
- Error blocks in red
- Scroll pinning preserved (auto-scroll when at bottom)
- Remove placeholderText from QML palette block (not available in Qt5)
- Use theme.placeholderTextColor directly instead of palette.placeholderText
- Add Qt version guards for QFontDatabase static vs instance API
- Add Qt version guard for QVariant::typeId vs QVariant::type
- Link KF5::ConfigCore for ollie-gui KF5 build
Installs ollie.svg to hicolor scalable apps and org.ollie.gui.desktop
to /usr/share/applications. Sets desktopFileName so Plasma can match
the running window to the .desktop entry when pinned.
Session list with create/kill/rename, chat view, prompt input,
folder dialogs for cwd. Reuses OllieDBusClient from plasmoid plugin.
Supports both Qt5 (KF5) and Qt6 (KF6) builds.