Panel.qml keeps the state, the CLI calls and the stage switch (889 lines, was 2360); each stage is its own file taking the panel as a required property. The omarchy installer copies every QML/JS file and clears stale ones. tests/static.sh filters qmllint on [syntax], not the word error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
127 lines
4.3 KiB
QML
127 lines
4.3 KiB
QML
import QtQuick
|
|
import qs.Commons
|
|
import qs.Ui
|
|
|
|
// SessionsStage.qml - Sessions are running. They will keep the old provider until they are restarted, and one mid-request can lose that turn outright, so this is a decision rather than a notification.
|
|
//
|
|
// One stage of the claude-mode panel. Panel.qml hands itself in as `panel`
|
|
// and owns all the state and actions; this file only draws them.
|
|
Column {
|
|
id: stage
|
|
required property var panel
|
|
|
|
width: parent.width
|
|
visible: stage.panel.stage === "confirm" && stage.panel.sessionInfo !== null
|
|
spacing: Style.space(7)
|
|
|
|
readonly property int total: stage.panel.sessionInfo ? Number(stage.panel.sessionInfo.count) : 0
|
|
readonly property int busyCount: stage.panel.sessionInfo ? Number(stage.panel.sessionInfo.busy) : 0
|
|
|
|
Text {
|
|
width: parent.width
|
|
text: parent.total === 1
|
|
? "1 Claude session is running"
|
|
: parent.total + " Claude sessions are running"
|
|
color: Color.popups.text
|
|
wrapMode: Text.WordWrap
|
|
font.family: stage.panel.uiFont
|
|
font.pixelSize: Style.space(13)
|
|
font.bold: true
|
|
}
|
|
|
|
// Not "they will keep using the old provider". Their endpoint and model
|
|
// ids are fixed at startup, but the key is re-fetched on a timer and
|
|
// will resolve to the new mode, which the old endpoint refuses - so
|
|
// they fail rather than carry on.
|
|
Text {
|
|
width: parent.width
|
|
text: "They keep pointing at " + stage.panel.pTitle(stage.panel.mode) + ", but their key is "
|
|
+ "re-fetched on a timer and will switch under them. Worse, if one takes a "
|
|
+ "reply from the new provider first, that provider's message-id format "
|
|
+ "goes into its transcript and Anthropic will refuse to resume it at all."
|
|
color: Color.muted
|
|
wrapMode: Text.WordWrap
|
|
lineHeight: 1.2
|
|
font.family: stage.panel.uiFont
|
|
font.pixelSize: Style.space(10)
|
|
}
|
|
|
|
Text {
|
|
width: parent.width
|
|
visible: parent.busyCount > 0
|
|
text: parent.busyCount === 1
|
|
? "One is working right now and will break mid-turn."
|
|
: parent.busyCount + " are working right now and will break mid-turn."
|
|
color: stage.panel.urgentColor
|
|
wrapMode: Text.WordWrap
|
|
font.family: stage.panel.uiFont
|
|
font.pixelSize: Style.space(10)
|
|
}
|
|
|
|
Column {
|
|
width: parent.width
|
|
spacing: Style.space(1)
|
|
|
|
Repeater {
|
|
model: stage.panel.sessionInfo ? stage.panel.sessionInfo.sessions : []
|
|
|
|
Item {
|
|
required property var modelData
|
|
width: stage.width
|
|
height: Style.space(17)
|
|
|
|
Text {
|
|
anchors.left: parent.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: parent.modelData.tty
|
|
color: Color.muted
|
|
font.family: stage.panel.uiFont
|
|
font.pixelSize: Style.space(10)
|
|
}
|
|
|
|
Text {
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: Style.space(52)
|
|
anchors.right: busyTag.left
|
|
anchors.rightMargin: Style.space(6)
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: parent.modelData.cwd
|
|
color: Color.popups.text
|
|
elide: Text.ElideLeft
|
|
font.family: stage.panel.uiFont
|
|
font.pixelSize: Style.space(10)
|
|
}
|
|
|
|
Text {
|
|
id: busyTag
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: parent.modelData.busy === true
|
|
text: "working"
|
|
color: stage.panel.urgentColor
|
|
font.family: stage.panel.uiFont
|
|
font.pixelSize: Style.space(10)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Flow, not Row: these can total more than the card is wide, and a
|
|
// Row lays them straight past its right edge instead of wrapping.
|
|
Flow {
|
|
width: parent.width
|
|
spacing: Style.space(7)
|
|
|
|
// Restart is the only option that ends with every session on the mode
|
|
// the bar is now claiming, so it leads and it is the primary.
|
|
PillButton { fontFamily: stage.panel.uiFont;
|
|
label: "Switch and restart"
|
|
primary: true
|
|
onTriggered: stage.panel.applySwitch("restart")
|
|
}
|
|
PillButton { fontFamily: stage.panel.uiFont; label: "Switch and close"; onTriggered: stage.panel.applySwitch("stop") }
|
|
PillButton { fontFamily: stage.panel.uiFont; label: "Switch only"; onTriggered: stage.panel.applySwitch("none") }
|
|
PillButton { fontFamily: stage.panel.uiFont; label: "Cancel"; onTriggered: stage.panel.resetFlow() }
|
|
}
|
|
}
|