Commit Graph

425 Commits

Author SHA1 Message Date
Levi Neely 481f7f9d76 toggle arrow direction on collapsible blocks (▶/▼) 2026-07-16 06:54:06 +02:00
Levi Neely d7a66f1827 replace ListView with Flickable+Column+Repeater
ListView.positionViewAtEnd() causes freezes by forcing instantiation
of all delegates to measure total height. Flickable+Column avoids this
- contentHeight is computed directly from Column.implicitHeight
- Scroll to bottom is just contentY = contentHeight - height
- No virtualization needed with only 20 blocks
- Eliminates all positionViewAtEnd and _scrolling guard complexity
2026-07-16 06:51:37 +02:00
Levi Neely 79656596e4 fix startup freeze: async highlighting + reduce initial blocks to 20
- Code blocks show plain text immediately, highlight via Timer after
  150ms (prevents blocking the render thread during initial load)
- Reduced initial blocks from 40 to 20
- Detect append vs full reset in setRawText for better session switch
2026-07-16 06:49:20 +02:00
Levi Neely f122a69bce reverse-scroll chat: start at bottom, lazy-load on scroll up
- Model shows last 40 blocks initially, positioned at end
- Scrolling near top triggers loadEarlier() which prepends 30 blocks
- Scroll position maintained after prepend via contentY adjustment
- All blocks still parsed (for searching later) but only tail rendered
- Reduced initial render cost significantly
2026-07-16 06:46:47 +02:00
Levi Neely f1a045077b limit visible blocks to 80 + reduce cacheBuffer for startup perf
With 300KB+ chat logs producing hundreds of blocks, instantiating all
delegates was causing unresponsiveness. Cap the model at the last 80
blocks and set cacheBuffer: 200 to limit off-screen rendering.
2026-07-16 06:44:11 +02:00
Levi Neely 6f351b77e4 fix performance: cache subBlocks and syntax highlighting
- Cache parseSubBlocks per block (only reparse when content changes)
- Cache highlightedHtml results (code+language key)
- Prevents expensive KSyntaxHighlighting and regex on every render
- Also fixes scroll loop with _scrolling guard
2026-07-16 06:42:11 +02:00
Levi Neely a6a1a227c3 fix scroll: incremental model updates + prevent scroll loop
- ChatBlockModel::reparse() now does incremental diffs instead of
  beginResetModel which destroys all delegates and resets scroll
- ListView scroll uses _scrolling guard to prevent infinite loop
  from positionViewAtEnd triggering contentHeightChanged
2026-07-16 06:38:37 +02:00
Levi Neely 0783c7dda3 fix scroll height and prose line breaks in rich output
- Loader delegate: set explicit height from item.implicitHeight so
  ListView can calculate correct contentHeight for scrolling
- Prose sub-blocks: escape HTML, convert newlines to <br> before
  linkifying paths (RichText ignores bare newlines)
2026-07-16 06:36:00 +02:00
Levi Neely 9e10bf30db fix: Text has no background property, wrap diff lines in Rectangle 2026-07-16 06:31:02 +02:00
Levi Neely 6e03064d0f rich output rendering for ollie-gui
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)
2026-07-16 06:29:18 +02:00
Levi Neely 6642ab014b multi-line prompt input across all front-ends
Replace single-line TextField/QLineEdit with multi-line TextArea/QPlainTextEdit.
Enter sends, Shift+Enter and Ctrl+J insert newlines. Max height capped so the
input area does not take over the panel.
2026-07-16 06:19:14 +02:00
Levi Neely 5c51ef3a87 gitignore build directory 2026-07-16 06:10:10 +02:00
Levi Neely 7b8fa5eca4 support arbitrary color schemes in ollie-gui
Scan ~/.local/share/color-schemes/ in addition to /usr/share/color-schemes/
so user-installed themes (e.g. Catppuccin) are discovered. Mode is now any
scheme name rather than just system/light/dark. Settings dialog uses a
ComboBox listing all available schemes plus "System".
2026-07-16 06:08:41 +02:00
Levi Neely fcc3cd2313 kate stop button, sorted sessions, scroll pinning, install fix
- Kate: add always-visible stop button next to prompt input
- All front-ends: sort sessions alphabetically by ID
- All front-ends: only auto-scroll chat if at bottom, show
  floating go-to-bottom button when scrolled away
- CMakeLists: set KDE_INSTALL_PLUGINDIR to QT6_INSTALL_PLUGINS
  so plugins install to lib64/qt6/plugins/ (where Kate looks)
2026-07-16 06:03:15 +02:00
Levi Neely d5e27f1c82 fix kate crash 2026-07-15 17:55:14 +02:00
Levi Neely 455d9c9190 kate: fix use-after-free crash in setupGhostProvider
m_ghost was parented to the view, so Qt parent-child cleanup could
destroy it when a view was replaced. The raw pointer remained non-null,
causing a double-free on the next viewChanged signal.

Fix by using QPointer<OllieGhostProvider> which auto-nulls on destroy.

