The window is no longer one file pretending to be a chat box. The transcript, the run panel, the composer and the two consent dialogs are their own QML components over one Theme singleton, and the shell around them adapts to the screen: docked and scrollable on a desktop, a slide-out drawer on a phone. QML (app/qml/, new except Main.qml): - Theme.qml: single QML singleton, dark Breeze-flavoured tokens (surface, border, accent, text/textDim/textFaint, radius, pad, gap, sizes, monospace); diffLineColor() for unified-diff rows, compactBreakpoint 880, touchTarget 34, segmentHeight 30, headerHeight 42. - ChatView.qml: a row-type dispatcher over the transcript model (message, thought, tool, note), follow-the-tail scrolling with a "jump to latest" button once the user scrolls up, and an empty state that says where the agent runs and what it can do. - MessageCard.qml, ThinkBlock.qml, NoteLine.qml, ToolCard.qml (status pill, arguments, collapsible output, 500-line cut, diff colouring, spinner while the call runs), TodoPanel.qml. - Sidebar.qml: workspace/provider/status, mode and approval segmented rows, plan switch, the engine's todo list, version footer; scrolls, so a short window still reaches every control. - Composer.qml: auto-growing field, Enter sends / Shift+Enter newlines, red Stop while a turn runs, autocorrect hints off, finger-sized targets. - ConsentDialog.qml (Deny / Once / Always -> CST_PERM_*) and AskDialog.qml (the model's options become buttons, free text stays possible). - Main.qml: shell with header, draggable sidebar splitter (hover feedback, 200-560 px, double-click resets), transcript, composer, the two dialogs, Esc to cancel and Ctrl+L to clear. Under 880 px the sidebar becomes a drawer with a scrim instead of squeezing the chat away. AgentCore / main.cpp: - provider, model, approval and planMode are properties now; approval and plan mode write back into the engine's config, and renderMarkdown() calls cst_web_md_html(), so a table or a code fence looks like the WebUI's. - the todo hook writes m_todo on the GUI thread (it was written from the worker thread before: a data race on a QString member). - --size WxH for the window (the layout tests drive it), and the Basic style is chosen by default: the Breeze Quick style registers its types with relative URLs, which floods the log and breaks the composer. UI tests (app/src/ui/): - --uitest drives the real window with synthesized input and exits with the number of failures: 15 checks over docking/drawer transitions, mouse clicks and touch taps reaching the engine's mode, the plan switch, the composer arming the send button, and a 460x900 -> 1200x820 resize round trip. - every control the tests touch carries an objectName; the sidebar's implicitHeight binding loop is gone. Tests: cst-app-selftest and --uitest pass in the standalone app build, ctest cst-app-selftest passes in the repo build (38/38 on the host). Version 0.8.8.
61 lines
2.1 KiB
QML
61 lines
2.1 KiB
QML
// One place for the look: colors, spacing, fonts. The window, the cards and
|
|
// the dialogs all read from here, so re-theming (or swapping in Kirigami's
|
|
// Kirigami.Theme) is a single file.
|
|
pragma Singleton
|
|
|
|
import QtQuick
|
|
|
|
QtObject {
|
|
// Breeze-dark-ish (the desktop the app is built for), no hard contrast.
|
|
readonly property color bg: "#15181a"
|
|
readonly property color surface: "#1e2225"
|
|
readonly property color surfaceAlt: "#262b2f"
|
|
readonly property color surfaceHi: "#313840"
|
|
readonly property color border: "#343b41"
|
|
readonly property color text: "#eff0f1"
|
|
readonly property color textDim: "#9aa2a8"
|
|
readonly property color textFaint: "#6d757b"
|
|
readonly property color accent: "#3daee9"
|
|
readonly property color accentDim: "#1d6f95"
|
|
readonly property color ok: "#27ae60"
|
|
readonly property color warn: "#f67400"
|
|
readonly property color err: "#da4453"
|
|
|
|
readonly property int radius: 6
|
|
readonly property int radiusSm: 3
|
|
readonly property int gap: 8
|
|
readonly property int gapL: 14
|
|
readonly property int pad: 12
|
|
readonly property int padL: 16
|
|
|
|
readonly property int bodySize: 14
|
|
readonly property int smallSize: 12
|
|
readonly property int monoSize: 13
|
|
readonly property string mono: "monospace"
|
|
|
|
readonly property int sidebarWidth: 268
|
|
readonly property int contentMax: 1100
|
|
|
|
// Layout: below the breakpoint the sidebar slides over the transcript
|
|
// instead of taking a column, and controls stay thumb-sized above it
|
|
// (a finger needs ~34-40 px, a mouse is happy with 26).
|
|
readonly property int compactBreakpoint: 880
|
|
readonly property int touchTarget: 34
|
|
readonly property int segmentHeight: 30
|
|
readonly property int headerHeight: 42
|
|
readonly property int jumpButton: 40
|
|
|
|
// The tool output / diff line colors, used by ToolCard.
|
|
function lineColor(line) {
|
|
if (line.startsWith("@@"))
|
|
return accent
|
|
if (line.startsWith("+++") || line.startsWith("---"))
|
|
return textDim
|
|
if (line.startsWith("+"))
|
|
return ok
|
|
if (line.startsWith("-"))
|
|
return err
|
|
return text
|
|
}
|
|
}
|