Skip to content

chore(deps): bump the minor-and-patch group across 1 directory with 18 updates - #3360

Open
dependabot[bot] wants to merge 6 commits into
mainfrom
dependabot/npm_and_yarn/minor-and-patch-12971d8af9
Open

chore(deps): bump the minor-and-patch group across 1 directory with 18 updates#3360
dependabot[bot] wants to merge 6 commits into
mainfrom
dependabot/npm_and_yarn/minor-and-patch-12971d8af9

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 20, 2026

Copy link
Copy Markdown
Contributor

Bumps the minor-and-patch group with 17 updates in the / directory:

Package From To
@astryxdesign/cli 0.4.0 0.4.3
@astryxdesign/core 0.4.0 0.4.3
@biomejs/biome 2.5.6 2.5.8
@types/node 26.1.2 26.2.0
dugite 3.2.2 3.2.3
knip 6.26.0 6.32.2
@ai-sdk/openai-compatible 3.0.30 3.0.31
@larksuiteoapi/node-sdk 1.72.0 1.73.0
@openai/agents-core 0.14.3 0.16.1
ws 8.21.2 8.21.3
esbuild 0.28.1 0.28.2
electron 43.2.0 43.4.0
@earendil-works/pi-tui 0.83.0 0.84.2
lucide-react 1.28.0 1.31.0
@astryxdesign/theme-neutral 0.4.0 0.4.3
@storybook/react-vite 10.5.6 10.5.8
vite 8.1.5 8.2.1

Updates @astryxdesign/cli from 0.4.0 to 0.4.3

Release notes

Sourced from @​astryxdesign/cli's releases.

v0.4.3

Astryx 0.4.3 — all @astryxdesign/* packages ship at this version.

npx astryx upgrade --apply

@​astryxdesign/core

New Features

  • New string utilities: characterCount, firstCharacter, and truncateCharacters — replacements for .length, .charAt(0), and slice-based truncation that measure and cut user-visible strings by whole characters, so an emoji, flag, or accented letter counts as one and never gets split. Built on Intl.Segmenter with a code-point fallback.
  • ComplexSelector: support ghost toolbar triggers, leading icons, popup alignment, and an imperative handleRef (open/close/toggle/isOpen) for programmatic control.
  • useContainerReveal: two ways to control the reveal without reaching into the hook's private custom properties. getContainerProps({hoverDelay}) gates the reveal on pointer dwell — the hover-intent idea Tooltip and HoverCard already have as delay — so a cursor sweeping down a list no longer lights up every row it grazes, and getContainerProps({forceState}) pins the container's trigger state when something else owns the interaction (a scroll, a drag, an open row menu). Per element, getContentRevealProps({forceVisibility}) pins how one child looks regardless of its container. Still CSS-only: no hover state in React, no re-render. Keyboard and touch are untouched — focus always reveals, forceState: 'inactive' and forceVisibility: 'hidden' both yield to :focus-within.

Fixes

  • Banner: a dismissed banner no longer drops focus, a custom status no longer loses its ARIA role, and the info banner paints again under the neutral theme. Dismissing unmounted the focused dismiss button, so focus landed on <body> and a keyboard user lost their place in the page. Banner now records where focus entered from and returns it there, the same handoff ToastViewport makes for a dismissed toast. Measured in Chromium: document.activeElement was BODY, and is now the control the user tabbed in from.

    BannerStatusMap is documented as augmentable, but all four status lookups were closed Record<BannerStatus, ...> maps. Adding the augmentation the docs show produced four TypeScript errors inside Banner.tsx itself, which a consumer cannot fix, and at runtime an unknown status resolved to undefined for its icon, its background and its ARIA role, so the banner stopped being a live region at all. The lookups are partial now: an unrecognized status renders with no status fill, no default glyph and role="status".

    A theme could not reach the banner's radius. --_banner-radius was declared in the doc file and in derivedVarRegistry.ts, but no rule read it, so a theme's borderRadius on the banner target expanded into a variable nothing consumed. The four card-silhouette radii read it now, falling back to --radius-container.

    Under @astryxdesign/theme-neutral the info banner had no background at all, light or dark: the override set background-color directly and forced --color-accent-muted to transparent, and a plain CSS property written by a theme lands in @layer astryx-theme, which StyleX's @layer priority4 outranks. Info now goes through --color-accent-muted like the other three statuses and like the stone theme already did.

    Also in this change: children={false} (the ordinary {cond && <ul/>} idiom) no longer produces an expand toggle that opens an empty box, and description="" no longer leaves an empty 20px row, both via isRenderable; a long unbroken word in the title or description no longer forces the page into horizontal scrolling at a 320px viewport, measured at document.scrollWidth 529px before; and the content area's bottom border uses logical border-block-end alongside its inline siblings.

  • Count and cut text the way people read it: the TextArea character counter (and its over-limit state and screen-reader announcements) counts user-perceived characters — an emoji is 1, not 2; PowerSearch token truncation no longer cuts an emoji or accented letter in half; Table's auto-generated headers capitalize astral-plane letters correctly; Avatar's initials now use the shared character utilities.

  • ComplexSelector: honor the sm, md, and lg element-height tokens exactly.

  • TreeList's variant axis is themeable, and a new guard keeps every extensible axis honest. TreeListVariantMap invites theme packages to add variants — its own JSDoc shows the module augmentation — but themeProps('tree-list', {density}) never passed variant, so a custom variant type-checked, rendered, and produced no selector to style. It is passed now, and documented in the target's visualProps so astryx theme build stops calling it an unknown prop. packages/core/src/theme/extensibleAxes.test.ts is the third theming-drift guard, beside the ones covering targets and vars/derived. Those two check what a component renders against what it documents; neither looked at the open prop unions, which is why this went unnoticed. For every *Map that types a component prop, it now asserts the three places that have to agree: the interface is declared in the index a consumer augments (a re-export is invisible to both module augmentation and the CLI), the prop is reflected through themeProps, and it is documented as a visual prop. It reads the TypeScript AST rather than the type checker, and holds the map's OWNER accountable — a component forwarding actionVariant or statusVariant to the component that owns the map is not separately responsible for it.

    Registry maps that widen a set of NAMES rather than a visual prop (IndicatorMap, IndicatorFamilyMap) are out of scope by construction, not by allowlist: the guard only considers maps whose alias types a prop on a *Props interface.

  • Security: reject javascript:, vbscript: and data:text/html URLs in the Markdown parser, so untrusted markdown can no longer produce an executable link href or image src; and fix escapeRegExp in ChatTokenizedText, whose character class closed early and left ] and \ unescaped, so token values containing them were injected raw into a RegExp

  • extends now reaches the CSS. A theme that extended another built a stylesheet holding only the declarations it stated itself: the base's tokens, component overrides and surface rules were all absent, and because each theme is @scoped to its own data-astryx-theme value, loading the base's stylesheet alongside could not fill the gap either. Every consumer of an inheritance chain silently got stock geometry, elevation and type with a new palette painted over it (#5067). Nothing warned; the loss only showed up by diffing two generated stylesheets token by token. The cause was theme build shadowing its own inputs. It writes <name>.js next to <name>.ts, and the loader resolved a plain ./<name> specifier to that generated artifact before the source — so the second build of a family read the artifact, which carries no components and exports <name>Theme rather than whatever the source exports. A named import that missed became extends: undefined, and defineTheme treated an absent base as no base at all. The loader now resolves source extensions first, which is also the resolution the author's TypeScript sees, so the CSS a build emits matches the theme that type-checked.

    Three things behind it are fixed too, so the failure cannot come back by another route. defineTheme throws when extends is present but is not a theme, naming the likely cause, instead of inheriting nothing — the one behavior change here, and it turns a silent stylesheet into a build error. A theme's onDark/onLight surfaces and its __inputTokens are now inherited like its tokens and components were, so a child no longer reverts its base's inverted-surface customizations to the defaults or loses its [light, dark] tuples. And a built theme module now carries the resolved components and surfaces alongside its tokens, so extending one — the ./built subpath every shipped theme exposes — is no longer lossy. theme build also stopped hand-picking fields when it re-resolves a plain object theme file, which dropped extends, color and syntax on the way in.

    An extended theme is flat: everything it inherits is resolved into its own output, and its stylesheet stands alone. Measured on a 14-theme family (one base, 13 palettes extending it): each palette went from 25 custom properties and no component rules to the base's full 175 and 70, with its own colours still winning.

@​astryxdesign/cli

Fixes

  • The unloaded-font advisory is a notice, not a warning. A theme file cannot load a font — Astryx sets --font-family-* and loading is the app's job — so #5045's advisory fires on any theme naming a webfont, including a perfectly correct one. As a warning that made a clean build read as defective, and it put the shipped template permanently in violation of its own "compiles with no warnings" guard (#5079 had to allowlist the template's two font names in that assertion). The theme.build receipt now separates the two: warnings are defects the author should fix, notices are advisories about a correct theme. The font advisory moves to notices and to stdout with the rest of the build's progress; stderr stays for defects. The template guard is back to warnings being empty, and no longer needs to know which fonts the template names.

    Programmatic callers reading data.warnings for font advisories should read data.notices; the message text is unchanged.

  • extends now reaches the CSS. A theme that extended another built a stylesheet holding only the declarations it stated itself: the base's tokens, component overrides and surface rules were all absent, and because each theme is @scoped to its own data-astryx-theme value, loading the base's stylesheet alongside could not fill the gap either. Every consumer of an inheritance chain silently got stock geometry, elevation and type with a new palette painted over it (#5067). Nothing warned; the loss only showed up by diffing two generated stylesheets token by token.

... (truncated)

Changelog

Sourced from @​astryxdesign/cli's changelog.

0.4.3

Fixes

  • The unloaded-font advisory is a notice, not a warning. A theme file cannot load a font — Astryx sets --font-family-* and loading is the app's job — so #5045's advisory fires on any theme naming a webfont, including a perfectly correct one. As a warning that made a clean build read as defective, and it put the shipped template permanently in violation of its own "compiles with no warnings" guard (#5079 had to allowlist the template's two font names in that assertion). The theme.build receipt now separates the two: warnings are defects the author should fix, notices are advisories about a correct theme. The font advisory moves to notices and to stdout with the rest of the build's progress; stderr stays for defects. The template guard is back to warnings being empty, and no longer needs to know which fonts the template names.

    Programmatic callers reading data.warnings for font advisories should read data.notices; the message text is unchanged.

  • extends now reaches the CSS. A theme that extended another built a stylesheet holding only the declarations it stated itself: the base's tokens, component overrides and surface rules were all absent, and because each theme is @scoped to its own data-astryx-theme value, loading the base's stylesheet alongside could not fill the gap either. Every consumer of an inheritance chain silently got stock geometry, elevation and type with a new palette painted over it (#5067). Nothing warned; the loss only showed up by diffing two generated stylesheets token by token. The cause was theme build shadowing its own inputs. It writes <name>.js next to <name>.ts, and the loader resolved a plain ./<name> specifier to that generated artifact before the source — so the second build of a family read the artifact, which carries no components and exports <name>Theme rather than whatever the source exports. A named import that missed became extends: undefined, and defineTheme treated an absent base as no base at all. The loader now resolves source extensions first, which is also the resolution the author's TypeScript sees, so the CSS a build emits matches the theme that type-checked.

    Three things behind it are fixed too, so the failure cannot come back by another route. defineTheme throws when extends is present but is not a theme, naming the likely cause, instead of inheriting nothing — the one behavior change here, and it turns a silent stylesheet into a build error. A theme's onDark/onLight surfaces and its __inputTokens are now inherited like its tokens and components were, so a child no longer reverts its base's inverted-surface customizations to the defaults or loses its [light, dark] tuples. And a built theme module now carries the resolved components and surfaces alongside its tokens, so extending one — the ./built subpath every shipped theme exposes — is no longer lossy. theme build also stopped hand-picking fields when it re-resolves a plain object theme file, which dropped extends, color and syntax on the way in.

    An extended theme is flat: everything it inherits is resolved into its own output, and its stylesheet stands alone. Measured on a 14-theme family (one base, 13 palettes extending it): each palette went from 25 custom properties and no component rules to the base's full 175 and 70, with its own colours still winning.

Contributors

Thanks to everyone who contributed to this release:


0.4.2

New Features

  • astryx theme build warns when a theme names fonts it does not load. The resolved --font-family-* tokens and component-override fontFamily values are checked against CSS generics and known system families; anything else gets one warning per family in the receipt and, after the install instructions, the <link>/@font-face snippet to add. astryx docs typography gains a Loading Custom Fonts section (Google Fonts and self-hosted recipes, font-display: swap, real fallback stacks), and the theme docs' production-build section points at it (#5015).

  • astryx theme template writes an annotated theme template into your project (#5048). New sibling of theme add: where add starts you from a theme we ship, template starts you from a blank annotated one. astryx init --features theme calls the same leaf, so project setup writes it too — it previously printed a one-line hint and wrote nothing, which is the weakest form of the help a theme author needs, since the first problem is not knowing the command but not knowing what the theme surface contains. The file is theme.template.ts: every defineTheme field with a note on when to reach for it, the token families, the component override syntax, and the consumption steps (providing the theme, loading the fonts you name, building for SSR), each section naming the CLI command that prints its authoritative reference. An existing file is never clobbered.

    This came out of a vibe test (#5047): agents given an annotated template reached twice as far into the theme surface as agents given only the docs (17 component targets vs 8, and the only arm to use interaction states, custom variants and onDark), and shipped a third of the contrast defects.

    A template that lies is worse than no template, so its claims are machine-checked against live sources rather than trusted: scripts/check-theme-template.test.mjs fails when a defineTheme field is added and left undocumented, when a token family is missing from the inventory, when a CSS variable or component key it names does not exist, when it cites a docs topic that does not, or when a theme source drops its SYNC reference. theme build compiles it warning-free in CI, and the CLI typecheck now covers it.

Fixes

  • Heading's type is a documented theming target, and the docs stop teaching a CSS variable that does not exist (#5016). Heading reflects type as a theme selector — typography.scale generates heading: {'type:display-1' …} rules for it — but theming.targets listed only level and color, so astryx theme build warned Unknown prop "type" on component "heading" on every theme that sets a type scale, including the shipped neutralTheme. The drift guard missed it twice over: it read a conditional spread ({level, color, ...(type && {type})}) as an unknown bag, and it only checked a component against a doc file in its own directory, so Heading/ — documented from Text/Text.doc.mjs — was never checked at all. Both are fixed, which brings three more previously unchecked directories under the guard.

    Separately, the theme docs' component-override example set --button-press-scale, which no component defines: copying it produces CSS that silently never applies. It now sets a real public var, and the example no longer declares the same button key twice.

  • Two guards left failing on main by their own landings, so every PR since has been red through no fault of its own. #4963 gave Thumbnail's remove button a coarse-pointer hit-area var and did not document it, which the derived-var guard reads as an undocumented private var; the var is an inset on a ::after overlay, so it is documented as private and listed alongside the other vars no standard CSS property maps onto. #5026 moved borderDefaults into CoreTokenName — the landing the theme-template guard was explicitly waiting for (its comment says "when #5017 lands, this guard starts requiring the template to cover it") — so the template's token inventory now names --border-width.

Documentation

  • MobileNavToggle preview simulates a mobile AppShell instead of an empty stage: new playground.appShellMobile for components that render nothing without AppShell mobile context (#4983)

Contributors

... (truncated)

Commits
  • d9189c9 chore: version packages for v0.4.3
  • 44cde5e test(cli): synchronize watch assertion on rebuilt theme module (#5122)
  • 4d004cd Banner audit: dismiss focus handoff, status fall-through, empty slots and 320...
  • da6ea67 fix(cli): the unloaded-font advisory is a notice, not a warning (#5090)
  • 8b07cb9 fix(themes,cli): gate theme dists with check-fully-specified and pin --icons-...
  • 01592f7 feat(core): expand ComplexSelector composition API (#4769)
  • bb07062 fix: security — XSS in Markdown parser, ReDoS in ChatTokenizedText, dotfile c...
  • 356d2f9 fix(theme): make extends reach the CSS (#5067)
  • 791f395 chore: version packages for v0.4.2 (#5083)
  • 5ed78ad test(cli): the shipped theme template warns about its own fonts by design (#5...
  • Additional commits viewable in compare view

Updates @astryxdesign/core from 0.4.0 to 0.4.3

Release notes

Sourced from @​astryxdesign/core's releases.

v0.4.3

Astryx 0.4.3 — all @astryxdesign/* packages ship at this version.

npx astryx upgrade --apply

@​astryxdesign/core

New Features

  • New string utilities: characterCount, firstCharacter, and truncateCharacters — replacements for .length, .charAt(0), and slice-based truncation that measure and cut user-visible strings by whole characters, so an emoji, flag, or accented letter counts as one and never gets split. Built on Intl.Segmenter with a code-point fallback.
  • ComplexSelector: support ghost toolbar triggers, leading icons, popup alignment, and an imperative handleRef (open/close/toggle/isOpen) for programmatic control.
  • useContainerReveal: two ways to control the reveal without reaching into the hook's private custom properties. getContainerProps({hoverDelay}) gates the reveal on pointer dwell — the hover-intent idea Tooltip and HoverCard already have as delay — so a cursor sweeping down a list no longer lights up every row it grazes, and getContainerProps({forceState}) pins the container's trigger state when something else owns the interaction (a scroll, a drag, an open row menu). Per element, getContentRevealProps({forceVisibility}) pins how one child looks regardless of its container. Still CSS-only: no hover state in React, no re-render. Keyboard and touch are untouched — focus always reveals, forceState: 'inactive' and forceVisibility: 'hidden' both yield to :focus-within.

Fixes

  • Banner: a dismissed banner no longer drops focus, a custom status no longer loses its ARIA role, and the info banner paints again under the neutral theme. Dismissing unmounted the focused dismiss button, so focus landed on <body> and a keyboard user lost their place in the page. Banner now records where focus entered from and returns it there, the same handoff ToastViewport makes for a dismissed toast. Measured in Chromium: document.activeElement was BODY, and is now the control the user tabbed in from.

    BannerStatusMap is documented as augmentable, but all four status lookups were closed Record<BannerStatus, ...> maps. Adding the augmentation the docs show produced four TypeScript errors inside Banner.tsx itself, which a consumer cannot fix, and at runtime an unknown status resolved to undefined for its icon, its background and its ARIA role, so the banner stopped being a live region at all. The lookups are partial now: an unrecognized status renders with no status fill, no default glyph and role="status".

    A theme could not reach the banner's radius. --_banner-radius was declared in the doc file and in derivedVarRegistry.ts, but no rule read it, so a theme's borderRadius on the banner target expanded into a variable nothing consumed. The four card-silhouette radii read it now, falling back to --radius-container.

    Under @astryxdesign/theme-neutral the info banner had no background at all, light or dark: the override set background-color directly and forced --color-accent-muted to transparent, and a plain CSS property written by a theme lands in @layer astryx-theme, which StyleX's @layer priority4 outranks. Info now goes through --color-accent-muted like the other three statuses and like the stone theme already did.

    Also in this change: children={false} (the ordinary {cond && <ul/>} idiom) no longer produces an expand toggle that opens an empty box, and description="" no longer leaves an empty 20px row, both via isRenderable; a long unbroken word in the title or description no longer forces the page into horizontal scrolling at a 320px viewport, measured at document.scrollWidth 529px before; and the content area's bottom border uses logical border-block-end alongside its inline siblings.

  • Count and cut text the way people read it: the TextArea character counter (and its over-limit state and screen-reader announcements) counts user-perceived characters — an emoji is 1, not 2; PowerSearch token truncation no longer cuts an emoji or accented letter in half; Table's auto-generated headers capitalize astral-plane letters correctly; Avatar's initials now use the shared character utilities.

  • ComplexSelector: honor the sm, md, and lg element-height tokens exactly.

  • TreeList's variant axis is themeable, and a new guard keeps every extensible axis honest. TreeListVariantMap invites theme packages to add variants — its own JSDoc shows the module augmentation — but themeProps('tree-list', {density}) never passed variant, so a custom variant type-checked, rendered, and produced no selector to style. It is passed now, and documented in the target's visualProps so astryx theme build stops calling it an unknown prop. packages/core/src/theme/extensibleAxes.test.ts is the third theming-drift guard, beside the ones covering targets and vars/derived. Those two check what a component renders against what it documents; neither looked at the open prop unions, which is why this went unnoticed. For every *Map that types a component prop, it now asserts the three places that have to agree: the interface is declared in the index a consumer augments (a re-export is invisible to both module augmentation and the CLI), the prop is reflected through themeProps, and it is documented as a visual prop. It reads the TypeScript AST rather than the type checker, and holds the map's OWNER accountable — a component forwarding actionVariant or statusVariant to the component that owns the map is not separately responsible for it.

    Registry maps that widen a set of NAMES rather than a visual prop (IndicatorMap, IndicatorFamilyMap) are out of scope by construction, not by allowlist: the guard only considers maps whose alias types a prop on a *Props interface.

  • Security: reject javascript:, vbscript: and data:text/html URLs in the Markdown parser, so untrusted markdown can no longer produce an executable link href or image src; and fix escapeRegExp in ChatTokenizedText, whose character class closed early and left ] and \ unescaped, so token values containing them were injected raw into a RegExp

  • extends now reaches the CSS. A theme that extended another built a stylesheet holding only the declarations it stated itself: the base's tokens, component overrides and surface rules were all absent, and because each theme is @scoped to its own data-astryx-theme value, loading the base's stylesheet alongside could not fill the gap either. Every consumer of an inheritance chain silently got stock geometry, elevation and type with a new palette painted over it (#5067). Nothing warned; the loss only showed up by diffing two generated stylesheets token by token. The cause was theme build shadowing its own inputs. It writes <name>.js next to <name>.ts, and the loader resolved a plain ./<name> specifier to that generated artifact before the source — so the second build of a family read the artifact, which carries no components and exports <name>Theme rather than whatever the source exports. A named import that missed became extends: undefined, and defineTheme treated an absent base as no base at all. The loader now resolves source extensions first, which is also the resolution the author's TypeScript sees, so the CSS a build emits matches the theme that type-checked.

    Three things behind it are fixed too, so the failure cannot come back by another route. defineTheme throws when extends is present but is not a theme, naming the likely cause, instead of inheriting nothing — the one behavior change here, and it turns a silent stylesheet into a build error. A theme's onDark/onLight surfaces and its __inputTokens are now inherited like its tokens and components were, so a child no longer reverts its base's inverted-surface customizations to the defaults or loses its [light, dark] tuples. And a built theme module now carries the resolved components and surfaces alongside its tokens, so extending one — the ./built subpath every shipped theme exposes — is no longer lossy. theme build also stopped hand-picking fields when it re-resolves a plain object theme file, which dropped extends, color and syntax on the way in.

    An extended theme is flat: everything it inherits is resolved into its own output, and its stylesheet stands alone. Measured on a 14-theme family (one base, 13 palettes extending it): each palette went from 25 custom properties and no component rules to the base's full 175 and 70, with its own colours still winning.

@​astryxdesign/cli

Fixes

  • The unloaded-font advisory is a notice, not a warning. A theme file cannot load a font — Astryx sets --font-family-* and loading is the app's job — so #5045's advisory fires on any theme naming a webfont, including a perfectly correct one. As a warning that made a clean build read as defective, and it put the shipped template permanently in violation of its own "compiles with no warnings" guard (#5079 had to allowlist the template's two font names in that assertion). The theme.build receipt now separates the two: warnings are defects the author should fix, notices are advisories about a correct theme. The font advisory moves to notices and to stdout with the rest of the build's progress; stderr stays for defects. The template guard is back to warnings being empty, and no longer needs to know which fonts the template names.

    Programmatic callers reading data.warnings for font advisories should read data.notices; the message text is unchanged.

  • extends now reaches the CSS. A theme that extended another built a stylesheet holding only the declarations it stated itself: the base's tokens, component overrides and surface rules were all absent, and because each theme is @scoped to its own data-astryx-theme value, loading the base's stylesheet alongside could not fill the gap either. Every consumer of an inheritance chain silently got stock geometry, elevation and type with a new palette painted over it (#5067). Nothing warned; the loss only showed up by diffing two generated stylesheets token by token.

... (truncated)

Changelog

Sourced from @​astryxdesign/core's changelog.

0.4.3

New Features

  • New string utilities: characterCount, firstCharacter, and truncateCharacters — replacements for .length, .charAt(0), and slice-based truncation that measure and cut user-visible strings by whole characters, so an emoji, flag, or accented letter counts as one and never gets split. Built on Intl.Segmenter with a code-point fallback.
  • ComplexSelector: support ghost toolbar triggers, leading icons, popup alignment, and an imperative handleRef (open/close/toggle/isOpen) for programmatic control.
  • useContainerReveal: two ways to control the reveal without reaching into the hook's private custom properties. getContainerProps({hoverDelay}) gates the reveal on pointer dwell — the hover-intent idea Tooltip and HoverCard already have as delay — so a cursor sweeping down a list no longer lights up every row it grazes, and getContainerProps({forceState}) pins the container's trigger state when something else owns the interaction (a scroll, a drag, an open row menu). Per element, getContentRevealProps({forceVisibility}) pins how one child looks regardless of its container. Still CSS-only: no hover state in React, no re-render. Keyboard and touch are untouched — focus always reveals, forceState: 'inactive' and forceVisibility: 'hidden' both yield to :focus-within.

Fixes

  • Banner: a dismissed banner no longer drops focus, a custom status no longer loses its ARIA role, and the info banner paints again under the neutral theme. Dismissing unmounted the focused dismiss button, so focus landed on <body> and a keyboard user lost their place in the page. Banner now records where focus entered from and returns it there, the same handoff ToastViewport makes for a dismissed toast. Measured in Chromium: document.activeElement was BODY, and is now the control the user tabbed in from.

    BannerStatusMap is documented as augmentable, but all four status lookups were closed Record<BannerStatus, ...> maps. Adding the augmentation the docs show produced four TypeScript errors inside Banner.tsx itself, which a consumer cannot fix, and at runtime an unknown status resolved to undefined for its icon, its background and its ARIA role, so the banner stopped being a live region at all. The lookups are partial now: an unrecognized status renders with no status fill, no default glyph and role="status".

    A theme could not reach the banner's radius. --_banner-radius was declared in the doc file and in derivedVarRegistry.ts, but no rule read it, so a theme's borderRadius on the banner target expanded into a variable nothing consumed. The four card-silhouette radii read it now, falling back to --radius-container.

    Under @astryxdesign/theme-neutral the info banner had no background at all, light or dark: the override set background-color directly and forced --color-accent-muted to transparent, and a plain CSS property written by a theme lands in @layer astryx-theme, which StyleX's @layer priority4 outranks. Info now goes through --color-accent-muted like the other three statuses and like the stone theme already did.

    Also in this change: children={false} (the ordinary {cond && <ul/>} idiom) no longer produces an expand toggle that opens an empty box, and description="" no longer leaves an empty 20px row, both via isRenderable; a long unbroken word in the title or description no longer forces the page into horizontal scrolling at a 320px viewport, measured at document.scrollWidth 529px before; and the content area's bottom border uses logical border-block-end alongside its inline siblings.

  • Count and cut text the way people read it: the TextArea character counter (and its over-limit state and screen-reader announcements) counts user-perceived characters — an emoji is 1, not 2; PowerSearch token truncation no longer cuts an emoji or accented letter in half; Table's auto-generated headers capitalize astral-plane letters correctly; Avatar's initials now use the shared character utilities.

  • ComplexSelector: honor the sm, md, and lg element-height tokens exactly.

  • TreeList's variant axis is themeable, and a new guard keeps every extensible axis honest. TreeListVariantMap invites theme packages to add variants — its own JSDoc shows the module augmentation — but themeProps('tree-list', {density}) never passed variant, so a custom variant type-checked, rendered, and produced no selector to style. It is passed now, and documented in the target's visualProps so astryx theme build stops calling it an unknown prop. packages/core/src/theme/extensibleAxes.test.ts is the third theming-drift guard, beside the ones covering targets and vars/derived. Those two check what a component renders against what it documents; neither looked at the open prop unions, which is why this went unnoticed. For every *Map that types a component prop, it now asserts the three places that have to agree: the interface is declared in the index a consumer augments (a re-export is invisible to both module augmentation and the CLI), the prop is reflected through themeProps, and it is documented as a visual prop. It reads the TypeScript AST rather than the type checker, and holds the map's OWNER accountable — a component forwarding actionVariant or statusVariant to the component that owns the map is not separately responsible for it.

    Registry maps that widen a set of NAMES rather than a visual prop (IndicatorMap, IndicatorFamilyMap) are out of scope by construction, not by allowlist: the guard only considers maps whose alias types a prop on a *Props interface.

  • Security: reject javascript:, vbscript: and data:text/html URLs in the Markdown parser, so untrusted markdown can no longer produce an executable link href or image src; and fix escapeRegExp in ChatTokenizedText, whose character class closed early and left ] and \ unescaped, so token values containing them were injected raw into a RegExp

  • extends now reaches the CSS. A theme that extended another built a stylesheet holding only the declarations it stated itself: the base's tokens, component overrides and surface rules were all absent, and because each theme is @scoped to its own data-astryx-theme value, loading the base's stylesheet alongside could not fill the gap either. Every consumer of an inheritance chain silently got stock geometry, elevation and type with a new palette painted over it (#5067). Nothing warned; the loss only showed up by diffing two generated stylesheets token by token. The cause was theme build shadowing its own inputs. It writes <name>.js next to <name>.ts, and the loader resolved a plain ./<name> specifier to that generated artifact before the source — so the second build of a family read the artifact, which carries no components and exports <name>Theme rather than whatever the source exports. A named import that missed became extends: undefined, and defineTheme treated an absent base as no base at all. The loader now resolves source extensions first, which is also the resolution the author's TypeScript sees, so the CSS a build emits matches the theme that type-checked.

    Three things behind it are fixed too, so the failure cannot come back by another route. defineTheme throws when extends is present but is not a theme, naming the likely cause, instead of inheriting nothing — the one behavior change here, and it turns a silent stylesheet into a build error. A theme's onDark/onLight surfaces and its __inputTokens are now inherited like its tokens and components were, so a child no longer reverts its base's inverted-surface customizations to the defaults or loses its [light, dark] tuples. And a built theme module now carries the resolved components and surfaces alongside its tokens, so extending one — the ./built subpath every shipped theme exposes — is no longer lossy. theme build also stopped hand-picking fields when it re-resolves a plain object theme file, which dropped extends, color and syntax on the way in.

    An extended theme is flat: everything it inherits is resolved into its own output, and its stylesheet stands alone. Measured on a 14-theme family (one base, 13 palettes extending it): each palette went from 25 custom properties and no component rules to the base's full 175 and 70, with its own colours still winning.

Contributors

Thanks to everyone who contributed to this release:


0.4.2

New Features

... (truncated)

Commits
  • d9189c9 chore: version packages for v0.4.3
  • 4d004cd Banner audit: dismiss focus handoff, status fall-through, empty slots and 320...
  • 255e810 fix(TreeList): make the variant axis themeable, and guard every axis like it ...
  • 86a7f17 Grapheme-safe text: count characters the way people do (#4776)
  • 01592f7 feat(core): expand ComplexSelector composition API (#4769)
  • bb07062 fix: security — XSS in Markdown parser, ReDoS in ChatTokenizedText, dotfile c...
  • 356d2f9 fix(theme): make extends reach the CSS (#5067)
  • b2057d1 feat(useContainerReveal): hover-intent delay and forced reveal state (#5084)
  • 791f395 chore: version packages for v0.4.2 (#5083)
  • 15a65d5 feat(AvatarGroup): expose size on the avatar-group-overflow theming target (#...
  • Additional commits viewable in compare view

Updates @biomejs/biome from 2.5.6 to 2.5.8

Release notes

Sourced from @​biomejs/biome's releases.

Biome CLI v2.5.8

2.5.8

Patch Changes

  • #10710 0a0fbc1 Thanks @​dyc3! - Added a new nursery rule useReactCompiler, which reports diagnostics from React Compiler lint mode.

  • #11251 ea9dd8a Thanks @​dyc3! - Improved performance of noImportCycles.

  • #11247 52b44d6 Thanks @​dyc3! - Added the nursery rule noSvelteLegacyConst, which disallows legacy Svelte {@const} tags and recommends declaration tags with $derived().

    Invalid:

    {#each boxes as box}
      {@const area = box.width * box.height}
      <p>{area}</p>
    {/each}

    Valid:

    {#each boxes as box}
      {const area = $derived(box.width * box.height)}
      <p>{area}</p>
    {/each}
  • #11252 d5f5704 Thanks @​Turtle-Hwan! - Fixed #11250: useAwait no longer reports async functions that contain an await using declaration.

  • #11143 6be7be1 Thanks @​vznh! - Fixed #11017: noUselessUndefined no longer reports return undefined when the enclosing function has a return type annotation other than undefined or void.

  • #11234 caefe39 Thanks @​subotac! - Fixed #11228: CSS block comments between a declaration colon and value now preserve their source indentation.

     :root {
       --font-stack:
    -/* comment */
    +    /* comment */
         system-ui;
     }
  • #11285 bca1f73 Thanks @​denbezrukov! - Fixed #11280: CSS formatting keeps comments inside functional pseudo-classes and pseudo-elements instead of moving them before the function name.

    -:/* comment */ where(div) {}
    +:where(/* comment */ div) {}

... (truncated)

Changelog

Sourced from @​biomejs/biome's changelog.

2.5.8

Patch Changes

  • #10710 0a0fbc1 Thanks @​dyc3! - Added a new nursery rule useReactCompiler, which reports diagnostics from React Compiler lint mode.

  • #11251 ea9dd8a Thanks @​dyc3! - Improved performance of noImportCycles.

  • #11247 52b44d6 Thanks @​dyc3! - Added the nursery rule noSvelteLegacyConst, which disallows legacy Svelte {@const} tags and recommends declaration tags with $derived().

    Invalid:

    {#each boxes as box}
      {@const area = box.width * box.height}
      <p>{area}</p>
    {/each}

    Valid:

    {#each boxes as box}
      {const area = $derived(box.width * box.height)}
      <p>{area}</p>
    {/each}
  • #11252 d5f5704 Thanks @​Turtle-Hwan! - Fixed #11250: useAwait no longer reports async functions that contain an await using declaration.

  • #11143 6be7be1 Thanks @​vznh! - Fixed #11017: noUselessUndefined no longer reports return undefined when the enclosing function has a return type annotation other than undefined or void.

  • #11234 caefe39 Thanks @​subotac! - Fixed #11228: CSS block comments between a declaration colon and value now preserve their source indentation.

     :root {
       --font-stack:
    -/* comment */
    +    /* comment */
         system-ui;
     }
  • #11285 bca1f73 Thanks @​denbezrukov! - Fixed #11280: CSS formatting keeps comments inside functional pseudo-classes and pseudo-elements instead of moving them before the function name.

    -:/* comment */ where(div) {}
    +:where(/* comment */ div) {}

... (truncated)

Commits

Updates @types/node from 26.1.2 to 26.2.0

Commits

Updates dugite from 3.2.2 to 3.2.3

Release notes

Sourced from dugite's releases.

v3.2.3

What's Changed

Full Changelog: desktop/dugite@v3.2.2...v3.2.3

Commits

…8 updates

Bumps the minor-and-patch group with 17 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@astryxdesign/cli](https://github.com/facebook/astryx/tree/HEAD/packages/cli) | `0.4.0` | `0.4.3` |
| [@astryxdesign/core](https://github.com/facebook/astryx/tree/HEAD/packages/core) | `0.4.0` | `0.4.3` |
| [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.5.6` | `2.5.8` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `26.1.2` | `26.2.0` |
| [dugite](https://github.com/desktop/dugite) | `3.2.2` | `3.2.3` |
| [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) | `6.26.0` | `6.32.2` |
| [@ai-sdk/openai-compatible](https://github.com/vercel/ai/tree/HEAD/packages/openai-compatible) | `3.0.30` | `3.0.31` |
| [@larksuiteoapi/node-sdk](https://github.com/larksuite/node-sdk) | `1.72.0` | `1.73.0` |
| [@openai/agents-core](https://github.com/openai/openai-agents-js) | `0.14.3` | `0.16.1` |
| [ws](https://github.com/websockets/ws) | `8.21.2` | `8.21.3` |
| [esbuild](https://github.com/evanw/esbuild) | `0.28.1` | `0.28.2` |
| [electron](https://github.com/electron/electron) | `43.2.0` | `43.4.0` |
| [@earendil-works/pi-tui](https://github.com/earendil-works/pi/tree/HEAD/packages/tui) | `0.83.0` | `0.84.2` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.28.0` | `1.31.0` |
| [@astryxdesign/theme-neutral](https://github.com/facebook/astryx/tree/HEAD/packages/themes/neutral) | `0.4.0` | `0.4.3` |
| [@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite) | `10.5.6` | `10.5.8` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.1.5` | `8.2.1` |



Updates `@astryxdesign/cli` from 0.4.0 to 0.4.3
- [Release notes](https://github.com/facebook/astryx/releases)
- [Changelog](https://github.com/facebook/astryx/blob/main/packages/cli/CHANGELOG.md)
- [Commits](https://github.com/facebook/astryx/commits/v0.4.3/packages/cli)

Updates `@astryxdesign/core` from 0.4.0 to 0.4.3
- [Release notes](https://github.com/facebook/astryx/releases)
- [Changelog](https://github.com/facebook/astryx/blob/main/packages/core/CHANGELOG.md)
- [Commits](https://github.com/facebook/astryx/commits/v0.4.3/packages/core)

Updates `@biomejs/biome` from 2.5.6 to 2.5.8
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.5.8/packages/@biomejs/biome)

Updates `@types/node` from 26.1.2 to 26.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `dugite` from 3.2.2 to 3.2.3
- [Release notes](https://github.com/desktop/dugite/releases)
- [Changelog](https://github.com/desktop/dugite/blob/main/docs/releases.md)
- [Commits](desktop/dugite@v3.2.2...v3.2.3)

Updates `knip` from 6.26.0 to 6.32.2
- [Release notes](https://github.com/webpro-nl/knip/releases)
- [Commits](https://github.com/webpro-nl/knip/commits/knip@6.32.2/packages/knip)

Updates `@ai-sdk/openai-compatible` from 3.0.30 to 3.0.31
- [Release notes](https://github.com/vercel/ai/releases)
- [Changelog](https://github.com/vercel/ai/blob/main/packages/openai-compatible/CHANGELOG.md)
- [Commits](https://github.com/vercel/ai/commits/@ai-sdk/openai-compatible@3.0.31/packages/openai-compatible)

Updates `@larksuiteoapi/node-sdk` from 1.72.0 to 1.73.0
- [Commits](https://github.com/larksuite/node-sdk/commits)

Updates `@openai/agents-core` from 0.14.3 to 0.16.1
- [Release notes](https://github.com/openai/openai-agents-js/releases)
- [Commits](openai/openai-agents-js@v0.14.3...v0.16.1)

Updates `ws` from 8.21.2 to 8.21.3
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](websockets/ws@8.21.2...8.21.3)

Updates `esbuild` from 0.28.1 to 0.28.2
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](evanw/esbuild@v0.28.1...v0.28.2)

Updates `electron` from 43.2.0 to 43.4.0
- [Release notes](https://github.com/electron/electron/releases)
- [Commits](electron/electron@v43.2.0...v43.4.0)

Updates `@earendil-works/pi-tui` from 0.83.0 to 0.84.2
- [Release notes](https://github.com/earendil-works/pi/releases)
- [Changelog](https://github.com/earendil-works/pi/blob/main/packages/tui/CHANGELOG.md)
- [Commits](https://github.com/earendil-works/pi/commits/v0.84.2/packages/tui)

Updates `lucide-react` from 1.28.0 to 1.31.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.31.0/packages/lucide-react)

Updates `@astryxdesign/theme-neutral` from 0.4.0 to 0.4.3
- [Release notes](https://github.com/facebook/astryx/releases)
- [Changelog](https://github.com/facebook/astryx/blob/main/packages/themes/neutral/CHANGELOG.md)
- [Commits](https://github.com/facebook/astryx/commits/v0.4.3/packages/themes/neutral)

Updates `@storybook/react-vite` from 10.5.6 to 10.5.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.5.8/code/frameworks/react-vite)

Updates `storybook` from 10.5.6 to 10.5.8
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v10.5.8/code/core)

Updates `vite` from 8.1.5 to 8.2.1
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.2.1/packages/vite)

---
updated-dependencies:
- dependency-name: "@astryxdesign/cli"
  dependency-version: 0.4.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@astryxdesign/core"
  dependency-version: 0.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@biomejs/biome"
  dependency-version: 2.5.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@types/node"
  dependency-version: 26.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: dugite
  dependency-version: 3.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: knip
  dependency-version: 6.32.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@ai-sdk/openai-compatible"
  dependency-version: 3.0.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@larksuiteoapi/node-sdk"
  dependency-version: 1.73.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@openai/agents-core"
  dependency-version: 0.16.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: ws
  dependency-version: 8.21.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: esbuild
  dependency-version: 0.28.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: electron
  dependency-version: 43.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@earendil-works/pi-tui"
  dependency-version: 0.84.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: lucide-react
  dependency-version: 1.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@astryxdesign/theme-neutral"
  dependency-version: 0.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: "@storybook/react-vite"
  dependency-version: 10.5.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: storybook
  dependency-version: 10.5.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: vite
  dependency-version: 8.2.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript labels Aug 20, 2026
Dependabot bumped @astryxdesign/core to 0.4.3, but patch-package refuses a
0.4.0 patch filename. The patched files are unchanged, so the hunks apply as-is.
The grouped Dependabot bump installed only after retargeting the Astryx
patch. The rest of CI then needed the 0.4.3 theme artifacts, TuiMainScreen
in place of the now type-only TUI export, knip 6.32 unused-export cleanup,
and bundled Git pins moved to dugite 3.2.3 / dugite-native v2.53.0-4.

Generated-by: pi
Exact-version license overrides still named core 0.4.0 and pi-tui 0.83.0,
so check:release could not generate notices. Add 0.4.3 and 0.84.2, regenerate
both inventories, pin Git for Windows and GCM to the dugite-native v2.53.0-4
revisions, and move allowScripts onto esbuild 0.28.2.

Generated-by: pi
DropdownMenu layers no longer appear in server markup. Render the composer
in a document so the mode rows, divider, and checked state stay asserted.

Generated-by: pi
The CLI emits maka.variants.d.ts again. Track it and stop stripping the
reference from maka.d.ts so gray/elevated typing cannot drift unchecked.

Generated-by: pi

@hqhq1025 hqhq1025 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.

Review triage of 1d710c9

No dependency-specific correctness finding is established on this stale head, but the revision is not ready for a merge-readiness review.

Problem and mechanism: this grouped update advances 17 direct dependency surfaces and includes the required repository follow-ups for Astryx patches/generated theme declarations, pi-tui exports, knip cleanup, Dugite bundled-Git pins, license notices, and generated artifacts. Those follow-up commits are part of the patch and must survive any branch refresh.

Current gate: GitHub reports the branch conflicting with current main. A local merge-tree reproduces content conflicts in package.json, apps/desktop/package.json, and package-lock.json. Required CI and dependency audit passed on the old base, but the Windows package workflow was cancelled, so the Electron 43.4.0 and Dugite 3.2.3 packaging surfaces are not verified on a mergeable revision.

Next step: rebase or merge current main while preserving the five maintainer follow-up commits, regenerate the lockfile, Astryx theme outputs, third-party notices, and bundled-Git metadata from that resolved tree, then rerun required CI plus the platform package checks. A bare Dependabot regeneration must not silently discard the manually added compatibility fixes.

Merge verdict: not ready to merge until a conflict-free exact head exists and its generated/package artifacts pass. This is a normal COMMENT review under the maintainer comment-only policy; no REQUEST_CHANGES state is used.

Residual review focus after refresh: Astryx patch applicability and renderer behavior, OpenAI Agents 0.16 API compatibility, Electron packaging, pi-tui runtime exports, and Dugite archive/license/digest verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants