Part of #54, but independent — this is a privacy bug, not a styling gap, and should ship first.
Problem
TextField.Variant is silently dropped by renderTextField (render/fields.go:51-75): the renderer reads label/value but never the variant. The basic catalog defines shortText / longText / number / obscured — and obscured is the password/secret case. Today a model that correctly asks for a secret with "variant": "obscured" gets the typed value echoed to the terminal in cleartext, both while editing and in the rendered value readout.
Fix
- When
Variant == "obscured": echo the value as mask characters (• per rune) in both the display state and the editing state. The real value is still stored and still returned by FieldValues() — masking is display-only.
- Add a fixture + test pinning that the raw rendered output never contains the typed value for an obscured field.
- The other variants (
number, longText, shortText) remain display-equivalent for now; document that in docs/wire-format.md (see the hint-audit docs issue).
Notes
Worth auditing FieldValues() consumers in hosts afterward: the value legitimately flows back to the agent on submission (that's the point of the field), but hosts may want to redact it in any human-readable submission prompt they synthesize.
Part of #54, but independent — this is a privacy bug, not a styling gap, and should ship first.
Problem
TextField.Variantis silently dropped byrenderTextField(render/fields.go:51-75): the renderer reads label/value but never the variant. The basic catalog definesshortText/longText/number/obscured— andobscuredis the password/secret case. Today a model that correctly asks for a secret with"variant": "obscured"gets the typed value echoed to the terminal in cleartext, both while editing and in the rendered value readout.Fix
Variant == "obscured": echo the value as mask characters (•per rune) in both the display state and the editing state. The real value is still stored and still returned byFieldValues()— masking is display-only.number,longText,shortText) remain display-equivalent for now; document that indocs/wire-format.md(see the hint-audit docs issue).Notes
Worth auditing
FieldValues()consumers in hosts afterward: the value legitimately flows back to the agent on submission (that's the point of the field), but hosts may want to redact it in any human-readable submission prompt they synthesize.