Skip to content

Correct and rewrite the Help panel content - #376

Merged
dovvnloading merged 3 commits into
mainfrom
ux/help-panel-qa
Aug 31, 2026
Merged

dovvnloading merged 3 commits into
mainfrom
ux/help-panel-qa

Conversation

@dovvnloading

@dovvnloading dovvnloading commented Aug 31, 2026 •

Copy link
Copy Markdown
Owner

Problem

The Help panel content was extracted from the Qt build and has not been updated since. Checked against the running app, it is wrong in five places and incomplete in several more.

Incorrect:

  • "Controls toggle" - the control is named View.
  • "Hold Shift and drag a rectangle to zoom the view to a specific region" - Shift-drag is rubber-band selection. No zoom-to-area gesture exists.
  • Plugin listed as "Graphlink-Web" - the picker lists it as Web Research.
  • Pan documented as middle-mouse only - left-drag on empty canvas also pans.
  • Zoom documented as Ctrl+wheel - the wheel alone zooms.

Missing: Gitlink, Global Search, Knowledge, the quick switcher, node filters, branch status, and the Ctrl+P, Ctrl+Shift+C and Ctrl+Shift+M bindings.

The file header declared GENERATED - do not hand-edit and a count of 76 items. The file had been hand-edited and contained 88.

There were no tests covering the panel.

Change

Content:

  • Rewritten and re-sectioned to match the current app: Start Here, The Canvas, Node Types, Finding Things, Organizing, Plugins, The Builder, The Agent, Models and Settings, Saving and Output, Keyboard.
  • "Use Cases" removed. Its three concrete entries moved into Start Here.
  • Entries now state operational limits where they exist: Autopilot executes code without asking, a stopped build cannot be resumed, the sandbox isolates packages rather than the operating system, an agent is scoped to its bound folder.
  • File header replaced with accurate maintenance guidance.

UI:

  • Search added, matching entry titles, body text and key chords. A query replaces the section view rather than filtering within it.
  • keys field added to HelpItem. Chords render as <kbd>, one command per entry, replacing chords spelled into item titles.
  • Item cards replaced with a type-and-space list. Body copy raised off the 11px muted caption treatment, with a measure cap.
  • Rail intro paragraph removed. Rail hover and selected states differentiated - they were the same fill. Dialog title changed from "Help Center" to "Help".

Test plan

  • HelpDialog.test.tsx, new, 15 tests: content invariants; every documented chord resolves through the real resolveShortcut(); every live binding is documented; regression guards for the three stale strings; section switching; <kbd> rendering; five search behaviours including the empty state and Escape handling.
  • npm run check (schema drift, typecheck, lint, vitest, build, bundle size) against a clean checkout of this branch: 2080 pass.
  • Manual: walked all eleven sections, searched by word and by chord, confirmed results carry section context and that selecting a section clears the query.
  • Corrected facts verified in the running app: plain wheel zoom (100% to 152%), left-drag pan, and the plugin picker listing Web Research and Gitlink.

Stacked on #375.

dovvnloading and others added 3 commits August 31, 2026 17:22
ADR-012 stage 12.6 put a full-canvas hint on an empty scene - "Type a
message to start, or load the sample workspace" plus a Load Sample Workspace
button - on the theory that a blank canvas is indistinguishable from a
broken one.

It was painted at --gl-z-canvas-hud (21). That tier exists for the token
counter and the minimap, each of which owns one screen CORNER. This overlay
was `position: absolute; inset: 0`, so it claimed the entire canvas at a
tier ABOVE --gl-z-app-layer (20) - which is every popover anchored over that
canvas: View, Plugins, Pins. Its text and its button painted straight
through all of them, at every window size, whenever the scene was empty.
pointer-events: none kept it from swallowing clicks, but nothing kept it
from being drawn on top.

Removed rather than re-tiered: an empty canvas with a composer waiting at
the bottom of the window does not need a caption explaining that it is
empty.

The loadSampleWorkspace intent and store method are untouched -
OnboardingDialog still offers the sample workspace, in a dialog, which is
where a first-run affordance belongs.

Three E2E specs referenced the overlay. boot.spec asserted it was VISIBLE as
its proxy for "a fresh session has zero nodes" - that is asserted directly
now, which is the state the line was always about. create-node and
workspace-save-reload each dblclick a corner offset rather than the canvas
center, and each carried a comment explaining that the center would land on
the overlay's button; the offsets are kept (the coordinates are arbitrary
either way) and the comments now say why they are no longer load-bearing.
The three unit tests covering the overlay are replaced by one asserting it
does not render.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The View popover was a consolidation of three Qt islands - drag speed, grid
controls, node font - and it consolidated them additively: whatever each
island had, plus whatever the SPA rewrite introduced, stacked in the order
it was written. It read as a port rather than as a panel.

THREE CONTROLS FOR ONE NUMBER. Pan speed rendered a value badge, a slider,
AND a four-button segmented control, all bound to the same setting, stacked
vertically, with nothing saying which was authoritative. Grid spacing did
the same. Grid style rendered its value as a badge directly above a
segmented control that already showed it. This is the port artifact
exactly: the Qt controls offered presets, the SPA rewrite added sliders and
readouts, and nothing was taken away.

Each setting has one control now. The landmark values the backend publishes
are still there and still set the value on click, but as marks on the
slider's own scale rather than as a second widget under it - a third of the
height, and no ambiguity about what drives the number.

READOUTS DRESSED AS BUTTONS. Every value badge was a bordered, inset-filled
999px pill: pixel for pixel the shape of .view-chip, which IS a button. They
are plain right-aligned tabular text now. Nothing that cannot be clicked
looks like it can.

