feat(chat): a proper wordmark for the empty state - #82
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the LevelCode AI chat webview UX by replacing the empty-state ASCII logo with a hand-drawn wordmark and tightening/adjusting the chat surface model so chat is editor-tab-only (removing the contributed sidebar chat view) with updated commands/menus and regression tests.
Changes:
- Replace the empty-state ASCII art in the chat webview with a narrower full-block “wordmark” and add CSS/webview guards to pin its invariants.
- Remove the contributed
levelcodeAi.chatsidebar view and migrate chat actions to the editor tab title, updating settings/tests accordingly. - Seal sessions on chat-tab close and expand test coverage around “single surface” invariants.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| extensions/levelcode-ai/test/webviewCss.test.js | Adds an invariant test ensuring the empty-state wordmark uses only full blocks, fits the container, and preserves accessibility attributes. |
| extensions/levelcode-ai/test/sessionsUi.test.js | Updates expectations so Sessions is the only contributed view in the levelcodeAi container. |
| extensions/levelcode-ai/test/chatSurface.test.js | Refactors surface/restore/CSP/menu assertions for editor-tab-only chat and adds close/seal invariants. |
| extensions/levelcode-ai/package.json | Removes the contributed chat view and moves chat actions to editor/title; updates chat.startLocation enum. |
| extensions/levelcode-ai/media/chat.html | Replaces the old figlet-style empty-state ASCII logo with the new wordmark. |
| extensions/levelcode-ai/extension.js | Removes sidebar chat view plumbing, ensures the chat provider is panel-owned, seals on close, and adjusts focus/startup behavior. |
Suppressed comments (1)
extensions/levelcode-ai/package.json:91
- The PR title/description focuses on the empty-state wordmark, but this change set also removes the contributed chat view (
levelcodeAi.chat) and shifts multiple commands/menus/settings as a result. Please update the PR description/title to reflect that broader behavior change, or split the chat-surface refactor into a separate PR so reviewers can assess it independently.
"levelcodeAi": [
{
"id": "levelcodeAi.sessions",
"name": "Sessions",
"type": "webview"
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Replaces the figlet "ANSI Shadow" dump with a wordmark drawn for this space. The old one
was the most-used figlet font there is, carried a double-outline shadow that read as noise
at the size it actually renders, and did not line up: LEVEL ran to 41 columns while CODE
ran to 38 and sat at a 5-space indent, so the two words never shared an edge.
The new one is 11x39 (was 12x41), both words centred on the same axis, no shadow.
DRAWN, NOT GENERATED. A 10-row pixel grid with every stroke 2px thick, packed two pixel
rows per text row. That last constraint is the whole trick, and it was learned the hard way:
`▀` sits at the TOP of its cell and `▄` at the BOTTOM, so `▀` directly above `▄` leaves a
full empty cell between them — a seam straight through the letterform.
A 1px-stroke font produces that on nearly every row, and the first three attempts shattered
into fragments because of it. With 2px strokes every pixel pair collapses to a FULL block,
so the shipped art contains `█` and spaces and nothing else — it cannot develop seams in any
monospace font, whatever the user has configured. That property is now pinned.
Two things measured rather than assumed:
- Verified the seam directly: `█` over `█`, `▄` over `▀`, and `█` over `▀` all tile
solidly; only `▀` over `▄` gaps. That test is what redirected the design.
- Width is capped at ~44 columns. #empty is max 560px and the font is sized from the
container (clamp(5px, 3.6cqi, 13px)), so a wider mark does not scale down — it overflows
and grows a horizontal scrollbar under the logo. An earlier 71-column one-line version
did exactly that, which is why this stayed stacked.
Guards, each bypass-verified by reverting the fix:
- half-blocks reintroduced, i.e. the seam bug
- role="img" dropped, so a screen reader reads the picture out block by block
- the accessible name dropped
- the mark widened past the container
33 tests in webviewCss, 34 suites green.
8126086 to
b0717ae
Compare
|
Both comments here were about Both points were real and are fixed against develop in the linked PR: the close path now runs the same teardown New Chat does (it was sealing the session while leaving |
Replaces the figlet "ANSI Shadow" dump with a wordmark drawn for this space.
The old one was the most-used figlet font there is, carried a double-outline shadow that reads as noise at the size it actually renders, and didn't line up: LEVEL ran to 41 columns, CODE ran to 38 and sat at a 5-space indent, so the two words never shared an edge.
New: 11 × 39 (was 12 × 41), both words centred on the same axis, no shadow.
Drawn, not generated
A 10-row pixel grid with every stroke 2px thick, packed two pixel rows per text row. That last constraint is the whole trick, and I learned it the hard way after three attempts shattered into fragments:
A 1px-stroke font produces that on nearly every row. With 2px strokes every pixel pair collapses to a full block, so the shipped art contains
█and spaces and nothing else. It cannot develop seams in any monospace font, whatever the user has configured — and that property is pinned by a test.Two things measured rather than assumed
The seam itself. I rendered
█/█,▄/▀,█/▀and▀/▄and compared: the first three tile solidly, only▀over▄gaps. That result is what redirected the design away from the thin-stroke font I started with.The width cap.
#emptyis max 560px and the font is sized from the container (clamp(5px, 3.6cqi, 13px)), so a wider mark does not scale down to fit — it overflows and grows a horizontal scrollbar under the logo. An earlier 71-column single-line version did exactly that, which is why this stayed stacked at 39.Guards
Each bypass-verified by reverting the fix:
role="img"dropped, so a screen reader reads the picture out block by block33 tests in
webviewCss, 34 suites green.