- Remove import of QtQuick.Dialogs 1.15 (not available on Gentoo)
- Replace FolderDialog with FileDialog { selectFolder: true }
- FileDialog is part of QtQuick.Controls 2.x which is already imported
- Add C++ methods: loadRootBackends(), loadRootAgents(), getAvailableModels(), createSession()
- Add Q_PROPERTYs for root data state (backends, agents, models)
- Add '+' button to sessions toolbar
- Create New Session Dialog with:
- Directory field + Browse button (FolderDialog)
- Name field (optional, auto-generated if empty)
- Backend combo (populated from /backends)
- Model combo (filtered by selected backend)
- Agent combo (populated from /agents)
- Remote field (user@host:port)
- Root data loaded lazily on startup
- OK creates session via 'write new' 9P call and refreshes list
- Guard delegate against undefined properties during initial render
- Use || 0 fallbacks for optional model properties
- Remove broken ScrollBar.vertical.value assignment (not assignable)
- Fix Keys.onReturnPressed to use explicit function(event) parameter
- Call buildSessionTree() on Component.onCompleted
- Add getAgents() to Ollie9pClient for listing agents per session
- Add switchAgent() for switching sessions+agents atomically
- Add activeAgentId property and activeAgentIdChanged signal
- Replace flat ListView with tree-aware model (session → agents)
- Session nodes expandable/collapsible with ▶/▼ indicator
- Agent nodes indented, clickable to activate that agent
- Active agent highlighted, active session auto-expanded
- State dots on both session and agent rows
- TextArea grows from 5 rows up to 200px as content increases
- Auto-scrolls to bottom on text change
- Uses Math.min(contentHeight, max) to avoid unnecessary space
- Add fence state machine (NoFence → InFence) to ChatBlockModel
- On closing ```, render via KSyntaxHighlighting or inline diff colorizer
- Store rendered HTML in ChatBlock.renderedHtml, emit dataChanged on RenderedHtmlRole
- QML shows RichText Label when renderedHtml is populated, falls back to PlainText
- Add KF6::SyntaxHighlighting dependency for ollie-gui target
switchToSession() was loading the log but never starting the
streaming processes. New output from the agent was never delivered.
Now: stopStreams → load log → startChatStream + startStateStream.
Signals were emitted before m_agentId was set, causing QML's
onActiveSessionIdChanged handler to call readLog() with an empty
agent path. Now: discover agent → emit signals → start streams.
Replace all 28+ D-Bus call sites with 9P operations via plan9port's
9p command. Chat streaming via persistent QProcess reading the chat
file. State updates via statewait process restart loop.
Ghost text provider disabled (needs separate 9P port).
The entire KDE submodule is now D-Bus-free for server communication.
D-Bus is only used internally by KDE frameworks (KRunner plugin loading,
KStatusNotifierItem, etc.) — not for ollie protocol.
- KRunner: rewritten to use plan9port 9p command for all operations
(list sessions, kill, one-shot generate). No D-Bus dependency.
- Tray: removed. Was a thin D-Bus status wrapper, not useful enough
to justify maintaining.
- Plasmoid: removed. GUI is standalone now.
- Kate: temporarily disabled in CMake. Header partially converted to
9P (D-Bus includes removed, QProcess/9P helpers declared). Full
conversion is next.
- All ninepBin() helpers use $PLAN9/bin/9p (not hardcoded path).
- CMake: removed Qt5::DBus, KF5::Notifications, KF5::Plasma deps.
Only remaining link deps: Qt5::Core, Qt5::Widgets, Qt5::Quick,
Qt5::QuickControls2, KF5::Runner.
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).
QTextDocument::setHtml was called while the document was still
tearing down from clear(). Defer refreshSessions to the next
event loop iteration with QTimer::singleShot(0, ...).
Allow specifying a remote target (e.g. user@host) when creating a
session from the GUI. Empty means local execution. The value is passed
through to the D-Bus CreateSession method's remote parameter.
Reactions were removed from the core runtime. Remove the dead QML code:
- 3x setReactions/getReactions dbus calls
- blockReaction property on delegate loader
- Reaction badge label and reaction buttons row
MovingRanges are owned by the document. When the document is destroyed,
it deletes its ranges. If clearAnnotations is called after the document
is gone (e.g., view changed), qDeleteAll double-frees. Track the owning
document with QPointer and only delete ranges if it's still alive.
When the new-session dialog opens, the backend combo defaults to index 0
but onCurrentTextChanged doesn't fire for the initial value. Explicitly
call listModelsByBackend for the default backend so the model dropdown
is populated immediately.
Child MouseArea inside Flickable interferes with drag detection even
when only accepting RightButton. Move it to a sibling overlay with
propagateComposedEvents so left-drag reaches the Flickable natively.
Remove manual pan logic. Let Flickable handle drag-to-pan natively.
MouseArea only accepts RightButton (close) and wheel (zoom), so it
no longer steals left-click events from the Flickable.
Left-click drag was unreliable for panning. Use Meta (Super/Win key)
+ left-click-drag instead. Flickable interactive mode disabled;
panning is handled manually via MouseArea.
The mermaid container has been replaced with a proper mermaid.ink
server. Use /img/ endpoint (returns JPEG) instead of /svg/ since
Qt's SVG renderer can't handle CSS class-based styles. Falls back
to mmdc CLI with PNG output if server is unavailable.
Qt's SVG renderer doesn't support CSS class-based styling that mermaid
generates (<style> blocks with class selectors). This caused text and
connectors to be invisible — they had no fill/stroke applied.
Fix: output PNG from mmdc for mermaid diagrams. Qt renders PNG perfectly.
PlantUML and Draw.io continue using SVG (they use inline styles).
Text and connectors were invisible because mmdc rendered with a dark
theme (white text/edges) on the white diagram background. Explicitly
pass -t default to force dark text on light background.
- Detect mermaid/plantuml/drawio/mxgraph code fences as 'diagram' sub-blocks
- Render via local servers (PlantUML :8080, Mermaid :8081, draw.io :8082)
- Fall back to CLI tools (plantuml, mmdc, drawio) if servers unavailable
- Cache rendered SVGs in ~/.cache/*/diagrams/ keyed by content hash
- Show rendered image with white background (dark theme friendly)
- Collapsible source toggle (▶/▼) below rendered diagram
- Middle-click to invalidate cache and re-render
- Left-click opens fullscreen pannable/zoomable viewer
- Fullscreen: scroll-wheel zoom, drag to pan, Esc/right-click/dbl-click to close
- Both kf5 and kf6 builds
Connect the new ConfigChanged signal from the session manager to trigger
refreshSessions() and fetchConfig(), so the sidebar updates immediately
when the user runs /agent to switch agents.
In Qt5 Repeater delegates, 'property var block: model' doesn't
propagate dataChanged updates for individual roles. Add a reactive
'blockReaction' string property bound to model.reaction directly,
which updates when the model emits dataChanged.