Repository navigation
feat: redesign ui - #48
Conversation
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (226)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughAdds Playwright visual-test config and Storybook server script; introduces many new UI components and tests; refactors component import paths and styles; updates Alert/Input styling and Sonner toaster; and fixes numerous tests to return early after fatal assertions plus a small transport error-recording reorder. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
|
There was a problem hiding this comment.
Actionable comments posted: 12
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (10)
packages/ui/src/components/alert.test.tsx-7-18 (1)
7-18:⚠️ Potential issue | 🟡 MinorTest intent says class forwarding, but class forwarding is not asserted.
Line 7 says this test verifies class forwarding, but the render call does not pass
className, and no class assertion exists. Please either rename the test or assert class forwarding explicitly.Suggested patch
- it("renders role=alert by default and forwards class + data-variant", () => { + it("renders role=alert by default and forwards class + data-variant", () => { render( - <Alert data-testid="alert" variant="warning"> + <Alert data-testid="alert" variant="warning" className="custom-alert"> <AlertTitle>Heads up</AlertTitle> <AlertDescription>Restart required</AlertDescription> </Alert> ); const alert = screen.getByTestId("alert"); expect(alert).toHaveAttribute("role", "alert"); expect(alert).toHaveAttribute("data-variant", "warning"); expect(alert).toHaveAttribute("data-slot", "alert"); + expect(alert).toHaveClass("custom-alert"); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/alert.test.tsx` around lines 7 - 18, The test named "renders role=alert by default and forwards class + data-variant" currently does not exercise class forwarding; update the test for the Alert component by passing a className (e.g., className="foo") into the rendered <Alert ...> and add an assertion that the rendered element (queried via getByTestId("alert")) includes that class (e.g., toHaveClass("foo"); alternatively, if you prefer to keep the current assertions, rename the test to remove "forwards class" from the title so it accurately reflects that it only verifies role, data-variant, and data-slot for Alert with AlertTitle and AlertDescription).packages/ui/src/components/kind-chip.tsx-17-27 (1)
17-27:⚠️ Potential issue | 🟡 MinorPrevent overriding internal
data-slot/data-kindmarkers.Because
{...props}is applied last, callers can override internal markers (e.g.,data-slot,data-kind). If these are intended to be stable hooks, make internal attributes win.Suggested fix
<span - data-slot="kind-chip" - data-kind={kind} + {...props} + data-slot="kind-chip" + data-kind={kind} className={cn( "inline-flex items-center rounded-[var(--radius-chip)] px-1.5 py-0.5", "font-mono text-[10.5px] font-medium leading-[14px] lowercase whitespace-nowrap", "bg-[color:var(--color-accent-tint)] text-[color:var(--color-accent)]", className )} - {...props} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/kind-chip.tsx` around lines 17 - 27, The span in kind-chip.tsx exposes internal markers data-slot and data-kind to be overridden because {...props} is spread last; change the spread order or filter props so internal attributes win: either spread {...props} before the explicit attributes (data-slot="kind-chip", data-kind={kind}, className={cn(...)}), or destructure and remove data-slot/data-kind from incoming props (e.g., const { "data-slot": _, "data-kind": __, ...rest } = props) and then spread rest; update the span to use the chosen approach so data-slot and data-kind (and the className computed by cn) cannot be overwritten by callers.packages/ui/src/components/chat-message-bubble.test.tsx-130-139 (1)
130-139:⚠️ Potential issue | 🟡 MinorAdd align-override cases for non-
userroles (or explicitly lock the API down)Line 130 currently validates
alignoverride only forrole="user". Sincealignis part of the public props, add coverage foragent/tool/diff(and clarifysystembehavior) so API intent is explicit.✅ Suggested test expansion
it("Should honour an explicit align override", () => { @@ }); + + it.each(["agent", "tool", "diff"] as const)( + "Should honour align override for role='%s'", + role => { + const { container } = render( + <ChatMessageBubble role={role} align="right"> + override + </ChatMessageBubble> + ); + const root = container.querySelector<HTMLElement>('[data-slot="chat-message"]'); + expect(root?.getAttribute("data-align")).toBe("right"); + } + );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/chat-message-bubble.test.tsx` around lines 130 - 139, The test only checks ChatMessageBubble align override for role="user"; add additional test cases in chat-message-bubble.test.tsx that call render(<ChatMessageBubble role="agent" align="left">...</ChatMessageBubble>), role="tool", and role="diff" (and a note/test for role="system" if behavior differs) and assert the same expectations on the slot element selected via '[data-slot="chat-message"]' (getAttribute("data-align") === "left" and className contains the expected alignment class like "justify-start" or the appropriate class for your implementation) so the public align prop is explicitly validated across roles, or alternatively adjust ChatMessageBubble type/prop docs and tests to lock align usage to user-only if intended. Ensure you reference the ChatMessageBubble component and the test file when adding these assertions.packages/ui/src/components/mono-badge.tsx-48-53 (1)
48-53:⚠️ Potential issue | 🟡 MinorPrevent overriding internal data attributes via trailing prop spread.
Placing
{...props}last allows consumers to overridedata-slot/data-tone, which can desync the component’s internal contract and selectors.Suggested fix
function MonoBadge({ tone, uppercase, className, ...props }: MonoBadgeProps) { return ( <span + {...props} data-slot="mono-badge" data-tone={tone ?? "default"} className={cn(monoBadgeVariants({ tone, uppercase }), className)} - {...props} /> ); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/mono-badge.tsx` around lines 48 - 53, The span currently spreads {...props} last which lets callers override internal data attributes; change this to filter out data-slot and data-tone from the incoming props before spreading so the component-controlled attributes win. Locate the JSX span in mono-badge.tsx and replace the trailing {...props} usage with a filtered rest (e.g., extract 'data-slot' and 'data-tone' from the incoming props into throwaway variables and spread the remaining rest), keeping data-slot="mono-badge" and data-tone={tone ?? "default"} as the explicit attributes and still using cn(monoBadgeVariants({ tone, uppercase }), className) for className.packages/ui/src/components/code-block.tsx-35-51 (1)
35-51:⚠️ Potential issue | 🟡 MinorReset copy feedback duration on repeated copy clicks.
On Line 47, clicking copy again while
copiedis alreadytruedoes not retrigger the timeout in Lines 37-41, so the success state can clear too early relative to the latest click.Proposed fix
function CodeBlock({ @@ }: CodeBlockProps) { const [copied, setCopied] = React.useState(false); + const copyResetTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null); React.useEffect(() => { - if (!copied) return; - const timer = setTimeout(() => setCopied(false), COPY_FEEDBACK_MS); - return () => clearTimeout(timer); - }, [copied]); + return () => { + if (copyResetTimerRef.current) { + clearTimeout(copyResetTimerRef.current); + } + }; + }, []); @@ const handleCopy = React.useCallback(async () => { if (typeof navigator === "undefined" || !navigator.clipboard?.writeText) return; try { await navigator.clipboard.writeText(code); setCopied(true); + if (copyResetTimerRef.current) { + clearTimeout(copyResetTimerRef.current); + } + copyResetTimerRef.current = setTimeout(() => { + setCopied(false); + copyResetTimerRef.current = null; + }, COPY_FEEDBACK_MS); } catch { // Silently ignore — some browsers block clipboard access in insecure contexts. } }, [code]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/code-block.tsx` around lines 35 - 51, The copy success timeout doesn't reset if the user clicks copy again while copied is already true, so modify handleCopy (and related logic around copied and COPY_FEEDBACK_MS) to restart the feedback timeout on every successful copy: when navigator.clipboard.writeText(code) resolves, ensure any existing timer is cleared and a new timer is started (or alternatively bump a version/timestamp state used in the useEffect dependency so the effect re-runs) so the success state persists for COPY_FEEDBACK_MS after the most recent click; keep references to the copied state, COPY_FEEDBACK_MS, the existing useEffect, and handleCopy when implementing this fix.packages/ui/src/components/avatar.test.tsx-26-35 (1)
26-35:⚠️ Potential issue | 🟡 MinorImage-slot test is asserting the wrong element.
The case says it verifies image rendering, but it checks
avatar-fallback. This can miss real regressions in image-slot rendering.✅ Suggested test fix
it("Should render the image slot when provided", () => { const { container } = render( <Avatar> <AvatarImage src="https://example.test/me.png" alt="me" /> <AvatarFallback>ME</AvatarFallback> </Avatar> ); - const fallbackSlot = container.querySelector('[data-slot="avatar-fallback"]'); - expect(fallbackSlot).not.toBeNull(); + const imageSlot = container.querySelector('[data-slot="avatar-image"]'); + expect(imageSlot).not.toBeNull(); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/avatar.test.tsx` around lines 26 - 35, The test "Should render the image slot when provided" is asserting the wrong element; update the assertion to check for the image slot instead of the fallback. In the test that renders <Avatar> with <AvatarImage src=...> and <AvatarFallback>, locate the element with the image slot (e.g., querySelector('[data-slot="avatar-image"]') or check for an <img> with src/alt) and assert it is present; optionally also assert that the fallback slot ('avatar-fallback') is not used when the image is provided. This fixes the test for Avatar/AvatarImage rendering.packages/ui/src/components/popover.test.tsx-54-65 (1)
54-65:⚠️ Potential issue | 🟡 MinorEnsure
console.erroris always restored in the throw-path test.Current mutation on Lines 55–64 can leak if the expectation fails before restoration. Wrap mutation in
try/finally.Suggested patch
it("Should throw when PopoverContent is rendered outside <Popover>", () => { const originalError = console.error; - console.error = () => {}; - expect(() => - render( - <PopoverContent> - <PopoverTitle>orphan</PopoverTitle> - </PopoverContent> - ) - ).toThrow(/Popover\.\* components must be used inside <Popover>/); - console.error = originalError; + try { + console.error = () => {}; + expect(() => + render( + <PopoverContent> + <PopoverTitle>orphan</PopoverTitle> + </PopoverContent> + ) + ).toThrow(/Popover\.\* components must be used inside <Popover>/); + } finally { + console.error = originalError; + } });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/popover.test.tsx` around lines 54 - 65, The test that silences console.error while asserting that PopoverContent (with PopoverTitle) throws when rendered outside <Popover> should ensure console.error is always restored on failure; wrap the mutation of console.error and the render/assertion in a try/finally block so originalError is restored in the finally clause, locating the change around the it(...) test that references PopoverContent, PopoverTitle and console.error.packages/ui/src/components/section.tsx-23-44 (1)
23-44:⚠️ Potential issue | 🟡 MinorHeader visibility check treats
null/falseas present content.Line 23 can render an empty header when consumers pass
label={condition && ...}(false) ornull. That creates unintended chrome (border + spacing).Suggested patch
function Section({ label, right, className, children, ...props }: SectionProps) { + const hasLabel = label !== null && label !== undefined && label !== false; + const hasRight = right !== null && right !== undefined && right !== false; return ( @@ - {label !== undefined || right !== undefined ? ( + {hasLabel || hasRight ? ( <header @@ - {label !== undefined ? ( + {hasLabel ? ( <h2 @@ - {right !== undefined ? ( + {hasRight ? ( <div data-slot="section-right" className="flex items-center gap-2"> {right} </div> ) : null}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/section.tsx` around lines 23 - 44, The header rendering currently checks `label !== undefined` and `right !== undefined`, which treats null/false as present and can render an empty header; update the visibility checks to treat null and boolean false as absent by using nullish/boolean-aware checks (e.g., test `label != null && label !== false` and `right != null && right !== false`) for the outer header condition and the inner branches; adjust the conditions around the header element, the `h2` (`section-label`) branch and the `div` (`section-right`) branch so the header (data-slot="section-head") is only rendered when there is real content for `label` or `right`.packages/ui/src/components/metric.test.tsx-35-37 (1)
35-37:⚠️ Potential issue | 🟡 MinorFix selector mismatch in the tone test block.
On Line 35,
rootqueriesmetric-valueinstead of the rootmetricslot, so the assertion is not validating what the variable name implies.✅ Suggested fix
- const root = container.querySelector<HTMLElement>('[data-slot="metric-value"]'); + const root = container.querySelector<HTMLElement>('[data-slot="metric"]');🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/metric.test.tsx` around lines 35 - 37, The test's selector is wrong: the variable root is querying '[data-slot="metric-value"]' but should select the root slot '[data-slot="metric"]'; update the query for the root variable in metric.test.tsx to use '[data-slot="metric"]' (and then use that root variable for assertions about the root element's attributes, e.g. the "data-tone" check) so the test name and assertions match the element being inspected.packages/ui/scripts/serve-storybook.ts-9-13 (1)
9-13:⚠️ Potential issue | 🟡 MinorAlso verify the bundle root is a directory.
Lines 9-13 only check existence. If
rootpoints to a file, the server starts but cannot serve expected paths.Proposed fix
-if (!existsSync(root)) { +if (!existsSync(root) || !statSync(root).isDirectory()) { console.error(`[serve-storybook] missing Storybook bundle at ${root}`); console.error(`[serve-storybook] run 'bun run build:visual' before serving`); process.exit(1); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/scripts/serve-storybook.ts` around lines 9 - 13, The current check only uses existsSync(root) which allows a file path to pass; update the validation in serve-storybook.ts to also ensure root is a directory by using fs.statSync or fs.lstatSync on root and calling isDirectory(); if the path exists but is not a directory, log a clear error (e.g., "[serve-storybook] storybook bundle root is not a directory: {root}") and call process.exit(1) — keep the existing messages but add this directory check around the same block that references existsSync(root).
🧹 Nitpick comments (13)
packages/ui/src/components/direction.test.tsx (1)
12-19: Test name does not match behavior under test.Line 12 says “default,” but Line 14 explicitly sets
direction="ltr". Rename this test (or remove the prop) to reflect intent clearly.Suggested wording fix
- it("Should default descendants to ltr when wrapped in a DirectionProvider", () => { + it("Should forward ltr to descendants", () => {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/direction.test.tsx` around lines 12 - 19, The test title claims descendants "default" to ltr but the test explicitly passes a prop; update the test to reflect its actual behavior by either removing direction="ltr" from the render call to assert the default (using <DirectionProvider><DirReader/></DirectionProvider>) or rename the it(...) description to something like "Should provide explicit ltr direction to descendants when wrapped in a DirectionProvider"; make the change in the test that references DirectionProvider and DirReader so the name and implementation match.packages/ui/src/components/dropdown-menu.test.tsx (1)
56-107: Tighten mock assertions to catch duplicate/unexpected event emissions.
toHaveBeenCalledWith(...)can still pass if callbacks fire multiple times unexpectedly. Consider asserting call counts alongside payload checks.Suggested assertion tightening
- expect(handleClick).toHaveBeenCalled(); + expect(handleClick).toHaveBeenCalledTimes(1); - expect(handleChange).toHaveBeenCalledWith(true, expect.anything()); + expect(handleChange).toHaveBeenCalledTimes(1); + expect(handleChange).toHaveBeenCalledWith(true, expect.anything()); - expect(handleChange).toHaveBeenCalledWith("warning", expect.anything()); + expect(handleChange).toHaveBeenCalledTimes(1); + expect(handleChange).toHaveBeenCalledWith("warning", expect.anything());🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/dropdown-menu.test.tsx` around lines 56 - 107, The tests currently only assert payloads which can hide duplicate emissions; for each mock callback (handleClick, the checkbox handleChange, and the radio handleChange) add a call-count assertion such as expect(mock).toHaveBeenCalledTimes(1) in addition to the existing expect(...).toHaveBeenCalledWith(...) to ensure the handler fired exactly once when interacting with DropdownMenuItem, DropdownMenuCheckboxItem, and DropdownMenuRadioItem respectively; if reusing the same variable name for multiple tests, ensure each test uses its own fresh vi.fn() so the call-count assertion is meaningful.packages/ui/src/components/kind-chip.test.tsx (1)
7-12: Test title is misleading vs asserted behavior.Line 7 says “render the kind lowercase”, but Line 11 asserts
"Greet"(original casing). Consider renaming the test to reflect that lowercase is CSS-driven (className) rather than text normalization.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/kind-chip.test.tsx` around lines 7 - 12, The test title is inaccurate: it claims "lowercase" but the assertion expects the original casing ("Greet"); update the test for KindChip to either (A) rename the it(...) description to state that the component preserves original text casing and applies mono font and accent tint tokens (e.g., "renders the kind with original casing in mono with the accent tint tokens"), or (B) if the intention is to assert lowercase text content, change the assertion to expect the lowercased string and ensure the component transforms text accordingly; locate the test referencing KindChip and the container query '[data-slot="kind-chip"]' to make the edit.packages/ui/src/components/pills.tsx (1)
131-132: Avoid redundantonChangecalls for already-active items.Even when value is unchanged, Line 131 still emits
onChange, which can trigger unnecessary parent work/side effects.Small guard to keep changes idempotent
- onClick={() => onChange(item.value)} + onClick={() => { + if (!item.disabled && item.value !== value) onChange(item.value); + }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/pills.tsx` around lines 131 - 132, The onClick handler currently always calls onChange(item.value) even when the item is already active; change it to guard so it only invokes onChange when the value would actually change. Modify the onClick in the pills component to something like: if not isActive (and onChange is defined) then call onChange(item.value), i.e. use a conditional/no-op when isActive to avoid redundant emissions while keeping the pillToggleVariants({ active: isActive, size }) logic unchanged.packages/ui/src/components/collapsible.tsx (1)
15-15: Export order alphabetized.The export order was changed to alphabetical (
CollapsibleContentbeforeCollapsibleTrigger). While this doesn't affect functionality, consider whether alphabetical ordering is the preferred convention for exports across the component library.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/collapsible.tsx` at line 15, Export order changed to alphabetical; revert or standardize exports to match the repository convention (either grouped by primary component then helpers or alphabetized). Update the export statement so the symbols appear in the agreed order (Collapsible, CollapsibleTrigger, CollapsibleContent if keeping primary-first grouping, or CollapsibleContent, CollapsibleTrigger, Collapsible if using alphabetical) and ensure other component files follow the same pattern for consistency with exports like Collapsible, CollapsibleContent, CollapsibleTrigger.packages/ui/src/components/collapsible.test.tsx (1)
45-56: StrengthenkeepMountedassertion with closed-state visibility check.Right now this test only proves DOM persistence. Add a “closed but not visible” expectation to catch regressions where content stays visually open.
Suggested test improvement
await user.click(screen.getByRole("button", { name: "Toggle" })); - expect(screen.getByText("Body")).toBeInTheDocument(); + const body = screen.getByText("Body"); + expect(body).toBeInTheDocument(); + expect(body).not.toBeVisible();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/collapsible.test.tsx` around lines 45 - 56, Update the test for Collapsible/CollapsibleContent to not only assert the content remains in the DOM when closed with keepMounted, but also assert it is not visible after toggling: render using Collapsible, CollapsibleTrigger and CollapsibleContent(keepMounted), click the trigger (the button with name "Toggle") and replace or add the final assertion to check that the element returned by screen.getByText("Body") exists but is not visible (use the appropriate matcher such as toBeVisible or its negation) so the test fails if the content remains visually open.packages/ui/src/components/dialog.tsx (1)
30-63: Consider extracting shared “overlay root + motion context” wrapper logic.The controlled/uncontrolled open handling +
actionsRef+ provider setup is very similar to the newSheet(and likelyPopover) implementation. A shared helper/hook would reduce drift and make future fixes safer.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/dialog.tsx` around lines 30 - 63, Extract the shared "overlay root + motion context" logic used in Dialog (actionsRef, controlled/uncontrolled open handling, handleOpenChange, and DialogMotionContext.Provider) into a reusable helper (either a hook like useOverlayRootMotionContext or a wrapper component like OverlayRoot) so Sheet and Popover can reuse it; move the state and handlers (actionsRef, uncontrolledOpen/setUncontrolledOpen, isControlled, open resolution, and handleOpenChange) and the memoized value into that helper and have Dialog call it and then render DialogPrimitive.Root with the returned props plus the shared provider value instead of duplicating the logic from Dialog (refer to Dialog, handleOpenChange, actionsRef, DialogMotionContext, and DialogPrimitive.Root to locate the code to extract).packages/ui/src/components/sidebar.test.tsx (2)
163-171: Tighten this test to validate an actual breakpoint transition.The current setup starts in narrow mode immediately. Consider rendering wide first, then using the mock’s
fire(...)to simulate dropping below the breakpoint and asserting the state change.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/sidebar.test.tsx` around lines 163 - 171, The test currently renders Sidebar already in narrow mode; instead, render with a wide viewport then simulate the media-query change to narrow and assert the transition: use installMatchMedia to set initial query results that represent a wide viewport, render <Sidebar nav={<span>nav</span>} collapsed={false} collapseBreakpoint={800} />, verify the sidebar (query "[data-slot=sidebar]") is initially not collapsed, then call the mock's fire(...) to simulate the viewport dropping below the breakpoint and finally assert the sidebar has data-state="collapsed" and data-narrow="true"; reference installMatchMedia, its fire(...) helper, and the Sidebar component/collapseBreakpoint prop when making these changes.
91-99: Re-querying nodes afterrerenderis a best practice but the stated concern is not applicable here.The rail and panel elements are never conditionally rendered or keyed in a way that causes remounting when the
collapsedprop changes. Both elements persist in the DOM across rerenders—only their properties (width, aria-hidden) change. References captured beforererenderremain valid.That said, re-querying after
rerenderfollows React Testing Library best practices of testing current DOM state rather than relying on captured references, which improves test resilience to implementation changes. However, this is a stylistic improvement, not a correctness issue.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/sidebar.test.tsx` around lines 91 - 99, Update the test in packages/ui/src/components/sidebar.test.tsx to re-query the DOM after calling rerender instead of reusing the earlier captured reference: after calling rerender(<Sidebar ... collapsed={true} />) call container.querySelector<HTMLElement>("[data-slot=sidebar-rail]") again and assert on that new rail reference (and do the same for the panel if applicable) so the test uses current DOM nodes for the Sidebar component checks.packages/ui/src/components/command.tsx (1)
57-62: Hide decorative search icon from assistive technologies.Line 61 renders a visual-only icon; add
aria-hiddenso it isn’t announced redundantly.Suggested patch
- <SearchIcon className="size-4 shrink-0 opacity-50" /> + <SearchIcon aria-hidden="true" className="size-4 shrink-0 opacity-50" />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/command.tsx` around lines 57 - 62, The SearchIcon rendered inside the command input group is decorative and should be hidden from screen readers; update the JSX where SearchIcon is used (the SearchIcon element next to CommandPrimitive.Input) to include aria-hidden="true" so it isn't announced redundantly by assistive technologies.packages/ui/src/components/connection-indicator.tsx (1)
35-40: Consider status semantics for live connection changes.For dynamic status updates, adding
role="status"andaria-live="polite"on the container improves screen-reader announcements.Suggested patch
<div data-slot="connection-indicator" data-status={status} + role="status" + aria-live="polite" className={cn("inline-flex items-center gap-2", className)} {...props} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/connection-indicator.tsx` around lines 35 - 40, The connection-indicator container (the div with data-slot="connection-indicator" and data-status={status} in the ConnectionIndicator component) should expose live-region semantics so screen readers announce dynamic status changes; add role="status" and aria-live="polite" attributes to that container (alongside the existing data-slot, data-status, className and spread {...props}) to enable polite announcements of status updates.packages/ui/src/components/page-header.tsx (1)
66-71: Optionally avoid rendering an empty meta container.On Line 66-Line 71,
page-header-metais rendered even whenmetais not provided. Conditionally rendering this block can keep DOM output leaner and avoid layout/debug noise.♻️ Proposed refactor
- <div - data-slot="page-header-meta" - className="ml-auto flex shrink-0 items-center gap-2 text-[13px] text-[color:var(--color-text-secondary)]" - > - {meta} - </div> + {meta ? ( + <div + data-slot="page-header-meta" + className="ml-auto flex shrink-0 items-center gap-2 text-[13px] text-[color:var(--color-text-secondary)]" + > + {meta} + </div> + ) : null}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/page-header.tsx` around lines 66 - 71, The page-header currently always renders the meta container (data-slot="page-header-meta") even when the prop/variable meta is empty; update the PageHeader component to conditionally render that div only when meta is non-empty/truthy (check the meta prop/variable) so the DOM omits the container when there's no meta content, preserving the same className and attributes when rendered.packages/ui/src/components/sonner.test.tsx (1)
9-10: Replacedocument.querySelectorwith semantic RTL queries.
screen.getByRolealigns with React Testing Library best practices by making tests more robust against implementation changes and reflecting how users (including those using assistive technology) interact with the app.Suggested refactor
-import { act, render, waitFor } from "@testing-library/react"; +import { act, render, screen, waitFor } from "@testing-library/react"; @@ - const region = document.querySelector("section[aria-label^='Notifications']"); - expect(region).not.toBeNull(); + expect( + screen.getByRole("region", { name: /notifications/i }), + ).toBeTruthy();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/sonner.test.tsx` around lines 9 - 10, The test currently uses document.querySelector to find the notifications region (the region variable); replace that with a semantic RTL query such as screen.getByRole('region', { name: /^Notifications/i }) (or getByLabelText / getByAccessibleName if you prefer) and assert with RTL matchers (e.g. toBeInTheDocument) instead of checking for not.toBeNull; update imports to use screen and the RTL matchers if needed and remove the document.querySelector usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/playwright.config.ts`:
- Around line 10-11: The current STORYBOOK_PORT initialization may produce NaN
and corrupt STORYBOOK_URL; update the logic around STORYBOOK_PORT to validate
the environment value: parse the AGH_UI_STORYBOOK_PORT (e.g., Number or
parseInt), check Number.isInteger and that the port is in a valid range
(1–65535), and if invalid throw an error or exit early so the process fails
fast; then construct STORYBOOK_URL using the validated port variable
(STORYBOOK_PORT) so the webServer config never receives an invalid URL.
- Around line 45-49: Remove the per-project override that spreads
devices["Desktop Chrome"] so the "chromium" project inherits the top-level
Playwright configuration; locate the projects array and the chromium project
object (name: "chromium") and delete the use: { ...devices["Desktop Chrome"] }
entry (or remove the use property entirely) so the project relies on the
top-level use settings (viewport, colorScheme, reducedMotion, etc.).
In `@packages/ui/scripts/serve-storybook.ts`:
- Around line 5-6: portArg is currently set with Number(...) which can produce
NaN or out-of-range values; update the logic that defines portArg (and keep
hostArg) to parse and validate the port: use parseInt on process.argv[3] ??
process.env.AGH_UI_STORYBOOK_PORT ?? "6007", check Number.isInteger and that the
value is between 1 and 65535, and if invalid either fallback to 6007 (and log a
warning) or exit with an error; ensure the validated numeric port is used
wherever portArg is referenced (e.g., server start code) so startup won't
proceed with NaN or invalid ports.
In `@packages/ui/src/components/chat-message-bubble.tsx`:
- Line 33: The component currently computes resolvedAlign (const resolvedAlign:
ChatMessageAlign = align ?? (role === "user" ? "right" : "left")) but only
applies it to data-align in some branches, so passing align="right" for non-user
roles doesn't change the layout; update all className compositions that control
layout (the branches rendering the message container, avatar/message order, and
bubble alignment) to use resolvedAlign rather than role-based logic so layout
classes (e.g., flex direction, margin-start/margin-end, text alignment) reflect
resolvedAlign consistently while still setting data-align for styling hooks;
search for usages around the message container render (where data-align is
currently set) and replace the role-derived class decisions with checks against
resolvedAlign so agent/tool/diff messages honor align prop.
In `@packages/ui/src/components/dialog.test.tsx`:
- Around line 77-87: The test temporarily replaces console.error before calling
render on <DialogContent> with <DialogTitle> to assert it throws; wrap the
console.error assignment and the expect(...) render call in a try/finally so
console.error is restored no matter what. Specifically, when you mock
console.error (originalError = console.error; console.error = () => {}), run the
expect(() => render(...)) inside the try block and restore console.error =
originalError in the finally block to avoid leaking the mock to other tests;
keep the same render, DialogContent, DialogTitle, and expect usage.
In `@packages/ui/src/components/pills.tsx`:
- Around line 111-133: The component currently mixes tab and toggle semantics;
update the control to use proper toggle-group semantics: remove role="tablist"
from the container and role="tab" and aria-selected from each button (in the JSX
around the div with data-slot="pills" and the button rendering for items), keep
aria-pressed={isActive} on the button and ensure buttons remain native <button>
elements so default keyboard activation (Enter/Space) works; leave disabled
handling and onClick/onChange (items, value, onChange, pillToggleVariants) as-is
and remove any tab-specific attributes (role="tablist", role="tab",
aria-selected, and any planned roving/tabIndex or arrow handlers) to resolve the
mixed semantics.
In `@packages/ui/src/components/search-input.test.tsx`:
- Around line 8-18: The test for SearchInput incorrectly asserts the second
onChange call receives "b" instead of the accumulated value "ab"; update the
assertions in search-input.test.tsx to expect handle toHaveBeenNthCalledWith(2,
"ab") and ensure the test reflects the component's next-string semantics (either
stop pinning value="" or make the test render a controlled wrapper that updates
value on each onChange so the emitted values are accumulated). Target symbols:
SearchInput component, the test's handle mock, and the user.type call.
In `@packages/ui/src/components/search-input.tsx`:
- Around line 23-53: The input is being forced into controlled mode by always
passing value={value ?? ""} in the SearchInput component; change the input so it
only receives a value prop when the parent actually provides one (i.e. treat
undefined as uncontrolled). Concretely, in SearchInput update the <input> props
to conditionally pass value only when value !== undefined (and otherwise leave
it uncontrolled or use defaultValue if you want an initial value), e.g. replace
value={value ?? ""} with logic that spreads value only when defined (or uses
defaultValue from props), keeping onChange/disabled as-is.
In `@packages/ui/src/components/sheet.test.tsx`:
- Around line 67-77: The test temporarily overrides console.error (originalError
= console.error; console.error = () => {}) before asserting render of orphan
components like SheetContent/SheetTitle; if the expect().toThrow assertion fails
the override isn’t restored. Wrap the render+expect block in a try/finally so
console.error is always reset to originalError in the finally clause; apply the
same try/finally pattern to the other similar tests (tooltip, popover, dialog)
that set console.error, ensuring you reference the same originalError variable
and restore it in finally.
In `@packages/ui/src/components/sidebar.tsx`:
- Around line 110-118: The collapsed sidebar still permits keyboard focus even
with aria-hidden; update the motion.div (the sidebar panel) to also opt-out of
user interaction when effectivelyCollapsed is true by adding the inert attribute
(inert={effectivelyCollapsed}) alongside aria-hidden and by programmatically
moving focus off the panel when collapsing (e.g., focus a safe control) to
prevent trapped/hidden focus; target the motion.div element and any
focus-management code around effectivelyCollapsed/panelWidth to implement these
changes.
In `@packages/ui/src/components/sonner.test.tsx`:
- Around line 13-31: Add explicit cleanup between tests by registering an
afterEach hook that calls the sonner toast singleton's dismiss method and RTL's
cleanup to remove lingering toasts and DOM: add an afterEach that invokes
toast.dismiss() and cleanup() so tests that render <Toaster /> (and use
toast.success / toast.error) cannot leak toasts into subsequent tests; target
the toast symbol and the Toaster/render tests in this file when applying the
change.
In `@packages/ui/src/components/split-pane.tsx`:
- Around line 82-95: The Back button in the split pane is rendered when narrow
&& hasDetail even if onDetailClose is undefined, which can leave users stranded;
update the render/behavior so the button is only shown or active when a working
close path exists by either (A) gating the button render on onDetailClose (e.g.,
render split-pane-back only if onDetailClose is provided) or (B) implement an
internal fallback close handler in the SplitPane component (use component state
to hide the detail and call that internal handler when onDetailClose is absent),
and ensure the button's onClick uses onDetailClose ?? fallbackClose and has
appropriate aria-disabled/disabled state when no handler exists; reference
symbols: narrow, hasDetail, onDetailClose, backLabel,
data-slot="split-pane-back".
---
Minor comments:
In `@packages/ui/scripts/serve-storybook.ts`:
- Around line 9-13: The current check only uses existsSync(root) which allows a
file path to pass; update the validation in serve-storybook.ts to also ensure
root is a directory by using fs.statSync or fs.lstatSync on root and calling
isDirectory(); if the path exists but is not a directory, log a clear error
(e.g., "[serve-storybook] storybook bundle root is not a directory: {root}") and
call process.exit(1) — keep the existing messages but add this directory check
around the same block that references existsSync(root).
In `@packages/ui/src/components/alert.test.tsx`:
- Around line 7-18: The test named "renders role=alert by default and forwards
class + data-variant" currently does not exercise class forwarding; update the
test for the Alert component by passing a className (e.g., className="foo") into
the rendered <Alert ...> and add an assertion that the rendered element (queried
via getByTestId("alert")) includes that class (e.g., toHaveClass("foo");
alternatively, if you prefer to keep the current assertions, rename the test to
remove "forwards class" from the title so it accurately reflects that it only
verifies role, data-variant, and data-slot for Alert with AlertTitle and
AlertDescription).
In `@packages/ui/src/components/avatar.test.tsx`:
- Around line 26-35: The test "Should render the image slot when provided" is
asserting the wrong element; update the assertion to check for the image slot
instead of the fallback. In the test that renders <Avatar> with <AvatarImage
src=...> and <AvatarFallback>, locate the element with the image slot (e.g.,
querySelector('[data-slot="avatar-image"]') or check for an <img> with src/alt)
and assert it is present; optionally also assert that the fallback slot
('avatar-fallback') is not used when the image is provided. This fixes the test
for Avatar/AvatarImage rendering.
In `@packages/ui/src/components/chat-message-bubble.test.tsx`:
- Around line 130-139: The test only checks ChatMessageBubble align override for
role="user"; add additional test cases in chat-message-bubble.test.tsx that call
render(<ChatMessageBubble role="agent" align="left">...</ChatMessageBubble>),
role="tool", and role="diff" (and a note/test for role="system" if behavior
differs) and assert the same expectations on the slot element selected via
'[data-slot="chat-message"]' (getAttribute("data-align") === "left" and
className contains the expected alignment class like "justify-start" or the
appropriate class for your implementation) so the public align prop is
explicitly validated across roles, or alternatively adjust ChatMessageBubble
type/prop docs and tests to lock align usage to user-only if intended. Ensure
you reference the ChatMessageBubble component and the test file when adding
these assertions.
In `@packages/ui/src/components/code-block.tsx`:
- Around line 35-51: The copy success timeout doesn't reset if the user clicks
copy again while copied is already true, so modify handleCopy (and related logic
around copied and COPY_FEEDBACK_MS) to restart the feedback timeout on every
successful copy: when navigator.clipboard.writeText(code) resolves, ensure any
existing timer is cleared and a new timer is started (or alternatively bump a
version/timestamp state used in the useEffect dependency so the effect re-runs)
so the success state persists for COPY_FEEDBACK_MS after the most recent click;
keep references to the copied state, COPY_FEEDBACK_MS, the existing useEffect,
and handleCopy when implementing this fix.
In `@packages/ui/src/components/kind-chip.tsx`:
- Around line 17-27: The span in kind-chip.tsx exposes internal markers
data-slot and data-kind to be overridden because {...props} is spread last;
change the spread order or filter props so internal attributes win: either
spread {...props} before the explicit attributes (data-slot="kind-chip",
data-kind={kind}, className={cn(...)}), or destructure and remove
data-slot/data-kind from incoming props (e.g., const { "data-slot": _,
"data-kind": __, ...rest } = props) and then spread rest; update the span to use
the chosen approach so data-slot and data-kind (and the className computed by
cn) cannot be overwritten by callers.
In `@packages/ui/src/components/metric.test.tsx`:
- Around line 35-37: The test's selector is wrong: the variable root is querying
'[data-slot="metric-value"]' but should select the root slot
'[data-slot="metric"]'; update the query for the root variable in
metric.test.tsx to use '[data-slot="metric"]' (and then use that root variable
for assertions about the root element's attributes, e.g. the "data-tone" check)
so the test name and assertions match the element being inspected.
In `@packages/ui/src/components/mono-badge.tsx`:
- Around line 48-53: The span currently spreads {...props} last which lets
callers override internal data attributes; change this to filter out data-slot
and data-tone from the incoming props before spreading so the
component-controlled attributes win. Locate the JSX span in mono-badge.tsx and
replace the trailing {...props} usage with a filtered rest (e.g., extract
'data-slot' and 'data-tone' from the incoming props into throwaway variables and
spread the remaining rest), keeping data-slot="mono-badge" and data-tone={tone
?? "default"} as the explicit attributes and still using cn(monoBadgeVariants({
tone, uppercase }), className) for className.
In `@packages/ui/src/components/popover.test.tsx`:
- Around line 54-65: The test that silences console.error while asserting that
PopoverContent (with PopoverTitle) throws when rendered outside <Popover> should
ensure console.error is always restored on failure; wrap the mutation of
console.error and the render/assertion in a try/finally block so originalError
is restored in the finally clause, locating the change around the it(...) test
that references PopoverContent, PopoverTitle and console.error.
In `@packages/ui/src/components/section.tsx`:
- Around line 23-44: The header rendering currently checks `label !== undefined`
and `right !== undefined`, which treats null/false as present and can render an
empty header; update the visibility checks to treat null and boolean false as
absent by using nullish/boolean-aware checks (e.g., test `label != null && label
!== false` and `right != null && right !== false`) for the outer header
condition and the inner branches; adjust the conditions around the header
element, the `h2` (`section-label`) branch and the `div` (`section-right`)
branch so the header (data-slot="section-head") is only rendered when there is
real content for `label` or `right`.
---
Nitpick comments:
In `@packages/ui/src/components/collapsible.test.tsx`:
- Around line 45-56: Update the test for Collapsible/CollapsibleContent to not
only assert the content remains in the DOM when closed with keepMounted, but
also assert it is not visible after toggling: render using Collapsible,
CollapsibleTrigger and CollapsibleContent(keepMounted), click the trigger (the
button with name "Toggle") and replace or add the final assertion to check that
the element returned by screen.getByText("Body") exists but is not visible (use
the appropriate matcher such as toBeVisible or its negation) so the test fails
if the content remains visually open.
In `@packages/ui/src/components/collapsible.tsx`:
- Line 15: Export order changed to alphabetical; revert or standardize exports
to match the repository convention (either grouped by primary component then
helpers or alphabetized). Update the export statement so the symbols appear in
the agreed order (Collapsible, CollapsibleTrigger, CollapsibleContent if keeping
primary-first grouping, or CollapsibleContent, CollapsibleTrigger, Collapsible
if using alphabetical) and ensure other component files follow the same pattern
for consistency with exports like Collapsible, CollapsibleContent,
CollapsibleTrigger.
In `@packages/ui/src/components/command.tsx`:
- Around line 57-62: The SearchIcon rendered inside the command input group is
decorative and should be hidden from screen readers; update the JSX where
SearchIcon is used (the SearchIcon element next to CommandPrimitive.Input) to
include aria-hidden="true" so it isn't announced redundantly by assistive
technologies.
In `@packages/ui/src/components/connection-indicator.tsx`:
- Around line 35-40: The connection-indicator container (the div with
data-slot="connection-indicator" and data-status={status} in the
ConnectionIndicator component) should expose live-region semantics so screen
readers announce dynamic status changes; add role="status" and
aria-live="polite" attributes to that container (alongside the existing
data-slot, data-status, className and spread {...props}) to enable polite
announcements of status updates.
In `@packages/ui/src/components/dialog.tsx`:
- Around line 30-63: Extract the shared "overlay root + motion context" logic
used in Dialog (actionsRef, controlled/uncontrolled open handling,
handleOpenChange, and DialogMotionContext.Provider) into a reusable helper
(either a hook like useOverlayRootMotionContext or a wrapper component like
OverlayRoot) so Sheet and Popover can reuse it; move the state and handlers
(actionsRef, uncontrolledOpen/setUncontrolledOpen, isControlled, open
resolution, and handleOpenChange) and the memoized value into that helper and
have Dialog call it and then render DialogPrimitive.Root with the returned props
plus the shared provider value instead of duplicating the logic from Dialog
(refer to Dialog, handleOpenChange, actionsRef, DialogMotionContext, and
DialogPrimitive.Root to locate the code to extract).
In `@packages/ui/src/components/direction.test.tsx`:
- Around line 12-19: The test title claims descendants "default" to ltr but the
test explicitly passes a prop; update the test to reflect its actual behavior by
either removing direction="ltr" from the render call to assert the default
(using <DirectionProvider><DirReader/></DirectionProvider>) or rename the
it(...) description to something like "Should provide explicit ltr direction to
descendants when wrapped in a DirectionProvider"; make the change in the test
that references DirectionProvider and DirReader so the name and implementation
match.
In `@packages/ui/src/components/dropdown-menu.test.tsx`:
- Around line 56-107: The tests currently only assert payloads which can hide
duplicate emissions; for each mock callback (handleClick, the checkbox
handleChange, and the radio handleChange) add a call-count assertion such as
expect(mock).toHaveBeenCalledTimes(1) in addition to the existing
expect(...).toHaveBeenCalledWith(...) to ensure the handler fired exactly once
when interacting with DropdownMenuItem, DropdownMenuCheckboxItem, and
DropdownMenuRadioItem respectively; if reusing the same variable name for
multiple tests, ensure each test uses its own fresh vi.fn() so the call-count
assertion is meaningful.
In `@packages/ui/src/components/kind-chip.test.tsx`:
- Around line 7-12: The test title is inaccurate: it claims "lowercase" but the
assertion expects the original casing ("Greet"); update the test for KindChip to
either (A) rename the it(...) description to state that the component preserves
original text casing and applies mono font and accent tint tokens (e.g.,
"renders the kind with original casing in mono with the accent tint tokens"), or
(B) if the intention is to assert lowercase text content, change the assertion
to expect the lowercased string and ensure the component transforms text
accordingly; locate the test referencing KindChip and the container query
'[data-slot="kind-chip"]' to make the edit.
In `@packages/ui/src/components/page-header.tsx`:
- Around line 66-71: The page-header currently always renders the meta container
(data-slot="page-header-meta") even when the prop/variable meta is empty; update
the PageHeader component to conditionally render that div only when meta is
non-empty/truthy (check the meta prop/variable) so the DOM omits the container
when there's no meta content, preserving the same className and attributes when
rendered.
In `@packages/ui/src/components/pills.tsx`:
- Around line 131-132: The onClick handler currently always calls
onChange(item.value) even when the item is already active; change it to guard so
it only invokes onChange when the value would actually change. Modify the
onClick in the pills component to something like: if not isActive (and onChange
is defined) then call onChange(item.value), i.e. use a conditional/no-op when
isActive to avoid redundant emissions while keeping the pillToggleVariants({
active: isActive, size }) logic unchanged.
In `@packages/ui/src/components/sidebar.test.tsx`:
- Around line 163-171: The test currently renders Sidebar already in narrow
mode; instead, render with a wide viewport then simulate the media-query change
to narrow and assert the transition: use installMatchMedia to set initial query
results that represent a wide viewport, render <Sidebar nav={<span>nav</span>}
collapsed={false} collapseBreakpoint={800} />, verify the sidebar (query
"[data-slot=sidebar]") is initially not collapsed, then call the mock's
fire(...) to simulate the viewport dropping below the breakpoint and finally
assert the sidebar has data-state="collapsed" and data-narrow="true"; reference
installMatchMedia, its fire(...) helper, and the Sidebar
component/collapseBreakpoint prop when making these changes.
- Around line 91-99: Update the test in
packages/ui/src/components/sidebar.test.tsx to re-query the DOM after calling
rerender instead of reusing the earlier captured reference: after calling
rerender(<Sidebar ... collapsed={true} />) call
container.querySelector<HTMLElement>("[data-slot=sidebar-rail]") again and
assert on that new rail reference (and do the same for the panel if applicable)
so the test uses current DOM nodes for the Sidebar component checks.
In `@packages/ui/src/components/sonner.test.tsx`:
- Around line 9-10: The test currently uses document.querySelector to find the
notifications region (the region variable); replace that with a semantic RTL
query such as screen.getByRole('region', { name: /^Notifications/i }) (or
getByLabelText / getByAccessibleName if you prefer) and assert with RTL matchers
(e.g. toBeInTheDocument) instead of checking for not.toBeNull; update imports to
use screen and the RTL matchers if needed and remove the document.querySelector
usage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
packages/ui/src/components/dialog.test.tsx (1)
93-104:⚠️ Potential issue | 🟠 MajorEnsure
console.erroris always restored.Line 95 and Line 103 restore logic is not exception-safe. If the assertion path fails early, the mock leaks into other tests.
🛠️ Suggested fix
it("Should throw when DialogContent is rendered outside <Dialog>", () => { const originalError = console.error; - console.error = () => {}; - expect(() => - render( - <DialogContent> - <DialogTitle>orphan</DialogTitle> - </DialogContent> - ) - ).toThrow(/Dialog\.\* components must be used inside <Dialog>/); - console.error = originalError; + try { + console.error = () => {}; + expect(() => + render( + <DialogContent> + <DialogTitle>orphan</DialogTitle> + </DialogContent> + ) + ).toThrow(/Dialog\.\* components must be used inside <Dialog>/); + } finally { + console.error = originalError; + } });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/dialog.test.tsx` around lines 93 - 104, The test "Should throw when DialogContent is rendered outside <Dialog>" currently overrides console.error by assigning to a local originalError and resetting it after the expect, which is not exception-safe; wrap the override and test assertion in a try/finally so console.error is restored in finally (use originalError in finally) to guarantee restoration even if render or expect throws; update the test that references console.error and the render of <DialogContent> / <DialogTitle> accordingly.
🧹 Nitpick comments (2)
packages/ui/src/components/dialog.tsx (1)
175-177: UseDialogClosewrapper here for slot consistency.This path currently uses
DialogPrimitive.Closedirectly, which skips your local wrapper conventions (data-slot="dialog-close"). Prefer reusingDialogClosefor consistent markup and selectors.♻️ Suggested refactor
- {showCloseButton ? ( - <DialogPrimitive.Close render={<Button variant="outline" />}>Close</DialogPrimitive.Close> - ) : null} + {showCloseButton ? ( + <DialogClose render={<Button variant="outline" />}>Close</DialogClose> + ) : null}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/dialog.tsx` around lines 175 - 177, The close button currently uses DialogPrimitive.Close directly which bypasses our local wrapper conventions; replace the direct usage of DialogPrimitive.Close with the local DialogClose wrapper so the element includes the expected data-slot and wrapper behavior — locate the JSX branch checking showCloseButton and swap DialogPrimitive.Close to DialogClose while keeping the inner Button (variant="outline") and text "Close" unchanged to preserve functionality and styling.packages/ui/src/components/pills.tsx (1)
127-129: Add a defensive disabled guard in the click handler.Right now
Line 129relies on native disabled-button behavior to suppressonChange. Adding an explicit guard makes intent resilient to future refactors.♻️ Suggested hardening
- onClick={() => onChange(item.value)} + onClick={() => { + if (item.disabled) return; + onChange(item.value); + }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/components/pills.tsx` around lines 127 - 129, The click handler for the pill relies on native disabled behavior and should defensively guard against calling onChange when the item is disabled; update the onClick arrow handler in the pills component so it first checks item.disabled (and optionally that onChange is defined) and returns early if disabled, otherwise calls onChange(item.value) — locate the onClick prop on the element that currently reads onClick={() => onChange(item.value)} and add the guard there.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/components/combobox.tsx`:
- Around line 110-118: The Button is receiving a non-existent render prop; move
the render prop to the ComboboxTrigger so the primitive trigger composes the
Button. Remove render from the Button instance and instead call ComboboxTrigger
(or ComboboxPrimitive.Trigger) with render set to a Button element configured
with type="button", variant="ghost", size="icon-xs", disabled={disabled},
data-slot="combobox-input-trigger" and the className currently attached; keep
any group/data attributes and ensure ComboboxTrigger receives any disabled or
aria props as needed so the Button returned by render reflects the correct
state.
In `@packages/ui/src/components/empty.test.tsx`:
- Around line 41-42: The test can produce false-positive results because it
asserts expect(iconSlot?.querySelector("svg")).not.toBeNull() when iconSlot may
be null; change the test so you first assert iconSlot is present (e.g.,
expect(iconSlot).not.toBeNull()) and only then query for the SVG (using
iconSlot.querySelector("svg")), or else change the expectation to check for
truthiness of iconSlot before asserting about the SVG; update the assertions
around the iconSlot variable in empty.test.tsx (the iconSlot lookup and
subsequent SVG assertion) to ensure the slot existence is validated prior to
inspecting its children.
---
Duplicate comments:
In `@packages/ui/src/components/dialog.test.tsx`:
- Around line 93-104: The test "Should throw when DialogContent is rendered
outside <Dialog>" currently overrides console.error by assigning to a local
originalError and resetting it after the expect, which is not exception-safe;
wrap the override and test assertion in a try/finally so console.error is
restored in finally (use originalError in finally) to guarantee restoration even
if render or expect throws; update the test that references console.error and
the render of <DialogContent> / <DialogTitle> accordingly.
---
Nitpick comments:
In `@packages/ui/src/components/dialog.tsx`:
- Around line 175-177: The close button currently uses DialogPrimitive.Close
directly which bypasses our local wrapper conventions; replace the direct usage
of DialogPrimitive.Close with the local DialogClose wrapper so the element
includes the expected data-slot and wrapper behavior — locate the JSX branch
checking showCloseButton and swap DialogPrimitive.Close to DialogClose while
keeping the inner Button (variant="outline") and text "Close" unchanged to
preserve functionality and styling.
In `@packages/ui/src/components/pills.tsx`:
- Around line 127-129: The click handler for the pill relies on native disabled
behavior and should defensively guard against calling onChange when the item is
disabled; update the onClick arrow handler in the pills component so it first
checks item.disabled (and optionally that onChange is defined) and returns early
if disabled, otherwise calls onChange(item.value) — locate the onClick prop on
the element that currently reads onClick={() => onChange(item.value)} and add
the guard there.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: dc5ae410-4ca6-4c64-a6c1-0f9841519df2
📒 Files selected for processing (37)
extensions/bridges/gchat/provider_test.gointernal/api/httpapi/handlers_test.gointernal/api/udsapi/handlers_test.gointernal/automation/manager_test.gointernal/bridgesdk/webhook_test.gointernal/cli/doc_test.gointernal/cli/skill_test.gointernal/daemon/bridges_test.gointernal/daemon/daemon_test.gointernal/daemon/task_runtime_test.gointernal/extension/host_api_test.gointernal/extension/manager_test.gointernal/memory/store_test.gointernal/subprocess/handshake_test.gointernal/subprocess/perf_bench_test.gointernal/subprocess/transport.gointernal/transcript/transcript_bench_test.gointernal/transcript/transcript_test.gopackages/ui/src/components/combobox.test.tsxpackages/ui/src/components/combobox.tsxpackages/ui/src/components/dialog.test.tsxpackages/ui/src/components/dialog.tsxpackages/ui/src/components/empty.test.tsxpackages/ui/src/components/empty.tsxpackages/ui/src/components/input.tsxpackages/ui/src/components/native-select.test.tsxpackages/ui/src/components/native-select.tsxpackages/ui/src/components/pills.test.tsxpackages/ui/src/components/pills.tsxpackages/ui/src/components/popover.test.tsxpackages/ui/src/components/popover.tsxpackages/ui/src/components/select.test.tsxpackages/ui/src/components/select.tsxpackages/ui/src/components/sheet.test.tsxpackages/ui/src/components/sheet.tsxpackages/ui/src/components/sidebar.test.tsxpackages/ui/src/components/sidebar.tsx
✅ Files skipped from review due to trivial changes (11)
- internal/cli/doc_test.go
- internal/bridgesdk/webhook_test.go
- internal/transcript/transcript_bench_test.go
- internal/daemon/bridges_test.go
- internal/subprocess/handshake_test.go
- internal/api/httpapi/handlers_test.go
- internal/transcript/transcript_test.go
- internal/daemon/daemon_test.go
- packages/ui/src/components/popover.test.tsx
- internal/extension/host_api_test.go
- packages/ui/src/components/sheet.test.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
- packages/ui/src/components/select.tsx
- internal/daemon/task_runtime_test.go
- packages/ui/src/components/combobox.test.tsx
- packages/ui/src/components/select.test.tsx
- packages/ui/src/components/sidebar.tsx
- packages/ui/src/components/empty.tsx
- packages/ui/src/components/sheet.tsx
- packages/ui/src/components/native-select.tsx
- packages/ui/src/components/sidebar.test.tsx
- Add --font-display and --font-wordmark to packages/ui/src/tokens.css (radii, motion, easing, accent-tint-strong tokens already present). - Install motion@12 as peer dep in @agh/ui and runtime dep in web. - Export UIProvider from @agh/ui — MotionConfig wrapper with reducedMotion='user' default and 150ms ease-out transition. - Add Vitest harness for packages/ui (vitest.config.ts + test-setup.ts) and wire it into the root vitest projects list. - Add UIProvider unit tests (user/always/never) and Storybook story with play-function interaction tests covering reducedMotion override. - Update web/src/styles.test.ts to assert the new token presence rather than their absence. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Relocate four Base UI primitives from web/src/components/ui into packages/ui/src/components, export them from @agh/ui, and rewire every web/src importer. Motion is wired via Base UI's actionsRef.unmount pattern combined with AnimatePresence + motion.div render props so enter/exit animations flow through MotionConfig (reducedMotion="user"). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…(task_03) Relocate the selection-family shadcn primitives from web/src/components/ui/ into packages/ui/src/components/, with colocated Vitest specs and stories. Every @/components/ui/(combobox|command|select|scroll-area|tabs) importer is rewritten; the originals are deleted in the same commit (ADR-002 greenfield). - Combobox inlines a minimal InputGroup shell (to avoid depending on web/src/components/ui/input-group, which moves in task_08) and uses a raw <input> for the control since Base UI's Input is Field.Control and intercepts combobox state. - Command inlines a small search-input chrome and imports Dialog from its sibling module. cmdk is added to packages/ui dependencies. - Select + Combobox keep their existing CSS open/close animations; motion conversion is deferred (SelectPortal has no keepMounted). - Tabs now forwards orientation to Base UI's TabsRoot so vertical layouts get the correct aria-orientation, fixing a latent pass-through bug. - packages/ui/src/test-setup.ts mocks Element.prototype.scrollIntoView for cmdk under jsdom. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…llapsible to @agh/ui (task_04) Consolidates the last batch of state-carrying shadcn primitives into packages/ui/src/components/ with colocated Vitest suites and Storybook stories, deletes the originals from web/src/components/ui/, and rewrites every importer (app-sidebar, six settings routes, bridge dialogs, agent sidebar group, session thinking-block, and five test mocks) to consume @agh/ui. CSS-based animations kept — Base UI's data-state transitions stay on tw-animate-css, matching the task_03 precedent. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…ask_05) Introduces two content-agnostic structural primitives in @agh/ui: Sidebar (rail + header + nav + footer slots with motion-driven width collapse, reduced-motion aware, auto-collapse on narrow viewports) and SplitPane (fixed-width list + flex detail with empty state and responsive back-navigation stack). Deletes the shadcn-derived web/src/components/ui/sidebar.tsx + sidebar hooks and rewrites the four local importers to compose @agh/ui directly or use plain tailwind markup, keeping DESIGN.md §4/§11 behavior intact. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…k_06)
Introduces the mock's page-level primitives in @agh/ui and rewrites every
call site under web/src/** that depended on
design-system/{pill,pill-button,page-content,panel,section-heading,toolbar,texture-canvas}
or ui/empty. Migrated files and their stories are deleted;
design-system-showcase is trimmed to consume only the new @agh/ui surface
plus the legacy metric/status files that task 07 will handle.
Pill and Pills share one semantic variant table
(default/accent/success/warning/danger/info) and map the legacy tone
strings via web/src/lib/pill-variant.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
… (task_07) Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…ui (task_08) Relocate Avatar, Breadcrumb, ButtonGroup, Field, InputGroup, Item, NativeSelect, Textarea, Sonner (decoupled from next-themes), DirectionProvider into @agh/ui. Rewrite every importer, delete web/src/components/ui/ entirely.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
State-free presentational shells per DESIGN.md §4 "Chat Components" and "Tool Call Card". `ChatMessageBubble` role drives layout (user right bubble, agent left flat, system hairline divider, tool/diff pass-through); `ToolCallCard` renders terminal icon + tool name + file path with a status-tinted MonoBadge (running → accent, done → success, error → danger). Stories + unit tests cover all 5 roles and 3 statuses. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Scaffolds a chromium-based visual-regression gate over every Storybook story in packages/ui: static Storybook build served by a Bun http script, story-index-driven spec with per-platform baselines, 0.1% pixel-diff threshold, prefers-reduced-motion forced at the browser context, and a ui-visual CI job pinned to ubuntu-22.04. Commits 168 darwin baselines; first CI run will bootstrap the linux set. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Introduce packages/ui/README.md as the canonical @agh/ui contributor guide: inventory grouped into foundations, structural, form, feedback, and chat; UIProvider wiring; motion vs CSS decision rules; Playwright snapshot workflow; anti-patterns; and ADR cross-links. Add a Vitest readme suite that acts as the automated gate — link-check for relative paths, inventory parity against src/index.ts, line budget, and a heading snapshot. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Replace the hand-rolled web/src/components/app-sidebar.tsx with a thin composition over @agh/ui Sidebar using its rail/header/nav/footer slots. Domain content (workspace rail, agent tree, nav rows, session list) stays in web/, but all chrome now flows through the shared primitive — including the built-in collapse trigger and aria contract. - Switch AppSidebar props to collapsed + onCollapseChange(next) to match Sidebar.onCollapse; useAppLayout exposes setCollapsed from the store. - Adopt ConnectionIndicator + StatusDot for the footer + session dots. - Render the agh wordmark + ALPHA chip in the header slot (DESIGN.md §4). - Rewrite the unit test suite against real @agh/ui primitives under UIProvider reducedMotion="always", with only @tanstack/react-router mocked. - Add Storybook stories: Default / Collapsed / NoWorkspaces / ManyWorkspaces / Disconnected / Reconnecting + TogglesCollapse + SwitchesWorkspace interaction stories. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Mount `<UIProvider reducedMotion="user">` at `web/src/main.tsx`, introduce the DESIGN.md §4 sticky blurred `AppHeader` rendered from `__root.tsx`, and drive a 200ms opacity fade between authenticated routes via `AnimatePresence mode="wait"` keyed on `useLocation().pathname` (collapses to 0ms under `prefers-reduced-motion: reduce`). Dark-only app drops `ThemeProvider` + `next-themes`, and the sidebar no longer carries the wordmark — the global app-shell header owns that lockup. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- flatten showcase to web/src/components/design-system-showcase.tsx as a pure @agh/ui + lucide-react + react consumer - enumerate every AGH-owned tokens.css custom property as a swatch card; link each primitive section to its DESIGN.md anchor on GitHub - delete web/src/components/design-system/ entirely - repoint the /design-system route import Phase 2 consolidation is done: no local primitive library remains outside @agh/ui. 18 RTL tests assert section coverage, swatch parity, DESIGN.md anchor contract, import-source contract, and route wiring.
Extend the packages/ui Playwright harness pattern to the web/ app so Phase 3–6 domain rewrites land with pixel-level regression coverage. Each domain task now commits baseline diffs alongside its component rewrite, with the same per-platform baseline + CI gate pattern established in task 11. - Share the story-index helper via @agh/ui/testing/visual subpath export (moved to packages/ui/src/testing/visual-story-index.ts), so the web spec reuses the enumeration and threshold contract without duplication. - Add web/playwright.visual.config.ts + web/scripts/serve-storybook.ts (port 6008 — distinct from 6007 used by @agh/ui) and the bun scripts build:visual / test:visual / test:visual:update / test:visual:install. - Snapshot the page viewport (not #storybook-root) because web stories that render an open Base UI Dialog mark the root as aria-hidden + inert AND portal the dialog body outside the root. Capturing the viewport covers portals and dodges the visibility wait. - Commit 171 darwin baselines under web/tests/visual/__snapshots__/ — every *.stories.tsx under web/src/** minus play-fn-tagged stories. Add a story for the /design-system route so its showcase is included. - Vitest coverage for the config invariants (9 cases) and the new route + story enumeration helper (11 cases). - New CI job web-visual on ubuntu-22.04 gated on web/** or packages/ui/** changes. First CI run needs --update-snapshots to seed linux baselines (same workflow_dispatch pattern as ui-visual). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Phase 3, step 1 of the web redesign. Rewrites the Tasks list + detail surfaces against the @agh/ui primitive library (SplitPane, PageHeader, SearchInput, Pills, Empty, Section, Metric, StatusDot, MonoBadge, CodeBlock, Table, Tabs) and introduces the shared TasksListRow primitive that Kanban/Inbox (task 18) will consume. Domain logic (hooks, adapters, stores) is untouched — only the presentational layer changed. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…ask_18) - Collapse Kanban to 4 columns (Pending/Running/Done/Failed); accept mock status aliases - Rewrite Dashboard cards to Active runs / Success rate / Average duration / Queue depth - Rewrite Dashboard Queue Health with bar histogram + Empty fallback - Rewrite Dashboard Status breakdown on Section + per-status Pill w/ counts - Rewrite Dashboard Active runs on Section + StatusDot/MonoBadge/Pill composition - Rewrite Inbox lane tabs on @agh/ui Tabs; inbox toolbar on SearchInput + Switch - Rewrite Inbox items on shared TasksListRow with data-variant-tagged action buttons - Convert TasksListRow outer <button> to <div role="button"> to host nested actions - Add Storybook stories + Playwright visual baselines for all three views Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Closes the Phase 3 Tasks-domain rewrite. TasksCreateModal, TaskEditorSurface, TaskRunDetailHeader, TaskRunDetailPanels (Identity / Progress / Activity) and TaskRunDetailSessionLink now consume the shared @agh/ui primitives (Dialog, Field, Input, Textarea, NativeSelect, Pills, PageHeader, Section, Metric, CodeBlock, MonoBadge, StatusDot, Table) while preserving every form hook, validation rule, route loader, and data-testid contract. Adds 3 Storybook stories and 15 darwin Playwright baselines covering empty / populated / pending / error / validation-error states. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- message-bubble.tsx composes ChatMessageBubble for all 5 roles (user, agent, system, diff); agent meta uses StatusDot (8px success / accent+pulse while streaming) + mono agent name per DESIGN.md §4. - tool-call-card.tsx composes @agh/ui ToolCallCard primitive wrapped in a click-to-expand button; per-tool icon + status tone via MonoBadge. - chat-view.tsx swaps empty state to @agh/ui Empty; preserves virtualizer, auto-scroll lock, and the scroll-to-bottom button. - chat-header.tsx uses StatusDot + MonoBadge; processing-indicator.tsx uses StatusDot dots with staggered pulse. - tool-group-section.tsx modernized with token-based surfaces and @agh/ui Button for overflow toggle. - Widens @agh/ui ToolCallCard primitive: accepts optional `icon` prop (LucideIcon or ReactNode), ReactNode for toolName/filePath, and applies a danger-toned border on status=error. - Extends UIMessage with `diff` role + optional `diff` shape for native diff rendering via CodeBlock (pipeline-emit follow-up). - 11 new Playwright baselines (5 roles, tool statuses, streaming, diff, five-role thread, chat-header states); 2 stale baselines removed. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Ship the 320px right-hand Session inspector composing @agh/ui Section / Metric / MonoBadge / StatusDot / Tabs / ScrollArea / Empty / Sheet. Stacks four sections (Trace, Usage, Memory, Files) at tall viewports and swaps to a Tabs layout under @media (max-height: 680px) via a hoisted style block — no runtime prop. Mounted alongside the chat column in session.\$id.tsx; exports a SessionInspectorDrawer wrapper for future narrow-viewport entry points. 22 unit/integration tests at 90.83% stmt coverage plus 7 Playwright visual baselines and 3 refreshed session route baselines. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Rewrites /network route + every component under web/src/systems/network/** as a pure visual migration over @agh/ui primitives. - Route shell: PageHeader + Pills tab switcher + Metric strip + SplitPane. Drops WorkspacePageShell, PillButton, MetricStrip. - Channels + peers list panels: SearchInput + button rows + StatusDot/MonoBadge, Empty for every loading/error/no-results branch. All data-testid contracts preserved for the Playwright e2e suite. - Channel detail: three Section blocks — Wire trace (Table of channel metadata), Members (StatusDot + MonoBadge list), Messages (KindChip + CodeBlock payload per message, mapping OpenAPI-optional `intent` to the seven-kind agh-network/v0 set, fallback `say`). - Peer detail: three Section blocks — Capabilities (KindChip list), Channels (single-row Table), Message Statistics (4-column Metric row). - Create channel dialog rewritten on Dialog + Field + Section; submit guarded via disabled + form-level early return. - NetworkEmptyState accepts IconComponent | ReactNode (mirrors @agh/ui Empty). 20 new unit tests + 5 play-fn stories + regenerated Playwright baselines (248 passed; 6 new network snapshots covering error/loading/no-messages states). Component coverage: 100% / 87.5% / 84.8% / 92.8% / 90.9% (≥80% each). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated web assets dependency to a newer version for improved stability and performance. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/211?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-27 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout - Fix release dry-run token contract ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth - Require npm auth before release merge ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated dependencies to latest versions. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/214?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Summary by CodeRabbit
New Features
Tests
Bug Fixes
Chores