feat(native): auto-generated UI for Configurable settings via inventory registry#232
feat(native): auto-generated UI for Configurable settings via inventory registry#232cooper (czxtm) wants to merge 2 commits into
Conversation
…ry registry
Adding a new field to a Configurable struct now automatically appears in
the Tuning section of the Developer settings tab — no frontend changes
required. Schema metadata (label, type, range, defaults, help text) is
emitted by the derive and consumed by a generic <AutoConfigField> React
component.
How it works:
1. The configurable runtime crate gains schema types (ConfigurableSchema,
ConfigField, FieldType, EnumVariant) that flow to TS via specta. A
type-erased RegisteredConfig holds fn pointers per struct; the derive
submits one to a global inventory at compile time.
2. The derive parses an expanded attribute grammar:
#[config(
store_path_fn = ...,
display_name = "Evolution",
description = "...",
)]
pub struct EvolutionLimits {
#[config(
default = 25,
key = "maxIterations",
label = "Max iterations",
range = 1..=200,
help = "API calls before stopping",
)]
pub max_iterations: usize,
}
FieldType is inferred from the Rust type: numeric primitives become
Number{min,max}, bool becomes Boolean, String becomes String{multiline}.
Any field annotated with #[config(options = ["a", "b"])] becomes an
Enum regardless of its Rust type — labels are humanized from the
variant values.
3. Each struct's derive generates:
- load<R>(app) — read all fields with defaults
- schema<R>(app) — full schema + current values
- set_field<R>(app, k, v) — type-checked single-field write
- Wry-monomorphic shims for the fn pointers in RegisteredConfig
4. Two Tauri commands wrap the registry:
- dev_configs_list — walks inventory, returns Vec<Schema>
- dev_config_set — dispatches by struct name to set_field
5. <AutoConfigField> renders the right control per FieldType.kind:
number → <Input type="number" min/max>, boolean → <Switch>,
string → <Input> (or <Textarea> when multiline), enum → <Select>.
Help text becomes a tooltip on an info icon.
6. <AutoTuningSection> calls dev_configs_list once, renders a section
per registered struct, and writes via dev_config_set. Replaces the
~85 lines of hand-written Tuning JSX in developer-tab.tsx with
<AutoTuningSection />.
Type-checking on set: the generated set_field round-trips the incoming
JSON value through the declared Rust type before writing. An out-of-range
or wrong-type value surfaces as an Error in the UI inline beneath the
field rather than corrupting the store.
Storybook compatibility: AutoTuningSection treats a null response from
invoke as "no registered configs" (Tauri commands aren't real in
storybook), so the snapshot still renders cleanly.
Closes: nixmac-93p
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
📋 PR Overview
🔬 Coverage
|

Summary
Test Plan
Docs