The Tools tab rendered every schema-portability finding, always open, above the argument form. On a server whose schemas are broadly unportable that put the same wall of text ahead of every tool's first input — and the findings address the server author, not the caller trying to fill the form. The section now opens collapsed behind the same disclosure heading the Skills pane's Conformance section uses, with an `N error(s), M warning(s)` badge. The expand choice is global rather than per tool (`useSchemaFindingsExpanded`, stored as `inspector.schemaFindings.expanded`): this panel is reused across selections, so a per-tool disclosure would re-collapse on every click and reproduce the same scrolling. The badge stays visible while collapsed and the tool-list severity icon is untouched, so nothing about a tool's standing is hidden by the closed state. Two neighbouring fixes on the same panel: - `JsonEditor` frames Ace in a bordered `Paper`. Ace paints its background edge to edge with nothing around it, so "Edit as JSON" replaced a column of bordered inputs with one borderless slab. - `ToolDetailPanel`'s body `ScrollArea` overrode the app-wide `type="scroll"` default with `type="auto"`, parking a permanent bar down the side of any tool whose form is taller than the panel. `offsetScrollbars` stays, so the form does not shift sideways when the bar fades in. `test-servers/configs/unportable-schemas-many-http.json` reproduces the original complaint: the same four presets as `unportable-schemas-http.json` carrying 26 findings rather than 5. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DU3QYnc95g6EM4vo3hYNet Signed-off-by: cliffhall <cliff@futurescale.com>
54 lines
2.2 KiB
TypeScript
54 lines
2.2 KiB
TypeScript
import { useLocalStorage } from "@mantine/hooks";
|
|
|
|
/**
|
|
* Whether the tool detail panel's schema-portability section is expanded
|
|
* (#2205).
|
|
*
|
|
* The preference is **global rather than per tool**, and that is the whole
|
|
* point of the issue: the findings sit above the argument form, so on a server
|
|
* whose schemas are broadly unportable every tool selection put a wall of
|
|
* identical text between the user and the first input — 26 findings across
|
|
* four tools in `unportable-schemas-many-http.json`, none of which the caller
|
|
* needs in order to fill the form. A per-tool disclosure would have to be
|
|
* re-collapsed on every selection, which is the same scrolling by another
|
|
* route.
|
|
*
|
|
* Collapsed is the default. Nothing is lost by it: the summary line still
|
|
* names the counts, the tool list still carries its per-tool severity icon,
|
|
* and one click re-opens the detail — for the whole session and every later
|
|
* one, since the choice persists.
|
|
*/
|
|
const SCHEMA_FINDINGS_EXPANDED_DEFAULT = false;
|
|
|
|
/** localStorage key. Shares the `inspector.<kind>.<scope>` namespace the other
|
|
* UI preferences use, so the whole group is easy to inspect or clear in bulk. */
|
|
export const SCHEMA_FINDINGS_EXPANDED_KEY = "inspector.schemaFindings.expanded";
|
|
|
|
/**
|
|
* Stores the boolean as `"true"` / `"false"` rather than Mantine's default
|
|
* `JSON.stringify`, matching the sort/compact adapters in `InspectorView`:
|
|
* the persisted value stays human-readable, and anything else — a manual edit,
|
|
* a value written by an older build — clamps back to the default instead of
|
|
* silently coercing to `false`.
|
|
*/
|
|
function deserialize(raw: string | undefined): boolean {
|
|
if (raw === "true") return true;
|
|
if (raw === "false") return false;
|
|
return SCHEMA_FINDINGS_EXPANDED_DEFAULT;
|
|
}
|
|
|
|
function serialize(value: boolean): string {
|
|
return value ? "true" : "false";
|
|
}
|
|
|
|
export function useSchemaFindingsExpanded() {
|
|
return useLocalStorage<boolean>({
|
|
key: SCHEMA_FINDINGS_EXPANDED_KEY,
|
|
defaultValue: SCHEMA_FINDINGS_EXPANDED_DEFAULT,
|
|
deserialize,
|
|
serialize,
|
|
// Read synchronously on first render — SPA only, no SSR — so a persisted
|
|
// "expanded" does not flash through the collapsed default.
|
|
getInitialValueInEffect: false,
|
|
});
|
|
}
|