Skip to content

Container Manager: stop the log dialog running off the screen - #19

Merged
DianaSensei merged 2 commits into
app/container-manager/mainfrom
claude/miniapp-container-logs-overflow-szzaje
Sep 22, 2026
Merged

DianaSensei merged 2 commits into
app/container-manager/mainfrom
claude/miniapp-container-logs-overflow-szzaje

Conversation

@DianaSensei

Copy link
Copy Markdown
Owner

Fixes the reported bug: opening a container's logs produced a window taller than the screen, with its own toolbar scrolled out of reach — unusable on any container with real output.

Root cause

A plugin bundle ships no CSS. scripts/makePluginConfig.mjs builds one ESM file and emits nothing else; the UI is styled entirely by the host app's compiled Tailwind sheet, which is generated by scanning the host's src/**. This repo is never scanned — the plugin is fetched at runtime from a URL.

So a class written only here lands in the DOM with no rule behind it, silently.

ContainerLogsDialog used h-[68vh] max-h-[calc(100vh-13rem)]. No host file spells either one, so the log box fell back to height: auto, grew with every line that streamed in, and pushed the dialog past both ends of the screen.

Everything this turned up

Auditing against the CSS the host actually emits — rather than grepping its source, which only approximates what Tailwind emits — showed plain utilities go missing the same way:

Class What broke
h-[68vh], max-h-[calc(100vh-13rem)] The reported bug
bottom-3 "Jump to latest" lost its offset, fell to the top of the log pane and covered the first line
pl-1.5, -ml-1.5, border-bad/60 The red rule marking a stderr line sat flush against the text and washed out — stderr indistinguishable from stdout
max-h-[70vh] ×4 Container / Image / Network / Volume detail dialogs had unbounded bodies
max-h-[65vh] Same shape in the resources dialog
focus-visible:border-bad Invalid-regex state on the search box

The fix

Each value becomes an inline style, which no build step can drop, and which works on whatever host the user already has — the point being that a plugin installs into an existing host, not a future one.

The log dialog's body also gains min-w-0 overflow-hidden: DialogContent is a grid, grid items default to min-width: auto, so one unbreakable log line could still push the dialog past its own max-width.

Guards

  • scripts/check-host-classes.mjs — resolves every class this plugin writes against a real host stylesheet. The only ground truth, and the check the offline test cannot do. Run it against the oldest host release you still support.
  • ui/hostCssClasses.test.ts — the part that works offline: fails on any new arbitrary-value sizing or layout class. No safelist can ever cover arbitrary values, so this one stays.
  • README.md gains a "Styling" section explaining the rule.

Verification

  • npm run typecheck — clean
  • npx vitest run — 53 tests pass
  • npm run build — bundle builds
  • scripts/check-host-classes.mjs clean against builds of both the currently released host and the host with the new safelist

Related

DianaSensei/developer-desktop-utils#165 adds a plugin-facing safelist host-side so future plugin code has stable ground. That only helps hosts built from here on, which is why this PR fixes the classes directly.

Not verified here: opening the app to look at the dialog by eye.

🤖 Generated with Claude Code

https://claude.ai/code/session_017Nz2ELEkkMQzn6N429NkFy


Generated by Claude Code

DianaSensei and others added 2 commits September 22, 2026 07:23
A plugin bundle ships no CSS: makePluginConfig.mjs builds one ESM file and
nothing else, and the UI is styled entirely by the host app's compiled
Tailwind sheet — which is generated by scanning the HOST's src/** and never
sees this repo. A class written only here lands in the DOM with no rule
behind it.

Named utilities survive that (the host uses the same kit, so the rule
exists), but arbitrary values each compile to their own rule and only get
emitted if a host file spells them identically. h-[68vh] and
max-h-[calc(100vh-13rem)] on the log dialog did not, so its log box fell
back to height:auto, grew with every line that streamed in, and pushed the
dialog past the top and bottom of the screen with its own toolbar out of
reach — the window was unusable on a container with any real output.

Express those sizes as an inline style instead, which no build step can
drop. The four detail dialogs and the resources dialog had the same
unbounded-body shape (max-h-[70vh] / max-h-[65vh]) and get the same
treatment. Also give the log dialog's body min-w-0 + overflow-hidden: grid
items default to min-width:auto, so one unbreakable line could still push
the dialog past its own max-width.

ui/hostCssClasses.test.ts fails the build on any new arbitrary-value sizing
or layout class outside the allowlist of spellings verified present in the
host's sheet, and README.md documents the rule for plugin authors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Nz2ELEkkMQzn6N429NkFy
Auditing against the host's actually-compiled CSS — rather than grepping its
source, which only approximates what Tailwind emits — turned up more than the
arbitrary-value classes the first pass found. Plain utilities go missing the
same way, and three did:

- bottom-3: the "Jump to latest" button had no offset, so it fell to the top
  of the log pane and covered the first line instead of floating above the
  newest one.
- pl-1.5 / -ml-1.5 / border-bad/60: the red rule marking a stderr line sat
  flush against the text and washed out, leaving stderr indistinguishable
  from stdout.
- focus-visible:border-bad on an invalid regex in the search box.

Give each an inline style (or a class the host does ship), and add
scripts/check-host-classes.mjs, which resolves every class this plugin writes
against a real host stylesheet — the only ground truth, and the check the
offline unit test cannot do.

Verified clean against a build of the currently released host, which is what
matters: a plugin installs into whatever host the user already has.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Nz2ELEkkMQzn6N429NkFy
@DianaSensei
DianaSensei merged commit c78c363 into app/container-manager/main Sep 22, 2026
4 checks passed
@DianaSensei
DianaSensei deleted the claude/miniapp-container-logs-overflow-szzaje branch September 22, 2026 08:02
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.

1 participant