~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
176 lines · 9.1 KB Raw History

name: ui description: Build or change knotless's web pages (web/) so they look right, not only work. Use for any change to a page, component or style under web/. Look at every state of what you touch with just look before pushing, hold it to the house rules here, and have it critiqued by eyes that did not write it.

Building knotless's pages

The shots check says what moved; it does not say whether what moved is good, and it only ever draws the states the recorded world happens to hold. A page nobody looked at shows it: a filter that empties a list leaves a bare sentence about the wrong thing, jammed against the controls above it. So look, at every state, before pushing.

AGENTS.md has the mechanics (tokens, component layers, popovers, inline text). This is how the pages should read, and how to check they do.

Looking

just look draws pages as this checkout does, from harness/shots/fixtures.json, with no PDS, and writes pictures to target/look for you to open with Read. It builds web/ first; run node harness/shots/look.mjs ... to skip the build when it is fresh.

just look pull-open                        # a page by name, desktop light + phone dark
just look '/alice.test/tally/issues?state=closed'   # any path
just look / --signed-in                    # as alice.test, logged in
just look / --set 'getFeed.events=[]'      # what a method answers, changed
just look issues --set 'listItems.items.0.title="A title long enough to wrap twice over on a phone and then some"'
just look repository --signed-in --click 'header details.popover summary'
just look pull --element .merge-box --all  # one element, in all four
just look check --as bob.test --click 'details.rerun-menu>summary'  # as another account
just look / --set 'getFeed.events=@feed.json'   # an answer from a file: every kind of line at once
just look / --set 'getViewer.login=true' --click 'header [popovertarget=login]' --type '#login-handle=chadtm'  # typed into, then shot
just look org-members --as bob.test --click '.org-invitation .btn.primary' --hold setOrgMembership  # a write left under way: its button busy
just look issue --phone --dark --webkit    # in WebKit, as Safari and every iPhone browser draw it

--webkit draws in Playwright's WebKit rather than Chromium, for a layout that wraps or overflows only on an iPhone; its pictures end -webkit. That WebKit is Linux's, not iOS's: it paints no custom highlights (code is drawn uncoloured), so a highlighting bug seen on an iPhone can't be seen in it.

It says when a page is wider than the screen, naming the element that runs past the edge: fix that before anything else, as the page then scrolls sideways on a phone. With --click it centres what it clicks and shoots the screen, not the whole page, as a menu is seen.

Quote --set's argument: the shell takes [] for a glob. An answer --set changed is held to its method's lexicon, as the server's are, and one that is not as it says fails the run, naming what is wrong: a page is only judged on an answer the server could give. The tool names the methods each page asked for; a --set of any other changes nothing, and it says so and exits 1. A path that was not recorded is answered from the same method's answer for another path, which it also says. A page new to the world needs it in harness/shots/world.mjs and just shots-record; until then, --set can fill in its answers.

Without a checkout

In a chat with only the knotless MCP, the runner looks instead, at a branch: commit the change to it, then ask for the look workflow there with LOOK as just look's arguments, quoted as a shell would, and read its pictures back.

rerun   repo: chadtmiller.com/knotless, ref: refs/heads/<branch>, workflow: look,
        env: {LOOK: "profile --phone --set 'getProfile.links=[{\"url\":\"https://example.com\"}]'"}
checks  repo: chadtmiller.com/knotless, ref: refs/heads/<branch>, workflow: look,
        wait: 60, log: true, images: true

It installs and builds the branch's web/ first, so a look takes about two minutes: ask knotless run list again, waiting 60 seconds at a time, as a longer wait can outlast the MCP call itself. The pictures come back 12 at most: ask for that many. What look says, a page wider than the screen or a --set that changed nothing, is at the end of the log. Answers go inline in --set; one too long for that can be committed as a file and given as @path, and taken out before the pull lands. A page whose query is new has no recorded answers: give them with --set until just shots-record records them.

The states to look at

For every list, page or component you touch, each that applies:

  • Full, as recorded, and many: rows that wrap, a long run.
  • Empty, and empty under each filter, tab or chip it has.
  • One, where a plural or a rollup could read wrong.
  • Long text: a long handle, repository name, title, branch, label.
  • Signed out and signed in (--signed-in), owner and not.
  • Phone and dark: the defaults draw desktop light and phone dark.
  • Busy: each button that writes, pressed and its write held (--hold <method>): the spinner and its words in place, the rest dimmed.
  • Open: every menu, popover and dialog it has (--click), on a phone as well. There a menu with much in it (a list to search, a form) is a sheet over the dimmed page; a few actions drop down under their button. Judge where it opens against what was tapped, not only that it fits.
  • Every kind of row a list draws, when its rows differ by kind (the feed's pushes, rollups, stars, comments): one --set ...=@file.json answer holding each, with long names, on a phone.

Look at a sibling page beside yours (below), so the new one matches it rather than inventing.

House rules

Case. Sentence case everywhere: tabs, chips, buttons, menu items, links in the header and menus, headings, column heads, field labels, dialog titles, as much as notes and errors ("New issue", "Getting started", "Log out", "Blocked accounts"). Only the first word and proper nouns take a capital: days and months, Atmosphere, Bluesky, PDS, DID. Labels end with no full stop; what is said, a sentence, ends with one. Names stay as they are written: knotless, handles, repositories, branches, files, commands, labels such as kind/bug. No text-transform to change case: write the label as it should read.

Empty states. Say what is empty, in the terms the reader chose: with Issues picked, "No issues yet" or "No issues in the last N events", not the page's general blurb. Offer the way out when there is one (all kinds, everyone's, a clear filter). A list's empty state goes where its rows would, as .empty does in ItemList's box, not as loose text.

Space. Every block stacked on another has a gap from the space scale between them; text never touches a row of controls. Things that belong together sit closer than things that do not: a heading to its list, less than the list to the next section.

Consistency. A thing done on two pages is done the same way on both: the same component where one exists (look in web/src/lib before making one), the same words for the same act, the same order of controls. Counts, times, people and repositories are drawn by their atoms and molecules, never by hand.

Icons. Where people go and act: tabs, menu items, header controls, and buttons such as Fork and Star, each with its Octicon from lib/icons.ts, the same icon for the same thing on every page (a pull is pull wherever it is). Not in sentences, nor on every row of a list: there, the avatar or state mark is enough. An icon shown without its word still says it, by aria-label or a hidden label. Tabs keep their words beside their icons on a phone too, and a row too long scrolls.

Weight. One primary button on a view at most. Quiet what is said about a thing (--mute, --text-sm) next to the thing itself.

Pages to match

  • A list with filters: issues, pulls (ItemList in its box, the search and filter menus above).
  • One item with its discussion: issue, pull.
  • A repository's pages: repository, commits, file, under RepoPage's header and tabs.
  • An account: profile, profile-repos, profile-activity.
  • Settings: the settings routes under SettingsPage.

Critique

You read your own pictures kindly. Before pushing a change that moves a page, hand the pictures to an agent that did not write it: the Agent tool, a fresh one, given the paths under target/look (and a sibling page's), this file's House rules, and only this question: "What looks wrong, out of place, or unlike its siblings here? Be specific: element, what is wrong, which rule." Not the code, nor what you meant: it judges what is drawn. Fix what it finds, or say in the pull why not.

Then

Push, and the pull's shots check draws what moved against main. Name the pages you meant to move on its Shots-moved: line; any other that moved is a mistake to fix.

A state the check does not draw (a menu open, an edit box, a list emptied by a filter) it cannot show the reviewer: give the pull your just look pictures of it, each as an --image to knotless pull create or knotless pull edit, as AGENTS.md says.