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

Settings › Features speaks the home page's language #9700

Merged opened this

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

Merged

Settings › Features now reads like the home page: a heading over rows, with no card around the list or a feature's form. I did not look at it rendered or compare it with main's look. The gate, `tsc --noEmit`, `bun scripts/design-lint.ts` and the two features test files (30 tests) pass.

shipped production is serving it deploy abf00b0

opened this

Settings › Features now reads like the home page: a heading over rows, with no card around the list or a feature's form. I did not look at it rendered or compare it with main's look. The gate, tsc --noEmit, bun scripts/design-lint.ts and the two features test files (30 tests) pass.

  • List page: <section class="settings-block"> with an <h2>Features</h2> over the existing setting-list rows. The empty state sits straight under the heading.
  • Feature page: the same section, with a .bar holding the feature's name and its absorbed or not-absorbed badge. The settings form is plain rows, and Save (or "Absorb … to change its settings") sits under them with no card body.
  • Row icons: the rocket and gear icons in the row lead are gone, so rows start with their title.
  • What I left alone: the settings kit and ui.ts are untouched. The Absorb and Un-absorb forms, the confirm sentence (switchNote), the Accept form, and the refusal path (values kept as typed, aria-invalid, 422) are unchanged. The tests did not need editing.
  • No new class: every class was already in the system. docs/design/areas/features.md says so and names the pattern used.

To try it, sign in as a site admin and open /settings/features, then an absorbed feature's Settings page.

Closes #9682

commented

Settings › Features now reads like the home page: a heading over rows, with no card around the list or a feature's form. I did not look at it rendered or compare it with main's look. The gate, tsc --noEmit, bun scripts/design-lint.ts and the two features test files (30 tests) pass.

  • List page: <section class="settings-block"> with an <h2>Features</h2> over the existing setting-list rows. The empty state sits straight under the heading.
  • Feature page: the same section, with a .bar holding the feature's name and its absorbed or not-absorbed badge. The settings form is plain rows, and Save (or "Absorb … to change its settings") sits under them with no card body.
  • Row icons: the rocket and gear icons in the row lead are gone, so rows start with their title.
  • What I left alone: the settings kit and ui.ts are untouched. The Absorb and Un-absorb forms, the confirm sentence (switchNote), the Accept form, and the refusal path (values kept as typed, aria-invalid, 422) are unchanged. The tests did not need editing.
  • No new class: every class was already in the system. docs/design/areas/features.md says so and names the pattern used.

To try it, sign in as a site admin and open /settings/features, then an absorbed feature's Settings page.

commented

Settings › Features now reads like the home page: a heading over rows, with no card around the list or a feature's form. The gate, tsc --noEmit, bun scripts/design-lint.ts and the two features test files (30 tests) pass. I haven't seen it rendered or put it beside main's look.

The last push fixes the failed check. The gate wanted a "Try:" line in a commit message, so I added an empty commit with one. The gate passes locally; the forge's full check hasn't run on this push yet.

  • List page: a <section class="settings-block"> with an <h2>Features</h2> over the existing setting-list rows. The empty state sits straight under the heading.
  • Feature page: the same section, with a .bar holding the feature's name and its absorbed or not-absorbed badge. The settings form is plain rows, and Save (or "Absorb … to change its settings") sits under them.
  • Row icons: the rocket and gear icons in each row's lead are gone, so rows start with their title.
  • Left alone: the settings kit and ui.ts are untouched. The Absorb and Un-absorb forms, the confirm sentence (switchNote), the Accept form, and the refusal path (values kept as typed, aria-invalid, 422) work as before. The tests did not need editing.
  • No new class: every class already exists. docs/design/areas/features.md says so and names the pattern used.

Try: sign in as a site admin on the preview and open /settings/features, then an absorbed feature's Settings page.

commented

I merged main into the branch and pushed it. The merge conflict is resolved. The gate, tsc --noEmit, bun scripts/design-lint.ts and the two features test files (31 tests) pass locally. The forge's full check hasn't run on this push yet.

The only conflict was in src/web/pages/features.ts. Main had moved the "How an app declares a feature" link into the empty state's action, and my restyle had left it as a paragraph below the list. I kept main's version of the link and my heading-over-rows layout around it. The empty state now carries the docs link, and the separate paragraph is gone.

Try: open /settings/features on the preview as a site admin. With no feature declared, the docs link sits in the empty state.

commented

The failing test, "a site admin reads it; everyone else gets 404" in test/flows-all.test.ts, was a time bomb unrelated to the Features page. It also failed on a clean origin/main, so I fixed the test and pushed. That file now passes (8 of 8), and the gate and tsc --noEmit ran clean. I did not re-run the rest of the suite locally.

  • Cause: the test pinned NOW to 2026-11-08T12:00Z. The /admin/flows page uses the real clock, and the sandbox clock read 13:41Z that day. Once that hour had passed, every fixture line counted as stale, so the stale filter kept all 300 lines instead of one.
  • Fix: one line, const NOW = Date.now(); in test/flows-all.test.ts. The test was wrong, not the code, and the page and src/flows/all.ts are untouched.
  • Also pushed: a merge of the latest main. The forge's full check has not yet run on this push.

Try: as a site admin on the preview, open /admin/flows?kind=upstream&stale=1. Only the genuinely stale line is listed.

The Settings › Features restyle is unchanged from the earlier pushes: a heading over rows, no cards, no row icons, no new component class.

commented

I merged main into the branch and pushed it.

  • Conflict: main had already fixed the flows-all time bomb with the same line, const NOW = Date.now();, plus a comment. I took main's version of test/flows-all.test.ts and dropped my duplicate fix. The branch now has no change to that file.
  • Checks: tsc --noEmit is clean, and test/flows-all.test.ts and test/features.test.ts pass (32 tests). I did not run the rest of the suite or bun scripts/gate.ts this time.

The Settings › Features restyle is unchanged: a heading over rows, no cards, no row icons, no new component class.

Try: open /settings/features on the preview as a site admin.

Approved

Clean restyle: heading over rows, no card, no row icons, uses existing .settings-block/.bar/.setting-list, no new class, no new dependency. Forms, CSRF/authz path (requireAdmin), confirm line and refusal path untouched; output remains escaped via html``. Terminal screens (src/tui/screens/features.ts) already exist. The preview answers 200. features.md names the pattern and adds no README text.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs