Skip to content

fix(web/playground): tighten grid, fix Workspace void, unify Create chat composer#986

Merged
sabbour-squad-lead[bot] merged 1 commit into
mainfrom
squad/playground-polish
Apr 21, 2026
Merged

fix(web/playground): tighten grid, fix Workspace void, unify Create chat composer#986
sabbour-squad-lead[bot] merged 1 commit into
mainfrom
squad/playground-polish

Conversation

@sabbour-squad-frontend
Copy link
Copy Markdown
Contributor

Playground visual/UX polish (4 issues)

A. Components tab grid tightness + empty-card sprawl

Before: 8 cards per row on wide viewports; empty "No preview available" cards took full ~180px body like real preview cards, making core/azure/aks/github sections feel sparse and noisy.
After: Responsive grid capped at repeat(auto-fill, minmax(260px, 1fr)) with a 320px card max — 4–5 cards/row at standard viewports. Pack sections where every component lacks a registered preview (azure, aks, github) now render as compact chip-style cards (~88px min-height) with a single explanatory banner (Previews unavailable for pack-only components — showing compact cards.) replacing the wall of identical empty states.

B. Workspace tab black void below the editor

Before: Workspace opened server.ts in a viewer clamped to ~45% width/height, leaving a large black rectangle to the right of the editor.
After: Added a fillContainer prop to FileViewer (non-default; opt-in) that overrides the chat-side-panel width: 45% / maxWidth: 55% sizing with width: 100% + flex: 1. Playground Workspace now renders the viewer edge-to-edge in the right pane. Main App chat layout is unchanged because fillContainer defaults to false.

C. Create tab chat input styled inconsistently with main chat

Before: Create tab used a bespoke hero-style input — different border radius, different padding, larger font, custom send icon (commands/go.svg).
After: Create composer styles mirror the main chat composer — borderRadiusLarge, stroke-1 border, spacing-s/spacing-m padding, fontSizeBase300 + lineHeightBase300, and the same ArrowRight24Regular icon on the send button. The Sparkle "Inspire me" affordance is preserved. Create now reads as a sibling chat entry point.

D. Non-core packs sparse (azure/aks/github all "No preview available")

Covered by the Issue A compact empty-state + banner.

Validation

  • npm run lint — 0 errors, 59 pre-existing warnings (unchanged)
  • CI=1 npm test -- --reporter=dot900 passed, 3 skipped, 159 todo (no regressions)

Files changed

  • packages/web/src/pages/Playground.tsx — grid, compact card mode, composer style, ArrowRight send icon
  • packages/web/src/components/FileManager/FileViewer.tsxfillContainer prop
  • packages/web/src/pages/PlaygroundWorkspace.tsx — pass fillContainer
  • .changeset/polish-playground-grid-workspace-create.md

🤖 Created by sabbour-squad-frontend

…hat composer

- Components tab: responsive grid capped at minmax(260px, 1fr)/320px so
  wide viewports show 4-5 cards/row instead of 8. Pack sections where
  every component lacks a registered preview (azure, aks, github) render
  as compact chip-style cards with a single explanatory banner, replacing
  the wall of 'No preview available' placeholders.
- Workspace tab: added a fillContainer prop to FileViewer so the Playground
  editor fills the full width of its pane instead of being clamped to the
  45% chat-side-panel sizing. Removes the large black void.
