Skip to content

feat(chat): a light travels round the message box while LevelCode works - #116

Merged
ndemianc merged 2 commits into
developfrom
feat/working-aura
Oct 20, 2026
Merged

ndemianc merged 2 commits into
developfrom
feat/working-aura

Conversation

@ndemianc

Copy link
Copy Markdown
Contributor

What it does

While LevelCode works, a light travels round the message box, like the border beam in VS Code's own chat (Copilot).

State What you see
Working: thinking, writing, running a command, checking its edits, or a message on its way A short bright arc circles the box over a faint whole ring, in the theme's progress colour
Waiting on you: a command to approve, a question to answer The light stops and dims to a thin ring with no glow, so a paused run does not look busy
Idle Nothing (it fades out when the run ends)
Reduced motion A still ring
High contrast (forced colours) None

One turn takes 1.6–3 s, set from the box's size when the light starts. It grows slower than the box, so a wide panel stays calm; most boxes wider than ~450px get 3 s.

Setting: levelcode.ai.chat.workingAura: boolean, on by default, application scope, so a folder's settings cannot switch it (#113's policy).

The browser edition gets it too: it uses the same chat page, and the rings inherit the skin's 24px corners.

How

  • media/chat.html: two pseudo-elements on #composer, masked to a band on its edge (mask-composite: exclude) so the box's inside and its clicks are untouched. ::after is the sharp line, ::before the blurred glow; both turn on one typed @property --aura-angle.
  • syncAura() picks off / working / waiting from busy() and agentParked(). setStreaming and syncSendBtn call it, and a MutationObserver on the transcript catches an approval card or question appearing or being answered, so no card has to remember to tell it. var, not let: syncSendBtn can reach it before its line has run.
  • extension.js: the setting is sent with both config messages (gateway and your own key).

Tested

  • test/workingAura.test.js (13): lifts auraState, auraDuration and syncAura from chat.html and runs them (the states, the speed's bounds, the switching, the setting turned on mid-run, no throw before layout); pins the CSS and wiring from source. Each of 30 one-edit mutations fails it.
  • scripts/test-extensions.sh: 137 files pass on macOS, Node 24.
  • tsc --checkJs on extension.js: the same 28 errors as develop's copy, none new. 0 in the new test and script.
  • Real editor (scripts/working-aura-editor-check.js, dev build + a stand-in provider): 9/9 in the default dark theme and in LevelCode One Light: working, idle, waiting on an approval card, after approval, reduced motion, setting off, no page exceptions.
  • Browser skin: this branch's chat.html with web/ai-extension/skin.js applied and the web-dark / web-light colours, in headless Chrome: 12/12 (lights up, follows the 24px corners, moves, clears at the end of the run, no page errors). web/test/unit/skin.test.js passes.

Not run

  • A full browser-edition release build (e2e-look.mjs); the skin check above renders the page the way the build skins it, not the built bundle.
  • Linux and Windows.

Like the border beam in VS Code's own chat: while a run is busy (thinking, writing, running a command,
checking its edits, or a message on its way) a short bright arc circles the message box over a faint whole
ring, in the theme's progress colour. While the run waits on the person (a command to approve, a question
to answer) it stops and dims to a thin ring with no glow, so a paused run does not look busy. Idle, there is
nothing. Reduced motion draws a still ring; high contrast draws none.

How: two pseudo-elements on #composer, masked to a band on its edge so the box's inside and its clicks are
untouched, turned by one typed @Property angle. syncAura() picks off / working / waiting from busy() and
agentParked(); setStreaming and syncSendBtn call it, and a MutationObserver on the transcript catches an
approval card or a question appearing or being answered. One turn takes 1.6-3 s, set from the box's size
when the light starts and growing slower than the box, so a wide panel stays calm.

Setting: levelcode.ai.chat.workingAura (boolean, application scope, on by default), sent with both config
messages. The browser edition shows it too: it uses the same chat page, and the rings inherit the skin's
24px corners.

Tested: test/workingAura.test.js lifts auraState, auraDuration and syncAura from chat.html and runs them
(the states, the speed's bounds, the switching, the setting turned on mid-run, no throw before layout), and
pins the CSS and the wiring from source; each of 30 one-edit mutations fails it. planProgressUi.test.js's
lifted syncSendBtn gets a syncAura stub.
scripts/working-aura-editor-check.js runs the dev build with this extension and a stand-in provider that
holds each turn open, and checks in the chat webview: working (the class, both rings shown, the animation
running, the angle moving, a turn of 1.6-3 s), idle, waiting on an approval card (still, no glow), after the
approval, reduced motion (no animation), the setting off (no light), and no page exceptions. It saves
screenshots; --theme picks a colour theme.

Ran on macOS: 9/9 in the default dark theme and in LevelCode One Light.
@ndemianc
ndemianc marked this pull request as ready for review October 20, 2026 03:34
Copilot AI balanced review requested due to automatic review settings October 20, 2026 03:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@ndemianc
ndemianc merged commit 271137e into develop Oct 20, 2026
2 checks passed
@ndemianc
ndemianc deleted the feat/working-aura branch October 20, 2026 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants