Tags: loopworx/forge
Tags
fix(tui): animated spinner via setInterval, visible sidebar gap, Sele… …ctOverlay contrast + error handling 3 issues fixed via TDD (14 new tests, 442 total): 1. Spinner static (issue #1): Root cause: the live:true + renderAfter mechanism is fragile through the ScrollBox content->viewport->wrapper hierarchy. When the spinner is scrolled out of the viewport (or the viewport culling filter excludes it), renderAfter is not called and the spinner freezes on frame 0. Fix: add a setInterval (80ms) in ChatView that advances the spinner and reassigns spinnerText.content. The content setter triggers requestRender() which schedules a fresh render pass regardless of culling. The interval starts on setThinking(true) and tool_start; stops on setThinking(false), text_delta, tool_end, agent_error, agent_settled, and dispose(). ChatView.dispose() clears the interval and is called by the /exit command. 2. No visible space between sidebar and chat (issue #2): Root cause: root background is #0f0f0f (backgroundPanel), sidebar is also #0f0f0f, and the 2-col sidebarGap had no backgroundColor (inherited #0f0f0f from root). All three merged into one indistinguishable shade. Fix: give mainColumn and sidebarGap the darkest shade #080808 (background) so they contrast with the panel-shade sidebar and root. Also removed a duplicate root.add(mainColumn) left by commit 9a47434. 3. Chat clears + TUI freezes after resume + question (issue #3): Root cause: handleForgeEvent's import().then() chain had no .catch(). When the question callback threw (e.g. SelectOverlay creation failed), the error became an unhandled promise rejection. The renderer's global unhandledRejection handler swallowed subsequent errors, leaving the TUI in a broken state (chat cleared, /sessions stopped working, user couldn't type because focus was trapped in a partially-created overlay). Additionally, the SelectOverlay used low-contrast colors (backgroundPanel #0f0f0f + border #484848) making it nearly invisible against the same-shade root. Fix: (a) handleForgeEvent: add .catch() to the import().then() chain that logs the error. (b) bin/forge.ts setOnQuestion: wrap the entire callback body in try/catch/finally with inputBar.focus() in finally so focus is ALWAYS restored. (c) SelectOverlay: backgroundColor #161616 (backgroundElement, distinct from root #0f0f0f) + borderColor #606060 (borderActive, higher contrast) + maxHeight 60% so long option lists don't cover the entire screen. Tests: 442 pass (14 new), 0 TS errors, 0 lint warnings, build OK.
PreviousNext