feat: a group box can carry a mark, not just a title (#119) - #120
Merged
Conversation
GroupBox had a title, a status and an id, but no glyph channel — a box could be titled and never badged. A consumer wanting to mark one box out of many (behold marking the operator's own namespace) had only the title to smuggle it through, and titles are load-bearing: behold's logical lens re-derives `namespace <ns>` verbatim to re-parent helm releases, so a suffix would silently unparent them. `GroupBox.mark` is that channel, in the node mark vocabulary (#95) rather than a parallel one: a GENERIC_GLYPHS key or a pack's own GlyphSpec, `colored` if it carries its own paint. It resolves as an override in resolveGlyph's chain — a box has no lexicon or kind to consult a pack with — so an unknown key degrades to "generic" exactly as it does on a card. No `ground` is offered: the box fill is painted at fill-opacity 0.6, so pinhole cannot honestly name what the glyph sits over. It paints in the box's top-right gutter, an 18px square inset 18px from the right edge — the mirror of the title's left inset — centred on the title row, and monochrome geometry is stroked in the title's own colour, so it follows the theme and the status tint the way the title does. The morph takes the same GroupBox[], so the mark rides it too, baked relative to the box's right edge because the box resizes between views. Its panel CSS is narrowed to direct children, or the box's own fill would reach into an authored mark's shapes. Absent, a box renders byte-identical to before, pinned two ways: the emitted markup for an unmarked box, and marked-minus-the-mark == unmarked. 211 -> 227 tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rfs1mLVWmwginHnDTg75sG
lex00
added a commit
that referenced
this pull request
Aug 31, 2026
Version bump only, cutting the release that carries #120. `GroupBox` gains an optional `mark?: string | GlyphSpec` — the node mark vocabulary applied to a box — painted in the box's top-right gutter. Purely additive: a box without it renders byte-identical to 0.3.6. Merging this tags `v0.3.7` and fires the publish workflow. Claude-Session: https://claude.ai/code/session_01Rfs1mLVWmwginHnDTg75sG Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #119.
GroupBoxhad a title, a status and an id, but no glyph channel — a box could be titled and never badged. A consumer wanting to mark one box out of many (behold marking the operator's own namespace) had only the title to smuggle it through, and titles are load-bearing: behold's logical lens re-derivesnamespace <ns>verbatim to re-parent helm releases, so a suffix would silently unparent them.The field
The node mark vocabulary (#95) applied to a box, not a parallel one: a
GENERIC_GLYPHSkey or a pack's ownGlyphSpec({ body, colored?, viewBox? }). It resolves as an override inresolveGlyph's chain — a box has no lexicon or kind to consult a pack with — so an unknown key degrades to"generic"exactly as it does on a card, and acoloredmark paints as authored. Nogroundis offered: the box fill is painted atfill-opacity0.6, so pinhole cannot honestly name what the glyph sits over (the same reason the containment views pass none).Where it paints
The box's top-right gutter: an 18px square inset 18px from the right edge — the mirror of the title's 18px left inset — vertically centred on the title row. Monochrome geometry is stroked in the title's colour, so it follows the theme and picks up the status tint the way the title does.
groupMarkMarkupis the single emitter, the wayglyphMarkupis for node glyphs.The morph takes the same
GroupBox[], so the mark rides it too, baked relative to the box's right edge (the box resizes between views, so the runtime slides it by the current width). Its panel CSS is narrowed to direct children —.pin-mbox > rect— or the box's own fill would reach into an authored mark's shapes.Absent = unchanged
Pinned two ways: the exact emitted markup for an unmarked box, and
marked.replace(theMark, "") === unmarked— the mark is purely additive.Checks
npm run tsc,npm test(211 -> 227),npm run buildall clean locally.🤖 Generated with Claude Code
https://claude.ai/code/session_01Rfs1mLVWmwginHnDTg75sG