QDBusInterface caches introspection data and can become stale after
the backing service restarts. This caused ListSessions calls to
silently fail, leaving the GUI empty after an olliesrv restart.
Recreate m_iface in the serviceRegistered handler to ensure a fresh
connection to the new service instance.
- Kate plugin: ktexteditor -> kf6/ktexteditor (KF6), kf5/ktexteditor (KF5)
- Add 99-ollie.sh plasma env script for QT_PLUGIN_PATH and QML_IMPORT_PATH
- Plugins now found without sudo or system-wide install
- YouTube videos show hqdefault.jpg thumbnail
- All cards have minimum 200px height
- Play button opens in browser (fixed parent chain)
- Use id-based refs instead of fragile parent.parent chains
Detect video URLs (YouTube, Vimeo, Dailymotion, Twitch, direct media)
in chat responses. Direct .mp4/.webm/.ogv files play inline via
QtMultimedia Video. Other video sites show a card with play button
that opens in the system browser.
Adds Qt6::Multimedia dependency.
Replace full-pane MouseArea sloppy focus with HoverHandler which
does not interfere with click event delivery. Also increase timer
to 300ms and guard against redundant forceActiveFocus() calls.
Incremental parsing caused phantom blocks and disappearing content.
The 150ms coalescing on the daemon side is sufficient for perf.
updateVisibleWindow() extraction kept for clean separation.
When the tail contains only one header (common case during streaming),
just update the last block content directly. Fall back to full reparse
only when a genuinely new block boundary appears.
reparseIncremental() only re-parses from the last block boundary
instead of the entire chat text. Fixes UI lag and typing blockage
during long streaming responses.
Also extracted updateVisibleWindow() for reuse.
- OllieDBusClient: detachProcess, listDetached, signalDetached,
getDetachedOutput, dismissDetached methods + D-Bus signal handlers
- ChatPane.qml: Detach button (visible during calling: state) +
badge showing detached process count (click opens Process Manager)
- main.qml + main-kf5.qml: Process Manager window with process list,
live output tail, Term/Kill/Dismiss buttons per process
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).
Circular node layout showing all sessions with peer relationship edges.
Nodes are color-coded by state (green=idle, blue=thinking, orange=calling),
pulse when active. Click a node to select that session.
Toggle between list and graph view in sidebar toolbar.
Adds peerList() to OllieDBusClient.
Code fences with /path:start-end on the fence line get parsed.
Apply replaces that line range in the target file.
Fallback: insert at cursor or replace selection.
agent-copilot.md instructs model to produce ranged fences.
Context menu: right-click selection shows Fix/Refactor/Add tests/Document
actions that submit the selection with file+line context to the agent.
Apply button: code blocks in assistant messages get a clickable Apply
button that inserts the code into the target file (detected from
preceding prose) or the active document.
Inline annotations: file:line references in agent output are highlighted
with MovingRanges in the active editor view.
setHtml() resets the document layout. sb->setValue(sb->maximum()) was
reading a stale maximum before relayout completed. Use moveCursor(End)
+ ensureCursorVisible() which forces layout and scrolls reliably.
Also: fix session list state updates destroying delegates (rename fix)
already included in previous commit.
- 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 Qt.callLater scroll debounce with Timer (16ms) to coalesce
rapid contentHeight changes and eliminate scroll flickering
- Add execute button (play icon) on code blocks for scripted languages
(bash, python, perl, ruby, etc.) — launches in terminal
- Fix assistant bubble width: always use 95% of available width
- Add minimum width (280px) to code fence blocks
- Move emoji popup into prompt RowLayout so it appears near input
- Disable wheel scroll inertia (direct contentY) while keeping flick
inertia intact
- Apply all fixes to both KF5 and KF6 QML files