- Create tab: aligned the chat composer with the main chat input
  (borderRadiusLarge, matching padding, stroke-1 border, 300-size font,
  ArrowRight send icon) so the Create entry point feels like chat.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Docs & changeset gate

  • ✅ changeset added (.changeset/*.md)
  • ℹ️ docs-site/docs/ not updated — consider updating if user-facing behavior or UI changed
  • ℹ️ docs-site/docs/extending/api-endpoints.md not updated — consider updating if the API surface changed

Changeset present. Good.


Hard gate for user-facing package changes without docs or changeset. ✅ = done, ⚠️ = likely needed, ℹ️ = optional or bypassed.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

👀 Squad review trail

Current head: 284b018
Last update: Label applied: nibbler:approved.
Gate path: Standard path — both leela:approved and zapp:approved are required on the current head.
Gate snapshot:squad/review-gate should be green on the current head.
Reviewer labels

  • Leela: ✅ approved via leela:approved
  • Zapp: ✅ approved via zapp:approved
    Active labels
  • leela:approved — Architecture review approved
  • zapp:approved — Security review approved

This sticky comment is maintained automatically so label-based squad review leaves an on-PR rationale even when the gate itself is status-check driven.

Copy link
Copy Markdown
Contributor

@sabbour-squad-lead sabbour-squad-lead Bot left a comment

Choose a reason for hiding this comment

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

🔒 Zapp — Security Review

Verdict: ✅ Approve — no security impact.

Scope reviewed

Playground.tsx (grid styling + compact card mode + createInputRow/createInput style overhaul + send-button icon swap), FileViewer.tsx (fillContainer boolean prop), PlaygroundWorkspace.tsx (pass the new prop). Read end-to-end for any new user-input path, URL-param surface, or preview-rendering change.

Findings

  1. No new user-input path. The Create composer is the same createPrompt textarea as before; only its styling and icon change. No new dangerouslySetInnerHTML, no new URL param parsing, no new query-string reads, no new clipboard handlers.
  2. Preview rendering is unchanged. ComponentCard still renders through A2UIEnvelopePreview / COMPONENT_PREVIEWS. The compact-mode branch only changes layout (classes.compCardCompact, an 88px min-height, a different grid template). The no-preview branch switches from an inline-styled div to classes.emptyPreviewLabel — still a static literal, no interpolation of untrusted data.
  3. Icon swap is inert. Replacing <img src="assets/icons/commands/go.svg"> with <ArrowRight24Regular> removes a static asset reference; no new script execution, no CSP implications, script-src 'self' stays clean.
  4. fillContainer prop. Pure boolean. Default false, opt-in, toggles styles.rootFill via mergeClasses. Does not affect data flow or trust boundaries.
  5. No new deps, no new API calls, no secret handling, no auth changes.

Notes

  • The compPackBanner copy (Previews unavailable for pack-only components — showing compact cards.) is a static literal — fine. Do not later substitute this with an LLM- or pack-contributor-supplied string without escaping.

Applying zapp:approved.

@sabbour-squad-lead sabbour-squad-lead Bot added the zapp:approved Security review approved label Apr 21, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Zapp recorded a security approved via zapp:approved on head 284b018.

This native review mirrors the label-driven squad gate for visibility only.
Merge eligibility still comes from the squad/review-gate status check and the current approval labels.

Copy link
Copy Markdown
Owner

@sabbour sabbour left a comment

Choose a reason for hiding this comment

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

🏗️ Leela — Architecture Review

Verdict: Approve.

Scope is right — pure packages/web presentation polish, zero API or pack-contract surface. No architecture risk.

What's good:

  • FileViewer.fillContainer is opt-in with fillContainer = false default. Existing chat-side-panel call sites stay on the 45%/55% clamp; only PlaygroundWorkspace passes fillContainer. Backward-compatible prop addition done correctly — no consumer migration needed.
  • Grid sizing lives in makeStyles classes, not inline style props — keeps the responsive tuning centralised. The componentGrid / componentCompactGrid split is a reasonable way to express "this pack contributes no previews" as a data-driven layout variant rather than per-card conditional chrome.
  • Compact-grid transition is derived from data (allEmpty = comps.every(c => !COMPONENT_PREVIEWS[c.name])), not hardcoded to pack names. When pack-azure/aks/github ship their own previews in the future, they'll automatically get the full grid — no follow-up refactor needed. Good future-proofing.
  • Composer parity with main chat: borrowing borderRadiusLarge, stroke-1, fontSizeBase300, ArrowRight24Regular, and the spacing tokens keeps the Create surface visually consistent with the chat entry. Swapping the PNG commands/go.svg for the Fluent icon also drops a raster asset dependency — small net positive.

Non-blocking notes:

  • componentGrid caps each card at maxWidth: 320px via descendant selector & > *, while componentCompactGrid caps at 280px. If a pack ships a mix of preview and no-preview components in the future, the "all empty" gate toggles the whole section to compact — which is still the right default, but worth a comment on ComponentCard.compact describing that the prop is pack-wide, not per-card.

Architecture 🟢 approved.

@sabbour sabbour added the leela:approved Architecture review approved label Apr 21, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Leela recorded a architecture approved via leela:approved on head 284b018.

This native review mirrors the label-driven squad gate for visibility only.
Merge eligibility still comes from the squad/review-gate status check and the current approval labels.

Copy link
Copy Markdown
Owner

@sabbour sabbour left a comment

Choose a reason for hiding this comment

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

🧪 Nibbler — Code Quality Review

Verdict: ✅ Approve — targeted CSS/UX polish, no regressions, behaviour-preserving.

Correctness

  • FileViewer's new fillContainer prop is opt-in (= false default), so the existing chat-side-panel consumers keep their width: 45% / maxWidth: 55% layout. Only PlaygroundWorkspace passes fillContainer, which is the single site that needed the fix. No broadcast changes.
  • mergeClasses(styles.root, fillContainer && styles.rootFill)mergeClasses tolerates falsy values, and the override rules (width: 100%; minWidth: 0; maxWidth: none; flex: 1) are applied late enough in the cascade to win against styles.root. The "Select a file" empty-state path also gets the same merge, so the void is killed in both branches, not just the populated one.
  • Grid: gridTemplateColumns: repeat(auto-fill, minmax(260px, 1fr)) + '& > *': { maxWidth: '320px' } yields 4–5 cards per row at common viewports without breaking narrow widths (the minmax(260px, 1fr) floor is respected at ≥260px). The 320px cap produces wasted gutter space at very wide viewports, which is a deliberate UX choice documented in the PR and doesn't cause layout bugs.
  • allEmpty = comps.every(c => !COMPONENT_PREVIEWS[c.name]) — correct predicate. The compact grid is only applied when every component in a pack section lacks a preview, and the per-card compact prop is OR-ed with !hasPreview so mixed sections still compact the individual empty cards. Good.

Create composer unification

  • ArrowRight24Regular replaces the go.svg <img> in both render sites (lines 1463 and 1678); old asset is no longer referenced. The inline style={{ width: '16px', height: '16px' }} scales the 24px icon viewBox correctly.
  • Padding/border/radius/font-size/line-height now match the main chat composer tokens (borderRadiusLarge, colorNeutralStroke1, fontSizeBase300/lineHeightBase300, spacingVerticalS + spacingHorizontalM). alignItems: 'flex-end' is the right alignment for a growing textarea.

Loading / error states

  • Pre-existing registryError / registryLoading branches are untouched. The new compPackBanner only renders when allEmpty — it does not suppress error states, and the error MessageBar still fires first. No path changes; no new error surfaces to cover.

Test coverage

  • 🟡 Concern (non-blocking): zero new tests for the grid compacting logic (allEmpty, compact prop propagation) or for the fillContainer branch. Given this is a visual polish PR and both CI suites (unit + Playwright E2E) passed green, regression risk is low — but a small snapshot/class assertion for the compact path would lock in the "all-empty pack → compact grid + banner" contract so a future refactor of COMPONENT_PREVIEWS doesn't silently flip it. Not blocking, but worth a follow-up.

🟢 Nit

  • className={${classes.compCardClickable}${isCompact ? ${classes.compCardCompact} : ''}} — the rest of the file (and this PR) already uses mergeClasses (it's imported in FileViewer). Using mergeClasses(classes.compCardClickable, isCompact && classes.compCardCompact) would be more idiomatic. Trivial.

CI green across lint/build/unit/check and Playwright E2E. Behaviour-preserving for every non-Playground consumer.

Approving.

@sabbour sabbour added the nibbler:approved Code quality review approved label Apr 21, 2026
@sabbour-squad-lead sabbour-squad-lead Bot merged commit c517aa8 into main Apr 21, 2026
23 checks passed
@sabbour-squad-scribe
Copy link
Copy Markdown
Contributor

Working as Scribe · see .squad/agents/scribe/charter.md

Retro entry

- 2026-04-21 | #986 "fix(web/playground): tighten grid, fix Workspace void, unify Create chat composer" | M | impl=1m | review=42m | cycles=1 | merged | @sabbour-squad-frontend[bot] | first_review=37m | ci=6m | reviewer=bot | human_comments=2 | issue=none | estimate=unknown | rejections_by_reviewer=nibbler:0,leela:0,zapp:0 | reverted=false

Queued via retro-log PR #994: #994
This update will land in .squad/retro-log.md after that PR merges.

sabbour pushed a commit that referenced this pull request Apr 21, 2026
Working as Scribe — see .squad/agents/scribe/charter.md
sabbour-squad-lead Bot pushed a commit that referenced this pull request Apr 21, 2026
* fix(web): core components tab density + preview rendering (#995)

#986 tightened the component grid but left two regressions on the Core tab:
- Grid produced 6+ cards/row at 1920px viewports (target was 4-5).
- Video, AudioPlayer, Tabs, Modal, Accordion had no COMPONENT_PREVIEWS
  entries, so the Core tab rendered 'No preview' placeholders next to
  real preview cards.

- Add previews for all shipped core basic components.
- Bump grid minmax (260->300) and card cap (320->380); gap -> spacingVerticalL.
- Add preview-card min-height so live previews are legible.
- Extract geometry to playground-layout-constants.ts so CSS and tests
  consume the same named constants (Nibbler DP ask).
- Unit-test guard for Core preview coverage + density math.
- Playwright assertions on card dimensions and preview visibility.

Closes #995. References #986.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore(squad/fry): log #995 outcome

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: sabbour-squad-frontend[bot] <275832692+sabbour-squad-frontend[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sabbour pushed a commit that referenced this pull request Apr 21, 2026
Updated GIT IDENTITY block to clarify that session-level GH_TOKEN export
(done once at session start) covers all gh write commands:
- gh pr review
- gh pr comment
- gh pr merge
- gh pr edit
- gh issue comment
- etc.

Previously, the template only mentioned 'push' and 'pr create', causing
agents to omit GH_TOKEN for review/comment/merge commands, which fell
through to authenticated user identity instead of bot identity.

Ported from sabbour/squad PR #27.

Fixes: #986 #989 #990
sabbour pushed a commit that referenced this pull request Apr 21, 2026
Changeset for template and documentation updates that fix the identity
consistency issue where reviewer agents posted as users instead of their
bot identities on PRs #986/#989/#990.

Ported from sabbour/squad PR #27.
sabbour-squad-lead Bot pushed a commit that referenced this pull request Apr 21, 2026
#1007)

* squad: merge decisions inbox (7 files) + update agent histories (leela bug intake)

- Merged .squad/decisions/inbox/ → decisions.md (7 inbox files, chronological order, deduplicated)
- Deleted all inbox files after merge
- Updated .squad/agents/fry/history.md: added note on bug #995, #997 assignments
- Updated .squad/agents/bender/history.md: added note on bug #998 (priority:high, regression from #989), #996 assignments
- Updated .squad/agents/zapp/history.md: consolidated history, archived entries > 15KB to history-archive.md, kept 2026-04-21 work only
- Created .squad/orchestration-log/2026-04-21T10-50-06Z-leela.md: logged leela spawn outcome
- Created .squad/log/2026-04-21T10-50-06Z-bug-intake.md: session log

Leela spawn (2026-04-21T03:46:48-07:00 → 2026-04-21T03:50:06-07:00):
- Filed 4 new issues (#995, #996, #997, #998) with squad triage labels
- Confirmed 1 duplicate (#991)
- Identified 1 high-priority regression (#998 from #989)
- Surfaced 1 test-coverage gap (schema conformance audit)

Decisions archive gate: No entries > 7 days old; no archival needed.
Inbox files: 7 processed and deleted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(identity): session-export pattern covers all gh write commands

Updated GIT IDENTITY block to clarify that session-level GH_TOKEN export
(done once at session start) covers all gh write commands:
- gh pr review
- gh pr comment
- gh pr merge
- gh pr edit
- gh issue comment
- etc.

Previously, the template only mentioned 'push' and 'pr create', causing
agents to omit GH_TOKEN for review/comment/merge commands, which fell
through to authenticated user identity instead of bot identity.

Ported from sabbour/squad PR #27.

Fixes: #986 #989 #990

* chore: add changeset for identity consistency fix

Changeset for template and documentation updates that fix the identity
consistency issue where reviewer agents posted as users instead of their
bot identities on PRs #986/#989/#990.

Ported from sabbour/squad PR #27.

* Scribe: Merge Round 3 decisions + ceremony logs

- Merged 5 inbox files (leela-round3, zapp-round3, nibbler-round3, zapp-993, nibbler-993) into decisions.md (149KB → 172KB)
- Deleted inbox files after merge
- Created orchestration logs for ralph, leela, zapp, nibbler, docs-gate, + session log
- Updated agent histories: fry (lockout from PR #1000), bender (dual assignment #998 + #1000-revise), leela (DP closure + gate mechanics)
- Summarized 4 agent histories (archive old logs; keep recent work + patterns)

Round 3 Summary:
- 5 DPs approved (DP #998 chat HIGH, #995#997 FE, #987 Ideas tab blocked on #991)
- PR #1001 merged (emit_ui fixture, all gates green)
- PR #1000 rejected (red CI + missing CI grep rule; Fry locked out; bender-1000-revise assigned)
- Mechanical gate (#993) active: 4-way + docs gate enforced on all future PRs
- 5 security decisions documented (schema invariant, Ideas curated-only, composition harness, DP-time conditions)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore(squad): bender — #998 decision + history

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore(nibbler): round-4 review history + decisions (PRs #1005/#1000/#1003/#1004)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: scribe round-4 decisions merge + identity update + retrospective

DECISIONS MERGED (7 inbox files → decisions.md):
- bender-1000-revise-2026-04-21.md: Pack ./client subpath resolution, zod version skew cast pattern, pack-client guardrails via vitest
- bender-998-fix-2026-04-21.md: Strict-required conformance for pack-core tool schemas (.nullable() in discriminatedUnion, parametrised test)
- fry-995-fix-2026-04-21.md: Playground layout constants are single source of truth (CSS, unit test, Playwright)
- fry-997-fix-2026-04-21.md: Workspace flex min-height:0 discipline, explicit geometry assertions
- leela-round4-2026-04-21.md: Round-4 PR review (PRs #1005/#1000/#1003/#1004, 4-way gate summary)
- nibbler-round4-2026-04-21.md: Code review verdicts, approved all 4 PRs, bundle-budget gate + geometry SSoT patterns locked in
- zapp-round4-2026-04-21.md: Security verdicts, approved all 4 PRs, .nullable() discipline + vitest guardrail acceptance + bundle-budget protection

IDENTITY STATUS UPDATED (identity/now.md):
- Mode: bug-shipping-then-feature-unblock
- Shipped: 5 UI bugs (#991, #980, #995, #997, #998) → PRs #1000#1005
- In flight: #996 (allow-list drift), #987 (Playground E2E regression)
- Round-4 learnings embedded (7 key lessons + implications)

RETROSPECTIVE APPENDED (retro-log.md):
- Round-4 summary: 5 bugs shipped, 5 PRs merged, 4-way gate cycle
- 7 key learnings:
  1. Stale agent verdicts must verify live CI state
  2. Edit-but-not-commit causes silent test passes
  3. Approval labels strip on PR synchronize (relabel pass needed)
  4. Worktree hygiene overdue (stale fry-987, bender-996, etc.)
  5. Bundle-budget ceiling gate proved ✅
  6. Named-constant geometry SSoT proved ✅
  7. Parametrised tool conformance test is durable ✅
- 5 implications for future rounds (agent validation, rebase discipline, label persistence, cleanup automation)

Decisions inbox cleaned (all 7 files merged + deleted).
decisions.md size: 204,010 bytes (+32 KB from round 3).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: sabbour-squad-frontend[bot] <275832692+sabbour-squad-frontend[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: sabbour-squad-backend[bot] <sabbour-squad-backend[bot]@users.noreply.github.com>
Co-authored-by: sabbour-squad-lead[bot] <nibbler@squad.local>
Co-authored-by: Bender (Backend Dev) <bender@squad.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

leela:approved Architecture review approved nibbler:approved Code quality review approved zapp:approved Security review approved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant