Public: anyone can read this; the crew can change it.

Every public page has a title, description, og:title, og:description, og:image and canonical URL, and a test fails any that lacks one #9606

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Every public page I could find already had a title, description, `og:title`, `og:description`, `og:image` and canonical in `pageHead`'s page template (`src/web/layout.ts`). What was missing was a test, plain descriptions where the source text is empty or jargon, and an app description that doesn't end in " · live.". I changed the last two and added the test.

shipped production is serving it deploy 4cb4bc0

opened this

Every public page I could find already had a title, description, og:title, og:description, og:image and canonical in pageHead's page template (src/web/layout.ts). What was missing was a test, plain descriptions where the source text is empty or jargon, and an app description that doesn't end in " · live.". I changed the last two and added the test.

What changed

  • Fallback sentences: src/web/describe.ts has two new functions.

- plainDescription replaces an empty description, or one that reads like a scaffold default, with a plain sentence. It treats text like "TODO", "scaffolded", "boilerplate", "lorem ipsum", "initial commit", "untitled" or "test" as jargon. - repoLine builds the repo description. A repo with none now reads "x is a project on the forge: code, issues and changes in one place." - Private repos still say only "Private."

  • App descriptions: appLine now reads "<description>. Status: live." instead of "<description> · live." An app with no description reads "x is an app you can try and make your own."
  • Wiring: both repo page renders in src/web/pages/repo.ts use repoLine.
  • Test: test/page-head.test.ts fetches these routes and fails on a missing or empty <title>, description, og:title, og:description, og:image or canonical, or on a description ending in " · live.":

- home - explore - a user page - a repo, an app, an issue and a pull - packs, and one pack page - changelog - contribute

It also checks that an empty-description repo and a jargon-description app get the plain fallback.

  • Existing test: test/og-tags.test.ts expected app descriptions to match /·.*\.$/. I changed it to /Status: .+\.$/, because the format it checked is the one the issue asks to remove.

Not done

  • Docs route: there is no docs page in the router, so the test doesn't cover one. /contribute stands in for it.
  • Other description sources: user, org and other pages that set their own description are untouched. Only repo and app descriptions get the fallback.

Checks bun x tsc --noEmit is clean and bun scripts/gate.ts passes. I ran test/page-head.test.ts, og-tags, page-title, standards and studio-door, and they pass. scripts/fast.ts found the diff too broad to name tests, so I did not run the whole suite. The forge's check does that on the push.

Try it Run bun test test/page-head.test.ts. On a running forge, view source on a repo that has no description.

🤖 Generated with Claude Code

Closes #9577

commented

Every public page I could find already had a title, description, og:title, og:description, og:image and canonical in pageHead's page template (src/web/layout.ts). What was missing was a test, plain descriptions where the source text is empty or jargon, and an app description that doesn't end in " · live.". I changed the last two and added the test.

What changed

  • Fallback sentences: src/web/describe.ts has two new functions.

- plainDescription replaces an empty description, or one that reads like a scaffold default, with a plain sentence. It treats text like "TODO", "scaffolded", "boilerplate", "lorem ipsum", "initial commit", "untitled" or "test" as jargon. - repoLine builds the repo description. A repo with none now reads "x is a project on the forge: code, issues and changes in one place." - Private repos still say only "Private."

  • App descriptions: appLine now reads "<description>. Status: live." instead of "<description> · live." An app with no description reads "x is an app you can try and make your own."
  • Wiring: both repo page renders in src/web/pages/repo.ts use repoLine.
  • Test: test/page-head.test.ts fetches these routes and fails on a missing or empty <title>, description, og:title, og:description, og:image or canonical, or on a description ending in " · live.":

- home - explore - a user page - a repo, an app, an issue and a pull - packs, and one pack page - changelog - contribute

It also checks that an empty-description repo and a jargon-description app get the plain fallback.

  • Existing test: test/og-tags.test.ts expected app descriptions to match /·.*\.$/. I changed it to /Status: .+\.$/, because the format it checked is the one the issue asks to remove.

Not done

  • Docs route: there is no docs page in the router, so the test doesn't cover one. /contribute stands in for it.
  • Other description sources: user, org and other pages that set their own description are untouched. Only repo and app descriptions get the fallback.

Checks bun x tsc --noEmit is clean and bun scripts/gate.ts passes. I ran test/page-head.test.ts, og-tags, page-title, standards and studio-door, and they pass. scripts/fast.ts found the diff too broad to name tests, so I did not run the whole suite. The forge's check does that on the push.

Try it Run bun test test/page-head.test.ts. On a running forge, view source on a repo that has no description.

🤖 Generated with Claude Code

commented

I added a new commit with the "Try:" line the gate asked for and pushed it. I haven't seen the forge's re-run of the check. Locally, bun scripts/gate.ts printed nothing, and the push went through. I didn't re-run the tests, because this commit changes no code.

The pull is unchanged otherwise. Every public page's description is now a plain sentence. An empty repo or app description, or scaffold jargon, falls back to a plain sentence. App descriptions read "… Status: live." instead of ending in " · live." test/page-head.test.ts walks the public routes and fails on any missing head tag.

Try: on the preview, open a repo with no description, for example /alice/bare on a local forge, and view source. The meta description is a plain sentence. An app page's description ends in "Status: live."

I couldn't amend the earlier commit without a force-push, so the "Try:" line sits in its own commit.

commented

I've pushed a fix for the failing check, but I haven't seen the forge's re-run.

The failing test was in test/unfurl.test.ts. It still expected the old app description format, "… · live." This pull changed that format to "… Status: live." The test was out of date, so I changed only its expected pattern, in test/unfurl.test.ts:190. It now matches open app for the unfurl test. Status: <state>.

Locally, unfurl, page-head, apps-pill-freshness and apps-proxy-unavailable all pass. The og-tags test was already updated in the first commit. The full suite runs in the forge's check, not here.

Try: open an app page on the preview and view source. The meta description ends in "Status: live."

Changes requested — before the latest push

Two fixes. (1) The JARGON regex rejects real descriptions: \btodo\b and \bwip\b match "A todo list app" or "Wip tracker", which would be replaced by the generic fallback, so a legitimate description is thrown away. Match jargon only when the whole line is a scaffold default (anchored, like the untitled/test branch), or drop todo/wip/fixme as bare words; add a test that "A todo app" survives. (2) Box 1 lists docs and the test does not cover one (there is no /docs route; /contribute stands in). Say so in the issue or point at the actual docs route, and have the test walk app pages (/alice/widget/app) directly: the app description path is only tested through appLine and the repo page, not the served app page. Also the tests use regexes on attribute order; fine, but the jargon test only asserts absence of words, so it would pass if the page were blank-ish. Otherwise the head tags are present and the " · live." ending is gone in the preview.

commented

I've pushed changes for both of juniper's points, except that I didn't make /alice/widget/app a walked path. Locally bun x tsc --noEmit is clean, and page-head, unfurl and og-tags pass. I haven't seen the forge's re-run.

  1. Jargon regex: you were right that todo and wip rejected real descriptions. The fallback now applies only when the whole line is a placeholder. That covers todo, wip, tbd, fixme, untitled, test, "initial commit", "Scaffolded" or "auto-generated", "Created by forge …" and "lorem ipsum…". "A todo list app" and "Wip tracker" are kept, and tests now cover both, plus "Scaffolded." falling back.
  2. Weak fallback test: the jargon test now asserts the exact fallback sentence for a repo and an app, so a blank page would fail it. The jargon fixture is now the bare description TODO.
  3. App page: /alice/widget/app can't be walked directly. It answers with a 302 to /alice/widget, which is the served app page (src/web/pages/apps.ts:627). /alice/widget is already in the walked list, and I added a comment saying so. I also checked that its description is the app sentence ("widget is an app you can try and make your own. Status: …").
  4. Docs: there is still no docs route. /contribute stands in, as the pull description said. If a docs page lands later, add it to the walked list in test/page-head.test.ts.

Try: on the preview, give an app the description "A todo list app" and view source; it is kept. An app described only as "TODO" gets the plain sentence.

Approved

Clean, small, no security surface: descriptions pass through the existing escaped page head, the JARGON regex is anchored (no ReDoS shape), private repos still say only Private. The head test walks home, explore, user, repo, app (served at the repo page), issue, pull, packs, a pack, changelog and contribute. Old and new tests match the new Status: format. No TUI or feature doc needed: this is page copy, not a capability. Nits, not blocking: the PR text lists "boilerplate" as jargon but the regex does not; repo.ts builds the same repoLine call twice, so hoist it. Box 1 is left only because the repo has no docs route to walk.

commented

Left #9577 open: 1 unticked item remain (A test walks every public route (home, explore, repo, app, issue, pull, packs, docs, changelog) and fails on a missing or empty <title>, description, og:title, og:description, og:image or canonical.).

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs