Move Qt/Tauri/full Web SPA under archive/, ship hermit as CLI/TUI plus libcstcore and cst-webui/1 HTTP+SSE (turn lifecycle hooks, capabilities). Co-authored-by: Cursor <cursoragent@cursor.com>
109 lines
3.0 KiB
QML
109 lines
3.0 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
|
|
// on_ask_user: the agent stopped and wants an answer from the human. Options
|
|
// (when the engine sends any) become buttons; the field is always there.
|
|
Dialog {
|
|
id: dialog
|
|
property string question: ""
|
|
property string optionText: ""
|
|
signal answered(string text)
|
|
|
|
readonly property var options: {
|
|
const raw = optionText.split(/[|\n]/).map(s => s.trim()).filter(s => s.length > 0 && s.length < 60)
|
|
return raw.length > 1 && raw.length <= 8 ? raw : []
|
|
}
|
|
|
|
modal: true
|
|
anchors.centerIn: parent
|
|
width: Math.min(620, parent ? parent.width - 60 : 620)
|
|
padding: Theme.pad
|
|
|
|
background: Rectangle {
|
|
color: Theme.surface
|
|
border.width: 1
|
|
border.color: Theme.border
|
|
radius: Theme.radius
|
|
}
|
|
|
|
function send(text) {
|
|
const t = text.trim()
|
|
if (!t.length)
|
|
return
|
|
answered(t)
|
|
close()
|
|
}
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: Theme.gap
|
|
|
|
RowLayout {
|
|
spacing: Theme.gap
|
|
Rectangle { width: 8; height: 8; radius: 4; color: Theme.accent }
|
|
Text {
|
|
text: "The agent asks"
|
|
color: Theme.text
|
|
font.pixelSize: Theme.bodySize + 1
|
|
font.bold: true
|
|
}
|
|
}
|
|
Text {
|
|
Layout.fillWidth: true
|
|
text: dialog.question
|
|
color: Theme.text
|
|
font.pixelSize: Theme.bodySize
|
|
wrapMode: Text.Wrap
|
|
}
|
|
Text {
|
|
Layout.fillWidth: true
|
|
visible: dialog.optionText.length > 0 && dialog.options.length === 0
|
|
text: dialog.optionText
|
|
color: Theme.textDim
|
|
font.pixelSize: Theme.smallSize
|
|
wrapMode: Text.Wrap
|
|
}
|
|
Flow {
|
|
Layout.fillWidth: true
|
|
visible: dialog.options.length > 0
|
|
spacing: Theme.gap
|
|
Repeater {
|
|
model: dialog.options
|
|
Button {
|
|
text: modelData
|
|
onClicked: dialog.send(modelData)
|
|
}
|
|
}
|
|
}
|
|
TextField {
|
|
id: answer
|
|
Layout.fillWidth: true
|
|
placeholderText: "your answer"
|
|
placeholderTextColor: Theme.textFaint
|
|
color: Theme.text
|
|
font.pixelSize: Theme.bodySize
|
|
selectByMouse: true
|
|
onAccepted: dialog.send(text)
|
|
background: Rectangle {
|
|
radius: Theme.radiusSm
|
|
color: Theme.bg
|
|
border.width: 1
|
|
border.color: answer.activeFocus ? Theme.accentDim : Theme.border
|
|
}
|
|
}
|
|
}
|
|
|
|
footer: DialogButtonBox {
|
|
padding: Theme.pad
|
|
Button {
|
|
text: "Send"
|
|
highlighted: true
|
|
enabled: answer.text.trim().length > 0
|
|
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
|
onClicked: dialog.send(answer.text)
|
|
}
|
|
}
|
|
|
|
onOpened: answer.forceActiveFocus()
|
|
}
|