1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
# sb-builder: one UI frame for every tab
Date: 2026-10-20
Status: approved
Builds on: phases 1, 2 and 4 (tabs, Jobs, Packages, Results, Hints)
## Goal
Every tab looks and works the same, and a multi-step task (check upstream,
update hints, preview, build) never sends the user hunting for the next
button in another place. Rules go into AGENTS.md so later tabs follow them.
## What is wrong today
- Action buttons sit at the bottom in Packages and Hints, in a side pane in
Results, at the top in Jobs.
- The ribbon opens tabs; tabs open and close.
- A step's follow-up lives elsewhere: Packages action -> auto switch to Jobs
-> Run it at the top of Jobs. Hints: Check upstream (bottom) -> tick ->
Update selected (bottom) -> diff dialog -> Build these -> Jobs -> Run it
(top).
- The Jobs Start menu name says nothing of what it holds.
## Window frame
Top to bottom: main ribbon, small ribbon, tab bar, the tab's view (its
filter bar first), status bar.
- **Permanent tabs**: Dashboard (default), Packages, Hints, Results, Jobs,
created at startup, not closable. Each loads its data the first time it is
shown (Packages, Hints and Results call `inventory`/`results` then, not at
startup). Navigation: tab bar, Ctrl+PgUp/PgDn, Dashboard tiles (Packages,
Recent jobs, slackrepo results as today). The ribbon does not open tabs.
`File` menu unchanged.
- **Main ribbon**: `QToolBar`, 32 px icons, text under icon, the current
tab's actions in workflow order. Refilled on tab change.
- **Small ribbon**: `QToolBar` right under it, 16 px icons, text beside
icon, the tab's view controls. Hidden when the tab has none.
- Each tab exposes `actions` and `view_actions`, lists of `QAction` it owns,
so enabled and checked state survive tab switches. Icons are freedesktop
theme names with a `QStyle` fallback, as the ribbon does now.
- An action that does not apply is disabled with a tooltip saying why;
never hidden, so the ribbon does not shift.
- Filter bars (search, chips, `N shown · M selected` or `N of M`) stay at
the top of the view; their Refresh buttons move to the small ribbon.
## Selection
- Change actions act on the **ticked** rows; view actions (Show build log)
on the **highlighted** row.
- A click anywhere on a row toggles its tick (done for Packages and Hints).
- Ctrl+A ticks the visible rows, Ctrl+Shift+A unticks all (done); the
small ribbon's Select visible and Clear carry the same shortcuts.
## Ribbons per tab
| Tab | Main ribbon | Small ribbon |
|---|---|---|
| Dashboard | Refresh | none |
| Packages | Build, Update, Rebuild, Remove, Update all, New hint, Publish | Select visible, Clear, Refresh |
| Hints | Check upstream, Update selected, Delete hint | Select visible, Clear, No download (checkable), Refresh |
| Results | Show build log | Refresh |
| Jobs | Pull overlay (menu: one entry per overlay), Check shadowing, Run it, Kill | none |
Disabled reasons (tooltips):
- Build, Update, Rebuild, Remove: "tick packages first".
- New hint: "none of the ticked packages is without a hint".
- Update selected: "tick outdated packages after Check upstream".
- Delete hint: "none of the ticked packages has a hint".
- Show build log: "select a result with a log".
- Run it: "select a finished preview".
- Kill: "no job running".
- Check upstream while running: "checking…".
Update all, Publish, Pull overlay and Check shadowing are always enabled
(the helper refuses a second job with the busy answer, as today).
Packages' detail pane keeps **Open in Hints** as a link (navigation, not an
action). Its New hint button moves to the ribbon.
### New hint on ticked packages
`hint-new` takes one or more packages and no version: `hint-new <pkg>...
[--no-dl]`. Each gets the `.info` pin; Update selected from upstream sets a
version later. The GUI sends no `--no-dl` here (Update selected has the
toggle); the helper keeps the flag. Every package must be without a hint, else the job is
refused before it starts, as today for one. Helper `VERSION` 0.6.0 in both
files, VM redeploy. The New hint dialog goes away.
## Next-step dialogs
- Shown only for jobs started from this GUI session: the main window keeps
the ids `job-start` returned. Jobs seen on reconnect or started elsewhere
only notify, as today.
- Non-modal, one per job, never reopened by polling.
- **Preview ended ok** (`slackrepo` with `--preview`): dialog titled
`Preview: <kind and args without --preview>`, with the whole job log
(`job-follow` from offset 0; the job has ended, so the stream closes by
itself), a **publish** checkbox (default `builds.publish`), **Run it**
(default button) and **Not now**. Run it goes through the signing-key
check (`start_signed`) and starts the real run.
- **sbpull or sbshadow preview ended ok with a shadow plan** (`shadow:` or
`unshadow:` lines, as `SHADOW_PLAN` today): same dialog, **Apply
shadowing** (`sbshadow --yes`, after a confirm: it changes the repo) and
**Not now**. Without a plan, no dialog.
- **Hint job ended** (`hint-update`, `hint-new`) or a delete: the existing
diff dialog; Build these starts `slackrepo update --preview`, whose end
opens the preview dialog.
- A real run ending, a failed or killed job: notification only.
- **Run it** in the Jobs ribbon, with a finished preview selected, reopens
that preview's dialog (also for a shadowing preview), so Not now loses
nothing. The Jobs top bar (Start, Apply shadowing, Run it, publish, Kill)
goes away.
The hugo flow becomes: Hints, Check upstream -> Update selected -> diff
dialog, Build these -> preview dialog, Run it. No tab switch.
## Jobs tab signal
- Starting a job no longer switches to Jobs; the user stays on the tab.
- While a job runs, the Jobs tab shows a running icon (`system-run`) and
accent-colored text (palette highlight).
- When it ends, the icon becomes the end status (`✔` ok, `✘` failed,
killed, lost) and stays until the Jobs tab is shown, then clears.
- The status bar job button stays.
## AGENTS.md: UI guidelines
A new section, binding for every tab:
1. Tabs are permanent; each loads lazily on first show.
2. Main ribbon: the tab's actions in workflow order. Small ribbon: view
controls. Nothing actionable lives inside a view except navigation links.
3. Change actions act on ticked rows, view actions on the highlighted row.
A row click toggles its tick; Ctrl+A / Ctrl+Shift+A select visible /
clear.
4. An inapplicable action is disabled with a tooltip saying why, never
hidden.
5. When a job this session started ends, its next step opens as a
non-modal dialog where the user is; the Jobs tab shows activity; a
dismissed step can be taken again from the ribbon.
6. A modal confirm only for destructive or outward steps (delete hint,
publish, apply shadowing).
## Testing
`test_gui.py` with the fake remote, offscreen:
- ribbon contents per tab (action texts in order) after switching tabs;
- disabled states and tooltips (nothing ticked, no preview selected, no job
running);
- tabs are not closable and present from the start; data loaded on first
show only (no `inventory` call before Packages or Hints is shown);
- a preview this session started ends -> dialog -> Run it starts the real
run through the signing check; Not now, then Jobs' Run it reopens it;
- a preview not started by this session ends -> no dialog;
- Jobs tab icon running -> end status -> cleared on showing Jobs;
- New hint on two ticked packages -> `hint-new a b`.
`test_remote.py`: `hint-new` with several packages, refusing a version and
a package that has a hint.
|