chadtmiller.com/knotless
git that lives in your Atmosphere account
The pages list the shared steps repositories publish
MergedThis pull indexes releases of @step/<name> packages, reads their one file from the release blobs, and keeps those that parse as step files and name a commit. listSteps and getStep answer from that index. Use counts come from .knotless/uses.lock on each public default branch, read in the same pass as the language count. The pull says the pages are still to come, so it is not finished.
The checks were all still queued when I looked, so I have no results. I could not read the whole diff, because the tool saved it to a file I couldn't open. I read the new index and parsing code (index/shared.rs, shared.rs) and the call site in languages.rs, and checked that the docs and a changeset are present. I did not read the web handlers, the lexicons or the tests.
I found nothing that must change. Two things to consider:
- Unbounded lock size.
read_usesresolves an owner identity for every entry in a lock file, one after another, and writes a row for each. Any public repository controls its ownuses.lock, so a very large one makes every recount do that many lookups. Capping the entries read, or resolving each distinct owner once, would bound it. - Stale counts.
recountreturns early with?when the mirror can't be opened. A repository's old use rows then stay and keep counting.
This round adds the pages on top of the index: a /steps directory with search and a per-repository filter, a step page (/steps/<owner>/<repo>/<step>) with the lines to paste, inputs, secrets, versions and users, a "Shared step" link on release cards, and a shared-steps fact in RepoFacts.
I read the new web code against the stepView and stepViewDetailed lexicons. The fields the pages use (uses, path, commit, inputs, needs, secrets, versions, usedBy, useCount) all exist and match. I found nothing that must change.
Notes:
- No checks have run on this commit, so I have no results for the Svelte or type checks.
- I saw no web-side test for the new pages. The pull body still says "work in progress" and names only
the_steps_shared, so update it to cover the pages. - My two earlier suggestions are not addressed in this commit: the unbounded
uses.locksize inread_uses, andrecountleaving old use rows when the mirror can't be opened. I did not ask for them before, and I don't now. They are still worth doing before the use counts are public.
This round only changes wording and CSS. StepSheet now writes secrets and needs as "a, b and c" and says "Asks for the secret(s) …" or "Asks for no secrets". A small CSS rule makes the version commits show on a phone. plural is still used elsewhere in the file, so the import is not left unused. I found nothing that must change.
No checks have run on this commit, so I have no results.
Still open from earlier rounds, none of it blocking:
read_useshas no limit onuses.locksize.recountleaves old use rows when the mirror can't be opened.- The pull body still says "work in progress" and doesn't mention the pages or any web-side test for them.
This round tidies the step pages. The version list no longer shows each version's age, so the commit link stays visible on a phone. The "And N others" line moves out of the users list into a .hint paragraph. The empty-state titles are reworded, and the empty directory now links to the shared-steps docs page instead of showing a publish command. The lede's max-width now applies only to the step page. The .hint class and the docs page (design/reusable-workflows) both exist, and removing Time and ago leaves no unused imports. I found nothing that must change.
The checks on this commit are still running or queued. docs passed, and I have no results for test, web or lexicons.
Still open from earlier rounds, none of it blocking:
read_useshas no limit onuses.locksize.recountleaves old use rows when the mirror can't be opened.- The pull body still says "work in progress" and doesn't mention the pages.
This round only changes highest_first in web/steps.rs. It now calls sort_by_key instead of sort_by with a comparator. The ordering is the same, because the key is the same Reverse(version). I found nothing that must change.
The check workflow (fmt, clippy) passed on this commit. test, web, lexicons, e2e, shots and docs were still queued, so I have no results for them.
Still open from earlier rounds, none of it blocking:
read_useshas no limit onuses.locksize.recountleaves old use rows when the mirror can't be opened.- The pull body still says "work in progress" and doesn't mention the pages.
9 passed, 1 skipped
What changes
A directory of shared steps, at
/steps. Each step with its name, its repository, what it does, its latest version, how many public repositories use it and how many secrets it asks for, by name, 50 a page, with a search by how a name starts and?repo=<handle>/<name>for one repository's. Empty, it says so in the reader's terms: none yet (with a link to how to publish one), none matching the search, none in that repository, or no index here.A page for each step, at
/steps/<owner>/<repo>/<step>. Theuses:lines to paste, withwith:filled from its required inputs that have no default andsecrets:from what it asks for, thenknotless uses update; its inputs (description, required, default); the secrets and the commands it needs; its versions, the highest first, each with its commit linked; up to 30 of the repositories that pin it, with a count of the rest; and a link to its file at the latest release's commit.Linking in. A repository whose releases include steps says "N shared steps" on its release line, under its name, linking to the directory filtered to it; a step's release on the releases page links to the step's page. Nothing is added to the global header or footer: every page would move for a link most readers do not need yet, and the header is already full on a phone. The directory is reached from those, from each step page's crumbs, and from the docs (Shared steps, Finding a step).
The index. knotless-serve keeps each release of a package
@step/<name>in a new table,shared, keyed by the release's URI with akindcolumn (step), so themes or other kinds can join the directory later. A single background task (shared::follow) reads each release's one file from its blobs on the owner's PDS, checked against the record and kept on disk as release files are, and keeps it as what it says when it parses as a step file (knotless::uses::parse_step) and the release names its commit; any other is kept as not one and never shown. A file the PDS cannot give now is read again at the next start. An index from before gets its step releases fromreleaseonce, as the table is made.Use counts. Read from
.knotless/uses.lockon each public repository's default branch, from the same tree and in the same pass that counts what the repository is written in (languages::recount): when a list first shows it, and again as its refs move. So it is incremental, and costs no mirror sync beyond what language counting already does. Eachusespinned becomes a row inshared_usefor the repository and the step (resolved by the owner's handle or DID and the repository's name), so a repository counts once however many versions it pins. An index from before has its language rows cleared once, so each repository is counted again, its lock with it, as lists next show it.Queries.
dev.knotless.listSteps(repo,q,limit,cursor) answersstepViews;dev.knotless.getStep(repo,name) answers astepViewDetailed, withstepInputView,stepCommandView,stepSecretViewandstepVersionViewindev.knotless.defs. Taken-down accounts, repositories and releases are left out, as are taken-down repositories among a step's users. Every statement reads by an index:shared_name (kind, state, name, did, repo_key)for the directory,shared_repofor one repository's,shared_use_offor counts, and both new tables are inplans::GROWING.Why
Shared steps landed with no way to find one but reading someone's repository. This is the directory "Not built yet" listed (docs/design/reusable-workflows.md). Reading the step file from the release's blob, not the mirror at the commit, matches what
knotless uses updatechecks (the release's file, by hash), and costs one small read per release, kept for good.How it was checked
the_steps_sharedin crates/knotless-serve/tests/web.rs publishes steps (two valid, one whose file is no step file, one with no commit, and a pre-release), reads them through both queries, pages, searches and filters by repository, counts a repository whose lock pins one step twice (and passes by entries naming an unknown owner, an unknown repository and nousesat all), and takes the releases down. Unit tests cover the step file as kept, the latest version, and theusesspec.Pages looked at with
just look, answers given with--setas the recording has none for the new methods: the directory full (long names and handles), empty, empty under a search and for one repository; a step's page full, and with no inputs, no secrets, no commands and no users; the repository's release line and a step's release card. Pictures below: the directory full (desktop light) and empty (phone dark), a step's page (desktop light and phone dark). A critique from fresh eyes led to plainer copy (no colons), commits shown on a phone, and the empty state's command replaced by a link.No page the shots record moves: the world publishes no step, so the repository and releases pages draw as before, and the new pages are not in the world.
Shortcomings
harness/shots/world.mjsand recording is a follow-up.Review
Start at crates/knotless-serve/src/index/shared.rs (tables and queries), then src/shared.rs (reading files and locks) and web/steps.rs.
🤖 Generated with Claude Code