fix: accessible names for the authorization-parameter rows (#2018)

Copilot round 2 (suppressed comments). Five of the seven findings were the
accessibility of the new row list and one stray cast; all are addressed here.

- The reserved-key reason is now the key input's `error` **string** rather than
  a bare boolean plus free-standing text. Mantine renders it in the input's own
  error slot and wires the `aria-describedby` association, so a screen reader
  learns *why* the field is invalid; a boolean only set `aria-invalid`. This
  also deletes the duplicate `ReservedParamError` text and its Stack wrapper.
- Each control carries a per-row `aria-label` — the section heading and the
  placeholders are not programmatically associated with the inputs, so the key
  box, the value box, and a remove button announcing only "X" were
  indistinguishable to assistive technology. The label names the row by its key,
  falling back to "row N" while the key is still blank.
- Dropped an unnecessary `as unknown as Record<string, unknown>` in the
  servers-route integration test: `MCPConfig.mcpServers` is already typed as
  `Record<string, StoredMCPServer>`, so the entry's `oauth` reads directly.

Three tests cover the new behavior (accessible names, the blank-key row-number
fallback, and the aria-describedby association), each verified to fail against
the pre-fix component. No change to the reserved-key rule or the EMA boundary.

Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-15 21:28:59 -04:00
commit 55734f3776

View file

@ -471,9 +471,8 @@ describe("/api/servers routes", () => {
}),
});
expect(res.status).toBe(200);
const stored = readConfig(h.configPath).mcpServers
.authparams as unknown as Record<string, unknown>;
expect(stored.oauth).toEqual({
const stored = readConfig(h.configPath).mcpServers.authparams;
expect(stored?.oauth).toEqual({
authorizationParams: { kc_idp_hint: "corp" },
});
});