From 2a6551c572c57a163e4fe063d3e80098ec7fae4e Mon Sep 17 00:00:00 2001 From: Jer Miller Date: Mon, 22 Jun 2026 09:35:43 -0600 Subject: [PATCH] fix(settings): commit sol-identity name on Enter; type all settings-form buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "sol identity" agent-name field reset to "sol" when the owner pressed Enter. Its form's only button ("reset to default") had no `type`, so it defaulted to `type="submit"`, and pressing Enter in the lone text input triggered an implicit form submission that clicked it — firing the reset-to-default handler and persisting the reset server-side (`onsubmit="return false;"` cancels only navigation, not the dispatched click). The agent-name input was also the one settings text input without a `data-section`, so it was excluded from the generic Enter-to-save handler — which is why Enter didn't commit here like it does in every other box. - Give all three untyped settings-form buttons an explicit `type="button"` (resetAgentName, createPersonalBtn, redactAddBtn) so Enter can never fire an implicit submit. redactAddInput keeps its own dedicated Enter→add handler, so Enter-to-add there is unaffected. - Add an Enter→blur handler to the agent-name input so Enter commits the typed name via the existing change-listener save path, matching every other settings text box. - Regression guard: an HTMLParser-based test asserts no button inside a settings-form lacks an explicit `type`, plus targeted tests pinning the agent-name and redact Enter behaviors. Reported by a Linux tester (batch #9). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../settings/tests/test_workspace_html.py | 71 +++++++++++++++++++ solstone/apps/settings/workspace.html | 13 +++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/solstone/apps/settings/tests/test_workspace_html.py b/solstone/apps/settings/tests/test_workspace_html.py index 9b0ca5c4a..2789cb7f8 100644 --- a/solstone/apps/settings/tests/test_workspace_html.py +++ b/solstone/apps/settings/tests/test_workspace_html.py @@ -4,6 +4,7 @@ from __future__ import annotations import re +from html.parser import HTMLParser from pathlib import Path WORKSPACE = Path(__file__).resolve().parents[1] / "workspace.html" @@ -24,6 +25,38 @@ def _section_block(text: str, section_id: str) -> str: return match.group(0) +class _SettingsFormButtonParser(HTMLParser): + def __init__(self) -> None: + super().__init__(convert_charrefs=True) + self._settings_form_depth = 0 + self.non_button_buttons: list[str] = [] + + def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: + attr_map = dict(attrs) + classes = set((attr_map.get("class") or "").split()) + starts_settings_form = tag == "form" and "settings-form" in classes + in_settings_form = self._settings_form_depth > 0 or starts_settings_form + + if starts_settings_form: + self._settings_form_depth += 1 + + if tag == "button" and in_settings_form and attr_map.get("type") != "button": + self.non_button_buttons.append( + attr_map.get("id") + or attr_map.get("class") + or self.get_starttag_text() + or " +
@@ -2518,7 +2518,7 @@ button:focus:not(:focus-visible) {
- +
@@ -2877,7 +2877,7 @@ button:focus:not(:focus-visible) {
- + reset the name back to "sol"
@@ -5805,6 +5805,13 @@ document.getElementById('saveCustomActivityBtn').addEventListener('click', async // Agent name reset const agentNameInput = document.getElementById('field-agent-name'); if (agentNameInput) { + agentNameInput.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + agentNameInput.blur(); + } + }); + agentNameInput.addEventListener('change', async (e) => { const newName = e.target.value.trim() || 'sol'; const today = new Date().toISOString().slice(0, 10); -- 2.51.2