Also replace qobject_cast with dynamic_cast for KF5 KTextEditor
interfaces to avoid crashes when qt_metacast accesses uninitialized
KateViewConfig during early view activation.
2026-07-15 11:06:20 +02:00
Levi Neely 5d18806ad6 kate: add KF5 preprocessor guards for InlineNote and completion APIs
KF5's KTextEditor uses interface classes (InlineNoteInterface,
CodeCompletionInterface, ConfigInterface) accessed via qobject_cast,
whereas KF6 puts these methods directly on View. Wrap the differences
with #if KTEXTEDITOR_VERSION_MAJOR >= 6 so both build paths compile.

Fixes:
- inlineNotes() return type: QVector<int> (KF5) vs QList<int> (KF6)
- paintInlineNote() signature: 2 params (KF5) vs 3 params (KF6)
- register/unregisterInlineNoteProvider via InlineNoteInterface
- isCompletionActive via CodeCompletionInterface
- configValue via ConfigInterface
2026-07-15 09:59:56 +02:00
Levi Neely e87038ca04 plasmoid: fix highlighted session text unreadable on light themes
Replace KirigamiDelegates.RoundedItemDelegate (not available in all
Kirigami versions) with PlasmaComponents.ItemDelegate. Add explicit
highlightedTextColor bindings to labels and icon in the session list
delegate for both KF5 and KF6 builds.
2026-07-14 15:58:46 +02:00
Levi Neely 1552fce126 kate: fix crash on document close (dangling overlay pointer)
The GhostOverlay is parented to the view widget and gets destroyed by
Qt child cleanup before ~OllieGhostProvider runs. Stop calling
hideOverlay() in destructor, connect destroyed() signal to null the
pointer.
2026-07-14 14:58:40 +02:00
Levi Neely 18402a2be7 kate: config page improvements, status bar dedup, default backend/model
- Add Default Backend / Default Model config for chat sessions
  (overrides OLLIE_BACKEND / OLLIE_MODEL env vars)
- Pass configured backend/model to CreateSession D-Bus call
- Move "Completion enabled on startup" checkbox below text fields
- Deduplicate status bar indicator when multiple views exist
- Make install target depend on build
- Remove Escape-to-dismiss (conflicts with Kate popups)
2026-07-14 14:53:13 +02:00
Levi Neely b67e82dca0 kate: fix ghost text provider, add multi-line overlay and config
- Fix parent not passed to InlineNoteProvider causing provider recreation
  on every viewChanged signal (killed debounce timer, no completions fired)
- Add view() accessor, use it in setupGhostProvider check
- Null-check focusProxy() to prevent crash during early viewChanged
- Multi-line completions: first line as inline note, continuation lines
  rendered via GhostOverlay floating widget
- Guard event filter and signal handlers against active completion popups
- Add suggestion cycling (Meta+O,N / Meta+O,P) with history
- Add Meta+O,C to toggle completions on/off with status bar indicator
- Add Meta+O,D to dismiss current suggestion
- Add Meta+O,Tab to manually trigger a completion
- Add config page for completion backend and model override
- Pass backend/model config via D-Bus Complete context parameter
2026-07-14 13:24:03 +02:00
Levi Neely 16e8fc7a75 feat: ghost-text code completion via InlineNoteProvider
Adds OllieGhostProvider that renders AI completions as translucent
gray text after the cursor. Uses the new Complete D-Bus method with
500ms debounce. Tab accepts, Escape dismisses, any edit clears.
Works on both KF5 and KF6 builds.
2026-07-14 12:30:18 +02:00
Levi Neely bbff78cd7e add .gitignore: exclude __pycache__ 2026-07-14 12:00:43 +02:00
Levi Neely 2f02d71ca3 add gui_brightness tool (percentage-based brightness control) 2026-07-14 11:56:01 +02:00
Levi Neely 606bb1bbaa add GUI automation tools (10 tools + prompt + Makefile targets)
New tools for KDE desktop automation via D-Bus:
- gui_clipboard: Klipper read/write/history
- gui_notify: interactive notifications with actions
- gui_screenshot: spectacle/KWin capture
- gui_windows: window management (list/focus/move/resize/desktops)
- gui_apps: launch/list/activate applications
- gui_input: synthetic keyboard/mouse (ydotool/xdotool)
- gui_activities: Plasma Activities management
- gui_files: Baloo file search
- gui_shortcuts: KGlobalAccel shortcuts
- gui_accessibility: AT-SPI2 full GUI automation

Adds prompts/tools-gui.md for agent discovery and Makefile
tools-install/tools-uninstall targets.
2026-07-14 11:53:09 +02:00
Levi Neely a86d7391b2 plasmoid: use Kirigami components for session list delegates
Replace plain ItemDelegate/Label with Kirigami.BasicListItem and
proper icon sources for state indicators.
2026-07-11 16:09:07 +02:00
Levi Neely d1d113b5fd fix kf5 plasmoid install and portal dialog race
- Makefile: directly install plasmoid to /usr/share instead of using
  kpackagetool5 (which doesn't overwrite existing files, causing the
  KF6 main.qml to persist over the KF5 version)
- olliedbusclient: fix portal FileChooser race condition by connecting
  to Response signal before making the OpenFile call using a
  predictable handle_token
2026-07-10 12:04:12 +02:00
Levi Neely 45419393ae gui: allow text selection in chat area
- Enable selectByMouse on chatArea TextArea
- Only auto-scroll to bottom when no text is selected
2026-07-10 11:43:48 +02:00
Levi Neely dc1816f023 gui: fix Qt5/KF5 compatibility
- 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
2026-07-09 11:26:10 +02:00
Levi Neely 7f93543e56 gui: theme manager with KDE color schemes, font settings, and native folder dialogs 2026-07-09 00:07:47 +02:00
Levi Neely 86518c75fe fix: prefer theme icon over font-rendered fallback
Use QIcon::fromTheme("ollie") if available, which loads the SVG
from hicolor. Falls back to FA font rendering if the theme icon
is not installed.
2026-07-08 21:13:57 +02:00
Levi Neely c2df43749e fix: use visible pink color for brain icon
#eeeeee was invisible on light/transparent backgrounds.
2026-07-08 21:11:37 +02:00
Levi Neely 75e518dd5f fix: use concrete fill color in icon SVG
currentColor only works with Breeze icon engine color substitution,
not with generic hicolor theme loaders.
2026-07-08 21:08:49 +02:00
Levi Neely a66b9984e3 fix: use proper vector path for brain icon SVG
Extracted path data from FA6 OTF directly. The text-based SVG
did not render because icon loaders do not support font rendering
in SVG text elements.
2026-07-08 20:58:37 +02:00
Levi Neely 74f51519f6 feat: add .desktop file and icon for task manager persistence
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.
2026-07-08 20:52:10 +02:00
Levi Neely 5984dec374 feat: render FA6 brain glyph as window icon 2026-07-08 20:08:00 +02:00
Levi Neely c294670df1 fix: correct resource prefix for ollie-gui QML 2026-07-08 19:55:00 +02:00
Levi Neely 8a644d8d7c feat: add ollie-gui QtQuick standalone application
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.
2026-07-08 19:46:10 +02:00
Levi Neely c8d3143d87 fix: use kpackagetool6 -g for system-wide plasmoid install
Without -g, kpackagetool installs to the running user HOME.
Since the Makefile runs as root, the package ended up in
/root/.local/share/ instead of /usr/share/plasma/plasmoids/.
2026-07-08 19:39:14 +02:00
Levi Neely eed04948c7 fix: use kpackagetool -u (update) instead of remove+install
The remove+install approach could leave stale QML when the install
path changed. Using -u updates in-place, falling back to -i for
first-time installs.
2026-07-08 19:36:53 +02:00
Levi Neely a988930dbc fix: use xdg-desktop-portal for folder dialog in plasmoid
plasmashell is QGuiApplication so QFileDialog (QtWidgets) cannot work.
Use org.freedesktop.portal.FileChooser.OpenFile via D-Bus instead.
Also fix StandardPaths ReferenceError in main.qml.
2026-07-08 19:33:48 +02:00
Levi Neely d97d2fb1af feat: use native QFileDialog for new session folder selection
QML FolderDialog does not work inside the plasmoid sandbox.
Move folder selection to C++ via QFileDialog::getExistingDirectory
and expose as createSessionWithDialog(). Applies to both kf5 and kf6.
2026-07-08 19:31:22 +02:00
Levi Neely 31e45452d9 fix(kf5): open folder dialog before creating session 2026-07-08 19:28:59 +02:00
Levi Neely 5ad224dfae fix: refresh session list on rename via reply callback and signal 2026-07-08 19:27:31 +02:00
Levi Neely 3b42c9ee25 plasmoid: folder picker for new sessions, fix chat offset encoding
- New session button opens a FolderDialog to choose the working directory before creating the session.

- Fix chat truncation: use toUtf8().size() for offset tracking to match the server byte-based offsets. QString::size() (UTF-16 code units) caused drift on non-ASCII characters, leading to stalled output.
2026-07-07 15:02:55 +02:00
Levi Neely 327030293b plasmoid: async D-Bus calls to prevent panel freezes
All synchronous QDBusInterface::call() replaced with asyncCall() +
QDBusPendingCallWatcher. Adds coalescing flags to prevent piling up
refreshSessions/fetchChat requests during rapid signal bursts.

Also removes build dependency from install targets to prevent cmake
re-running over read-only installed artifacts.
2026-07-07 13:32:07 +02:00
Levi Neely d457be9524 remove daemon (moved to ollie-dbus submodule) 2026-07-07 13:02:34 +02:00
Levi Neely e53ed3b918 plasmoid: auto-focus prompt input when expanded 2026-07-07 12:27:52 +02:00
Levi Neely 03321cf8a6 plasmoid: clear sessions when ollie-kde service disappears
Watch for NameOwnerChanged via QDBusServiceWatcher. When the
service unregisters, reset all state. When it re-registers,
refresh the session list.
2026-07-07 12:26:46 +02:00
Levi Neely 200bf7251e add prompts, skills, tools (D-Bus API versions) 2026-07-07 12:07:39 +02:00