NO SPACING SCALE. Every element carried its own margin - 10 above a field
row, 4 below a slider, 6 above a segment, 10 above a toggle - so no gap
meant the same thing twice and nothing lined up. One rule now: 6px inside a
field, 12px between fields, 16px and a rule between sections. The margin
reset lives in that same rule rather than on each child, because a bare
`margin: 0` on a child ties on specificity with the gap rule and silently
cancels it - which is what had happened to the filter sub-headings.

A TRACK THAT SHOWED NOTHING. The slider track was one flat bar, so the only
cue for a value was thumb position against an undifferentiated line. The
track is filled to the value now, which is what makes a column of sliders
readable at a glance.

OS CHECKBOXES. The toggles were the last engine-drawn controls in the panel,
sitting beside a custom slider, a custom segmented control and a custom
swatch row. The native input stays - all of its keyboard and screen-reader
behaviour with it - and only the paint job is replaced.

SECTIONS BY BRIDGE, NOT BY MEANING. "Snap to Grid" and "Smart Guides" are
drag behaviours and sat under GRID (appearance) because the legacy grid
bridge owned their checkboxes - the same accident that had already put the
connection toggles there. They are in CANVAS now, with pan speed. "Focus
Accepted Paths" was a one-toggle BRANCHES section immediately above FILTER
while doing FILTER's job, so it opens that section instead of preceding it.
Six sections become five.

A FOOTER THAT SCROLLED AWAY. This panel is taller than the popover at every
window size. Reset to Defaults was the last thing inside the scroller, so
reaching it meant scrolling past all twenty-five controls it undoes. The
panel is a fixed shell now - scrolling body, pinned footer.

Also fixed: .view-chip.active used --gl-neutral-button-pressed, a step
DARKER than the idle fill on the dark palette, so a selected chip was the
dimmest in the row and hovering an unselected one lit it brighter than the
selection. Same inverted scale the segmented control had. Shared with the
Chat Library's workspace tabs and tag filters.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Help panel was extracted from the Qt build and had not been maintained
since. Three things it stated confidently were no longer true:

- a "Controls toggle" that reveals drag, grid and font tools. That control
  is called View, and has been for some time.
- "Hold Shift and drag a rectangle to zoom the view to a specific region."
  Shift-drag is rubber-band selection. There is no zoom-to-area gesture, and
  a reader would have tried it and concluded something was broken.
- a plugin called "Graphlink-Web". The picker calls it Web Research.

Plus what was missing. It described panning as middle-mouse only when left-
drag on empty canvas pans too, and zoom as Ctrl+wheel when the wheel alone
zooms - both verified against the running app rather than the source. Gitlink
was absent from the plugin list entirely. So were Global Search, Knowledge,
the quick switcher, the node filters, branch status, and the Ctrl+P /
Ctrl+Shift+C / Ctrl+Shift+M bindings.

CONTENT. Rewritten rather than patched, because the copy had a second
problem the errors were sitting inside: every one of its 88 entries was the
same two even sentences, hedged the same way, telling the reader a feature
"is especially useful when" rather than what it does and where it stops. A
reference page that reads at one pitch is one nobody scans. The rewrite
leads with the fact, gives the key where there is one, and says where things
end - Autopilot does not ask before executing code, a stopped build cannot
be resumed, the sandbox isolates packages and not the operating system, an
agent reaches only the folder you bound it to. That last category is the
part no amount of clicking around discovers, and the part that makes the
rest worth trusting.

Sections were re-cut to match the app as it is: Start Here, The Canvas, Node
Types, Finding Things, Organizing, Plugins, The Builder, The Agent, Models
and Settings, Saving and Output, Keyboard. The old "Use Cases" section - nine
entries of aspirational workflow prose - is gone; the three that said
something concrete live in Start Here now.

The file's header claimed "GENERATED - do not hand-edit" and that it held 76
items. It was hand-edited long ago and had grown to 88, so the only
instruction at the top of the file was false AND discouraging the
maintenance it was already receiving. It now says what it is.

UI. Search, which the panel did not have: ~70 entries across ten sections,
reachable only by guessing which section - the guess the reader has already
failed to make. Typing filters everything at once, matches chords as well as
words (so "ctrl+f" finds canvas search), and each result says which section
it came from. A query replaces the section view rather than filtering inside
it, so an entry can never be counted but not shown.

Key chords were spelled into item titles as prose - "Ctrl + T / Ctrl + L /
Ctrl + S" as one heading for three unrelated commands, unsearchable by
command name and carrying no more weight than the words around them. They
are structured data now, rendered as <kbd>, one command per entry.

Every entry was a filled rounded card: seventy identical grey boxes down the
pane, spending a lot of ink to say "these are separate" about a list nobody
could have confused. Reference content wants type and space, so body copy
moved off the 11px muted caption treatment it shared with tooltips onto
something meant to be read, with a measure cap. The rail's two-sentence
intro - one of positioning, one instructing the reader to use the buttons
directly beneath it - is gone. The rail's hover and selected states were the
same fill; they step now.

TESTS. The panel had none, which is how it drifted. Prose cannot be
type-checked, but the key chords can: every chord in the content is now fed
through the real resolveShortcut(), so a moved binding fails a test instead
of lying to somebody, and a second test asserts every live binding is
documented at all. Guards for the specific rot found here - the old plugin
name, the renamed control, the removed gesture - fail if they return.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dovvnloading
dovvnloading merged commit c8135d6 into main Aug 31, 2026
4 checks passed
@dovvnloading
dovvnloading deleted the ux/help-panel-qa branch August 31, 2026 23:09
@dovvnloading dovvnloading changed the title QA and rewrite the Help panel Correct and rewrite the Help panel content Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant