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

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

The pages list the shared steps repositories publish

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:web/steps

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>. The uses: lines to paste, with with: filled from its required inputs that have no default and secrets: from what it asks for, then knotless 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 a kind column (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 from release once, as the table is made.

Use counts. Read from .knotless/uses.lock on 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. Each uses pinned becomes a row in shared_use for 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) answers stepViews; dev.knotless.getStep (repo, name) answers a stepViewDetailed, with stepInputView, stepCommandView, stepSecretView and stepVersionView in dev.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_repo for one repository's, shared_use_of for counts, and both new tables are in plans::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 update checks (the release's file, by hash), and costs one small read per release, kept for good.

How it was checked

the_steps_shared in 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 no uses at all), and takes the releases down. Unit tests cover the step file as kept, the latest version, and the uses spec.

Pages looked at with just look, answers given with --set as 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

  • The new pages are not in the shots world, so the shots check does not draw them; adding a step release and a lock to harness/shots/world.mjs and recording is a follow-up.
  • A repository is counted only once a list has shown it, as languages are, so a use count can lag for a repository nobody has listed.
  • No sort by use count: sorting every step by a count would read them all, so the directory is by name.

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

steps-desktop-light.png

steps-empty-phone-dark.png

step-desktop-light.png

step-phone-dark.png

Approved

This 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_uses resolves an owner identity for every entry in a lock file, one after another, and writes a row for each. Any public repository controls its own uses.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. recount returns early with ? when the mirror can't be opened. A repository's old use rows then stay and keep counting.
Approved

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.lock size in read_uses, and recount leaving 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.
Approved

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_uses has no limit on uses.lock size.
  • recount leaves 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.
Approved

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_uses has no limit on uses.lock size.
  • recount leaves old use rows when the mirror can't be opened.
  • The pull body still says "work in progress" and doesn't mention the pages.
Approved

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_uses has no limit on uses.lock size.
  • recount leaves old use rows when the mirror can't be opened.
  • The pull body still says "work in progress" and doesn't mention the pages.
Merged as 376bf71