Conversation
WalkthroughAdds a large set of new UI components and utilities to the renderer, introduces a CSS-variable based theme (light/dark/system) and a useTheme hook, replaces hard-coded color tokens with semantic tokens across core renderer components, adds a cn utility and components.json, adjusts deps/config and a small smoke-test script tweak. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Comment |
Add light/dark/system theme cycling and apply token-based theming across Sidebar, ChatView, and global styles to introduce light modeIntroduce a 📍Where to StartStart with the Macroscope summarized 0a535ae. |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In `@apps/renderer/src/components/Sidebar.tsx`:
- Around line 225-230: The button currently uses the disabled prop which
conflicts with accessibility guidance and tooltips; instead remove the disabled
attribute on the button element, add aria-disabled={isPickingFolder} to reflect
state, keep/adjust the visual "disabled" classes conditionally when
isPickingFolder, and add a click guard at the top of handlePickFolder (or inline
in the onClick wrapper) that returns early if isPickingFolder so clicks are
ignored; ensure tooltip behavior is preserved by using aria-disabled rather than
disabled.
In `@apps/renderer/src/components/ui/combobox.tsx`:
- Around line 196-214: The SVG in the Combobox component uses an incorrect xmlns
value; update the xmlns on the SVG inside ComboboxPrimitive.ItemIndicator to the
correct "http://www.w3.org/2000/svg" string so the icon renders properly (look
for the SVG element in the ComboboxPrimitive.ItemIndicator within the
combobox.tsx component and change the xmlns attribute value).
In `@apps/renderer/src/components/ui/empty.tsx`:
- Around line 94-105: The component EmptyDescription is typed as
React.ComponentProps<"p"> but renders a <div>, causing a props/semantic
mismatch; fix it by making the types and markup consistent—either change the
rendered element to <p> (keep the same props type) or change the prop type to
React.ComponentProps<"div"> (keep the <div>); update the function signature
(EmptyDescription) accordingly and ensure spreading {...props}, className and
data-slot="empty-description" remain correct for the chosen element.
In `@apps/renderer/src/components/ui/scroll-area.tsx`:
- Around line 5-35: Replace the custom use of ScrollAreaPrimitive
(ScrollAreaPrimitive.Root, ScrollAreaPrimitive.Viewport,
ScrollAreaPrimitive.Corner) and the local ScrollBar components with the Coss UI
ScrollArea wrapper: install the package via the shadcn CLI (`pnpm dlx
shadcn@latest add `@coss/scroll-area``), import Coss's ScrollArea,
ScrollAreaViewport and Corner (or the exported equivalents) and re-create this
component as a thin wrapper named ScrollArea that forwards props and children
while preserving the scrollFade and scrollbarGutter booleans by mapping them to
equivalent className masks and gutter classes on the Coss component (apply the
same mask expressions and `data-has-overflow-*` gutter classes), and ensure
data-slot attributes (scroll-area-viewport, scroll-area-corner) remain on the
mapped children so existing consumers continue to work.
In `@apps/renderer/src/components/ui/select.tsx`:
- Around line 128-142: The SVG used inside SelectPrimitive.ItemIndicator has a
typo in its xmlns attribute; update the xmlns on the SVG element within
SelectPrimitive.ItemIndicator to the correct namespace
"http://www.w3.org/2000/svg" so the checkmark renders correctly across browsers
(locate the SVG in the SelectPrimitive.ItemIndicator block and replace the
incorrect "http://www.w3.org/1500/svg" value).
In `@apps/renderer/src/components/ui/skeleton.tsx`:
- Around line 1-3: The file uses React.ComponentProps<"div"> in the Skeleton
component but doesn't import the React namespace; add an import for React (e.g.,
add "import React from 'react'" or "import type React from 'react'") at the top
of apps/renderer/src/components/ui/skeleton.tsx so the React.ComponentProps type
resolves for the Skeleton function signature.
🧹 Nitpick comments (6)
apps/renderer/src/components/ui/table.tsx (1)
36-47: Consider extracting long class strings for maintainability.The class string on line 40 is quite long with many frame-conditional styles. While this is a common pattern in shadcn-style UI libraries, consider extracting the frame-specific styles into a separate variable or using Tailwind's
@applydirective in a CSS file for better readability.That said, this is a stylistic preference and the current implementation is functionally correct.
apps/renderer/src/components/ui/separator.tsx (1)
13-13: The CSS selector for vertical self-stretch is fragile and likely won't work as intended.The selector
not-[[class^='h-']]:not-[[class*='_h-']]checks whether theclassattribute string starts with'h-'or contains'_h-'. Since other classes (e.g.,shrink-0) will appear first in the composed className, the[class^='h-']condition will almost never match—even when a height utility likeh-10is present.Consider simplifying by always applying
self-stretchfor vertical orientation and letting explicit height classes override it naturally, or document that consumers should use inline styles / CSS variables for custom heights:♻️ Suggested simplification
- "shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:not-[[class^='h-']]:not-[[class*='_h-']]:self-stretch", + "shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",apps/renderer/src/components/ui/toast.tsx (1)
220-250: Consider extracting shared toast content into a reusable component.The toast content rendering here (icon, title, description, action button) is nearly identical to lines 128-158 in the
Toastscomponent. Extracting this into a sharedToastContentcomponent would reduce duplication and ensure consistency when making future changes.♻️ Suggested extraction
// Shared component to use in both Toasts and AnchoredToasts function ToastContentBody({ toast }: { toast: Toast.ToastObject }) { const Icon = toast.type ? TOAST_ICONS[toast.type as keyof typeof TOAST_ICONS] : null; return ( <Toast.Content className="pointer-events-auto flex items-center justify-between gap-1.5 overflow-hidden px-3.5 py-3 text-sm ..."> <div className="flex gap-2"> {Icon && ( <div className="[&>svg]:h-lh [&>svg]:w-4 [&_svg]:pointer-events-none [&_svg]:shrink-0" data-slot="toast-icon" > <Icon className="in-data-[type=loading]:animate-spin ..." /> </div> )} <div className="flex flex-col gap-0.5"> <Toast.Title className="font-medium" data-slot="toast-title" /> <Toast.Description className="text-muted-foreground" data-slot="toast-description" /> </div> </div> {toast.actionProps && ( <Toast.Action className={buttonVariants({ size: "xs" })} data-slot="toast-action"> {toast.actionProps.children} </Toast.Action> )} </Toast.Content> ); }apps/renderer/src/components/ui/kbd.tsx (1)
5-26: Prefer Coss UI primitives for consistency.These custom Kbd/KbdGroup wrappers diverge from the guideline to use Coss UI components (installed via the ShadCN CLI) for consistent styling and Base UI accessibility alignment. If a Coss kbd component exists, consider swapping to it (or document why bespoke wrappers are required).
Based on learnings: Applies to **/*.tsx : Use Coss UI components (https://coss.com/ui) for consistent styling. Install new components using the ShadCN CLI (e.g.,
bunx --bun shadcnlatest add coss/button). Refer to Base UI docs for accessibility guidelines on primitives.apps/renderer/src/components/ui/textarea.tsx (1)
7-10: Consider documenting or removing thenumbertype forsize.The
sizeprop accepts"sm" | "default" | "lg" | number, but the internal styling logic (lines 35-38) only handles the string literals. When a number is passed, it's set ondata-sizebut no corresponding styles are applied.If numeric sizes are intended for custom CSS handling via
data-size, consider adding a brief comment documenting this. Otherwise, consider restricting the type to the supported string literals only.apps/renderer/src/index.css (1)
227-242: Consider using CSS variables for scrollbar colors for consistency.The scrollbar styling uses hardcoded
rgba()values while the rest of the file uses CSS variables. For better theme consistency, consider using the defined tokens:♻️ Optional: Use CSS variables for scrollbar colors
::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, 0.15); + background: var(--muted-foreground); + opacity: 0.15; border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { - background: rgba(0, 0, 0, 0.25); + background: var(--muted-foreground); + opacity: 0.25; } .dark ::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.1); + background: var(--muted-foreground); + opacity: 0.1; } .dark ::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.18); + background: var(--muted-foreground); + opacity: 0.18; }Note: Opacity on scrollbar thumbs may have limited browser support; the current approach works reliably.
| <button | ||
| type="button" | ||
| className="mb-2 flex w-full items-center justify-center rounded-md border border-white/[0.1] px-2 py-1.5 text-xs text-[#a0a0a0]/70 transition-colors duration-150 hover:bg-white/[0.04] disabled:cursor-not-allowed disabled:opacity-60" | ||
| className="mb-2 flex w-full items-center justify-center rounded-md border border-border px-2 py-1.5 text-xs text-muted-foreground transition-colors duration-150 hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-60" | ||
| onClick={() => void handlePickFolder()} | ||
| disabled={isPickingFolder} | ||
| > |
There was a problem hiding this comment.
Avoid the disabled prop; use aria-disabled and a click guard instead.
The current disabled usage conflicts with the repo’s accessibility guidance and can break tooltips. Use styling plus a guard in the handler.
🛠️ Suggested fix
- className="mb-2 flex w-full items-center justify-center rounded-md border border-border px-2 py-1.5 text-xs text-muted-foreground transition-colors duration-150 hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-60"
- onClick={() => void handlePickFolder()}
- disabled={isPickingFolder}
+ className={`mb-2 flex w-full items-center justify-center rounded-md border border-border px-2 py-1.5 text-xs text-muted-foreground transition-colors duration-150 hover:bg-secondary ${
+ isPickingFolder ? "cursor-not-allowed opacity-60" : ""
+ }`}
+ aria-disabled={isPickingFolder}
+ onClick={() => {
+ if (isPickingFolder) return;
+ void handlePickFolder();
+ }}🤖 Prompt for AI Agents
In `@apps/renderer/src/components/Sidebar.tsx` around lines 225 - 230, The button
currently uses the disabled prop which conflicts with accessibility guidance and
tooltips; instead remove the disabled attribute on the button element, add
aria-disabled={isPickingFolder} to reflect state, keep/adjust the visual
"disabled" classes conditionally when isPickingFolder, and add a click guard at
the top of handlePickFolder (or inline in the onClick wrapper) that returns
early if isPickingFolder so clicks are ignored; ensure tooltip behavior is
preserved by using aria-disabled rather than disabled.
| <ComboboxPrimitive.ItemIndicator className="col-start-1"> | ||
| <svg | ||
| fill="none" | ||
| height="24" | ||
| stroke="currentColor" | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth="2" | ||
| viewBox="0 0 24 24" | ||
| width="24" | ||
| xmlns="http://www.w3.org/1500/svg" | ||
| > | ||
| <path d="M5.252 12.7 10.2 18.63 18.748 5.37" /> | ||
| </svg> | ||
| </ComboboxPrimitive.ItemIndicator> | ||
| <div className="col-start-2">{children}</div> | ||
| </ComboboxPrimitive.Item> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Invalid SVG namespace will break rendering.
Same issue as in select.tsx: the xmlns attribute has http://www.w3.org/1500/svg instead of http://www.w3.org/2000/svg.
🐛 Proposed fix
<svg
fill="none"
height="24"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
width="24"
- xmlns="http://www.w3.org/1500/svg"
+ xmlns="http://www.w3.org/2000/svg"
>
<path d="M5.252 12.7 10.2 18.63 18.748 5.37" />
</svg>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <ComboboxPrimitive.ItemIndicator className="col-start-1"> | |
| <svg | |
| fill="none" | |
| height="24" | |
| stroke="currentColor" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| strokeWidth="2" | |
| viewBox="0 0 24 24" | |
| width="24" | |
| xmlns="http://www.w3.org/1500/svg" | |
| > | |
| <path d="M5.252 12.7 10.2 18.63 18.748 5.37" /> | |
| </svg> | |
| </ComboboxPrimitive.ItemIndicator> | |
| <div className="col-start-2">{children}</div> | |
| </ComboboxPrimitive.Item> | |
| ); | |
| } | |
| <ComboboxPrimitive.ItemIndicator className="col-start-1"> | |
| <svg | |
| fill="none" | |
| height="24" | |
| stroke="currentColor" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| strokeWidth="2" | |
| viewBox="0 0 24 24" | |
| width="24" | |
| xmlns="http://www.w3.org/2000/svg" | |
| > | |
| <path d="M5.252 12.7 10.2 18.63 18.748 5.37" /> | |
| </svg> | |
| </ComboboxPrimitive.ItemIndicator> | |
| <div className="col-start-2">{children}</div> | |
| </ComboboxPrimitive.Item> | |
| ); | |
| } |
🤖 Prompt for AI Agents
In `@apps/renderer/src/components/ui/combobox.tsx` around lines 196 - 214, The SVG
in the Combobox component uses an incorrect xmlns value; update the xmlns on the
SVG inside ComboboxPrimitive.ItemIndicator to the correct
"http://www.w3.org/2000/svg" string so the icon renders properly (look for the
SVG element in the ComboboxPrimitive.ItemIndicator within the combobox.tsx
component and change the xmlns attribute value).
| function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) { | ||
| return ( | ||
| <div | ||
| className={cn( | ||
| "text-muted-foreground text-sm [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-slot=empty-title]+&]:mt-1", | ||
| className, | ||
| )} | ||
| data-slot="empty-description" | ||
| {...props} | ||
| /> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Type mismatch: Component typed as <p> but renders <div>.
EmptyDescription accepts React.ComponentProps<"p"> but renders a <div>. This inconsistency could confuse consumers and allows <p>-specific props that won't apply to the rendered <div>.
💡 Proposed fix
Either change the rendered element to match the type:
-function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
+function EmptyDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<divOr render a <p> to match the type (if semantically appropriate):
function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
- <div
+ <p
className={cn(
"text-muted-foreground text-sm [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-slot=empty-title]+&]:mt-1",
className,
)}
data-slot="empty-description"
{...props}
- />
+ />
);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) { | |
| return ( | |
| <div | |
| className={cn( | |
| "text-muted-foreground text-sm [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-slot=empty-title]+&]:mt-1", | |
| className, | |
| )} | |
| data-slot="empty-description" | |
| {...props} | |
| /> | |
| ); | |
| } | |
| function EmptyDescription({ className, ...props }: React.ComponentProps<"div">) { | |
| return ( | |
| <div | |
| className={cn( | |
| "text-muted-foreground text-sm [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-slot=empty-title]+&]:mt-1", | |
| className, | |
| )} | |
| data-slot="empty-description" | |
| {...props} | |
| /> | |
| ); | |
| } |
🤖 Prompt for AI Agents
In `@apps/renderer/src/components/ui/empty.tsx` around lines 94 - 105, The
component EmptyDescription is typed as React.ComponentProps<"p"> but renders a
<div>, causing a props/semantic mismatch; fix it by making the types and markup
consistent—either change the rendered element to <p> (keep the same props type)
or change the prop type to React.ComponentProps<"div"> (keep the <div>); update
the function signature (EmptyDescription) accordingly and ensure spreading
{...props}, className and data-slot="empty-description" remain correct for the
chosen element.
| function ScrollArea({ | ||
| className, | ||
| children, | ||
| scrollFade = false, | ||
| scrollbarGutter = false, | ||
| ...props | ||
| }: ScrollAreaPrimitive.Root.Props & { | ||
| scrollFade?: boolean; | ||
| scrollbarGutter?: boolean; | ||
| }) { | ||
| return ( | ||
| <ScrollAreaPrimitive.Root | ||
| className={cn("size-full min-h-0", className)} | ||
| {...props} | ||
| > | ||
| <ScrollAreaPrimitive.Viewport | ||
| className={cn( | ||
| "h-full overscroll-contain rounded-[inherit] outline-none transition-shadows focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background data-has-overflow-x:overscroll-x-contain", | ||
| scrollFade && | ||
| "mask-t-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-start)))] mask-b-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-end)))] mask-l-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-start)))] mask-r-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-end)))] [--fade-size:1.5rem]", | ||
| scrollbarGutter && | ||
| "data-has-overflow-y:pe-2.5 data-has-overflow-x:pb-2.5", | ||
| )} | ||
| data-slot="scroll-area-viewport" | ||
| > | ||
| {children} | ||
| </ScrollAreaPrimitive.Viewport> | ||
| <ScrollBar orientation="vertical" /> | ||
| <ScrollBar orientation="horizontal" /> | ||
| <ScrollAreaPrimitive.Corner data-slot="scroll-area-corner" /> | ||
| </ScrollAreaPrimitive.Root> |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Coss UI ScrollArea component documentation installation shadcn
💡 Result:
Coss UI – ScrollArea (shadcn CLI install + docs)
- Docs:
coss.com/ui/docs/components/scroll-area(coss.com) - Install (shadcn CLI):
(coss.com)
pnpm dlx shadcn@latest add `@coss/scroll-area` - Use:
(coss.com)
import { ScrollArea } from "@/components/ui/scroll-area"
If you meant the core shadcn/ui ScrollArea (Radix/Base UI), the install command is:
pnpm dlx shadcn@latest add scroll-areaCitations:
- 1: https://coss.com/ui/docs/components/scroll-area?utm_source=openai
- 2: https://coss.com/ui/docs/components/scroll-area?utm_source=openai
- 3: https://coss.com/ui/docs/components/scroll-area?utm_source=openai
- 4: https://ui.shadcn.com/docs/components/scroll-area?utm_source=openai
🏁 Script executed:
# Check for existing UI component usage patterns in the repository
find apps/renderer/src/components/ui -type f -name "*.tsx" | head -20Repository: pingdotgg/codething-mvp
Length of output: 957
🏁 Script executed:
# Check package.json to see what UI libraries are currently in use
cat package.json | grep -A 20 '"dependencies"' | head -40Repository: pingdotgg/codething-mvp
Length of output: 49
🏁 Script executed:
# Search for existing imports of UI components to understand patterns
rg "from.*coss|from.*shadcn" apps/renderer/src/components/ui --no-heading -A 1 | head -30Repository: pingdotgg/codething-mvp
Length of output: 49
🏁 Script executed:
# Check if ScrollAreaPrimitive is imported from `@radix-ui` or another source
head -50 apps/renderer/src/components/ui/scroll-area.tsxRepository: pingdotgg/codething-mvp
Length of output: 2171
Replace with Coss UI ScrollArea component for consistency with codebase guidelines.
Coss UI provides a ScrollArea component that should be installed via ShadCN CLI: pnpm dlx shadcn@latest add @coss/scroll-area``. The custom extensions (scrollFade, `scrollbarGutter`) can be preserved by wrapping the Coss UI component instead of using Base UI directly. This ensures alignment with the team's component catalog and styling standards.
🤖 Prompt for AI Agents
In `@apps/renderer/src/components/ui/scroll-area.tsx` around lines 5 - 35, Replace
the custom use of ScrollAreaPrimitive (ScrollAreaPrimitive.Root,
ScrollAreaPrimitive.Viewport, ScrollAreaPrimitive.Corner) and the local
ScrollBar components with the Coss UI ScrollArea wrapper: install the package
via the shadcn CLI (`pnpm dlx shadcn@latest add `@coss/scroll-area``), import
Coss's ScrollArea, ScrollAreaViewport and Corner (or the exported equivalents)
and re-create this component as a thin wrapper named ScrollArea that forwards
props and children while preserving the scrollFade and scrollbarGutter booleans
by mapping them to equivalent className masks and gutter classes on the Coss
component (apply the same mask expressions and `data-has-overflow-*` gutter
classes), and ensure data-slot attributes (scroll-area-viewport,
scroll-area-corner) remain on the mapped children so existing consumers continue
to work.
| <SelectPrimitive.ItemIndicator className="col-start-1"> | ||
| <svg | ||
| fill="none" | ||
| height="24" | ||
| stroke="currentColor" | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth="2" | ||
| viewBox="0 0 24 24" | ||
| width="24" | ||
| xmlns="http://www.w3.org/1500/svg" | ||
| > | ||
| <path d="M5.252 12.7 10.2 18.63 18.748 5.37" /> | ||
| </svg> | ||
| </SelectPrimitive.ItemIndicator> |
There was a problem hiding this comment.
Invalid SVG namespace will break rendering.
The xmlns attribute has a typo: http://www.w3.org/1500/svg should be http://www.w3.org/2000/svg. This invalid namespace may cause the checkmark SVG to fail to render in some browsers.
🐛 Proposed fix
<svg
fill="none"
height="24"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
width="24"
- xmlns="http://www.w3.org/1500/svg"
+ xmlns="http://www.w3.org/2000/svg"
>
<path d="M5.252 12.7 10.2 18.63 18.748 5.37" />
</svg>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <SelectPrimitive.ItemIndicator className="col-start-1"> | |
| <svg | |
| fill="none" | |
| height="24" | |
| stroke="currentColor" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| strokeWidth="2" | |
| viewBox="0 0 24 24" | |
| width="24" | |
| xmlns="http://www.w3.org/1500/svg" | |
| > | |
| <path d="M5.252 12.7 10.2 18.63 18.748 5.37" /> | |
| </svg> | |
| </SelectPrimitive.ItemIndicator> | |
| <SelectPrimitive.ItemIndicator className="col-start-1"> | |
| <svg | |
| fill="none" | |
| height="24" | |
| stroke="currentColor" | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| strokeWidth="2" | |
| viewBox="0 0 24 24" | |
| width="24" | |
| xmlns="http://www.w3.org/2000/svg" | |
| > | |
| <path d="M5.252 12.7 10.2 18.63 18.748 5.37" /> | |
| </svg> | |
| </SelectPrimitive.ItemIndicator> |
🤖 Prompt for AI Agents
In `@apps/renderer/src/components/ui/select.tsx` around lines 128 - 142, The SVG
used inside SelectPrimitive.ItemIndicator has a typo in its xmlns attribute;
update the xmlns on the SVG element within SelectPrimitive.ItemIndicator to the
correct namespace "http://www.w3.org/2000/svg" so the checkmark renders
correctly across browsers (locate the SVG in the SelectPrimitive.ItemIndicator
block and replace the incorrect "http://www.w3.org/1500/svg" value).
| import { cn } from "#/lib/utils"; | ||
|
|
||
| function Skeleton({ className, ...props }: React.ComponentProps<"div">) { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n apps/renderer/src/components/ui/skeleton.tsx | head -20Repository: pingdotgg/codething-mvp
Length of output: 723
🏁 Script executed:
find . -name "tsconfig.json" -type f | head -5Repository: pingdotgg/codething-mvp
Length of output: 160
🏁 Script executed:
cat tsconfig.json 2>/dev/null || cat ./apps/renderer/tsconfig.json 2>/dev/null || find . -name "tsconfig.json" -exec cat {} \;Repository: pingdotgg/codething-mvp
Length of output: 388
Add React type import for ComponentProps reference.
Line 3 references React.ComponentProps<"div"> without importing the React namespace. While the modern JSX transform (jsx: "react-jsx") eliminates the need for React in JSX elements, explicit namespace references like React.ComponentProps still require the import and will cause a type-checking error.
+import type * as React from "react";
import { cn } from "#/lib/utils";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { cn } from "#/lib/utils"; | |
| function Skeleton({ className, ...props }: React.ComponentProps<"div">) { | |
| import type * as React from "react"; | |
| import { cn } from "#/lib/utils"; | |
| function Skeleton({ className, ...props }: React.ComponentProps<"div">) { |
🤖 Prompt for AI Agents
In `@apps/renderer/src/components/ui/skeleton.tsx` around lines 1 - 3, The file
uses React.ComponentProps<"div"> in the Skeleton component but doesn't import
the React namespace; add an import for React (e.g., add "import React from
'react'" or "import type React from 'react'") at the top of
apps/renderer/src/components/ui/skeleton.tsx so the React.ComponentProps type
resolves for the Skeleton function signature.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/renderer/src/components/ChatView.tsx`:
- Around line 478-482: The UI currently renders effort labels by capitalizing
the first character in the map over REASONING_OPTIONS (in the SelectItem
rendering), which turns values like "xhigh" into "Xhigh"; replace this logic by
defining a display-name mapping (e.g., a constant object like
REASONING_DISPLAY_NAMES keyed by the same values in REASONING_OPTIONS) and use
that map when rendering the SelectItem label and when comparing to
DEFAULT_REASONING, falling back to a nicer formatter (e.g., full word
replacements or Title Case) only if a key is missing; update the SelectItem
render to use REASONING_DISPLAY_NAMES[effort] || fallbackFormatter(effort).
🧹 Nitpick comments (1)
apps/renderer/src/components/ChatView.tsx (1)
451-456: Minor: Redundantdark:prefixes for transparent and semantic tokens.
bg-transparentis identical in both modes, andbg-accentis a semantic token that already adapts to the theme. Thedark:prefixes are unnecessary here.♻️ Simplified styling
<SelectTrigger size="sm" - className="w-auto min-w-0 border-0 shadow-none bg-transparent dark:bg-transparent before:hidden data-[popup-open]:bg-accent dark:data-[popup-open]:bg-accent" + className="w-auto min-w-0 border-0 shadow-none bg-transparent before:hidden data-[popup-open]:bg-accent" >Apply to both SelectTrigger instances (lines 451-456 and 471-476).
Also applies to: 471-476
| {REASONING_OPTIONS.map((effort) => ( | ||
| <SelectItem key={effort} value={effort}> | ||
| {effort.charAt(0).toUpperCase() + effort.slice(1)} | ||
| {effort === DEFAULT_REASONING ? " (default)" : ""} | ||
| </SelectItem> |
There was a problem hiding this comment.
Capitalization of "xhigh" produces awkward "Xhigh" in the UI.
The inline capitalization effort.charAt(0).toUpperCase() + effort.slice(1) transforms "xhigh" to "Xhigh", which isn't user-friendly. Consider a display name mapping for better readability.
💡 Suggested approach
+const EFFORT_LABELS: Record<string, string> = {
+ xhigh: "Extra High",
+ high: "High",
+ medium: "Medium",
+ low: "Low",
+};
+
{REASONING_OPTIONS.map((effort) => (
<SelectItem key={effort} value={effort}>
- {effort.charAt(0).toUpperCase() + effort.slice(1)}
+ {EFFORT_LABELS[effort] ?? effort}
{effort === DEFAULT_REASONING ? " (default)" : ""}
</SelectItem>
))}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {REASONING_OPTIONS.map((effort) => ( | |
| <SelectItem key={effort} value={effort}> | |
| {effort.charAt(0).toUpperCase() + effort.slice(1)} | |
| {effort === DEFAULT_REASONING ? " (default)" : ""} | |
| </SelectItem> | |
| const EFFORT_LABELS: Record<string, string> = { | |
| xhigh: "Extra High", | |
| high: "High", | |
| medium: "Medium", | |
| low: "Low", | |
| }; | |
| {REASONING_OPTIONS.map((effort) => ( | |
| <SelectItem key={effort} value={effort}> | |
| {EFFORT_LABELS[effort] ?? effort} | |
| {effort === DEFAULT_REASONING ? " (default)" : ""} | |
| </SelectItem> |
🤖 Prompt for AI Agents
In `@apps/renderer/src/components/ChatView.tsx` around lines 478 - 482, The UI
currently renders effort labels by capitalizing the first character in the map
over REASONING_OPTIONS (in the SelectItem rendering), which turns values like
"xhigh" into "Xhigh"; replace this logic by defining a display-name mapping
(e.g., a constant object like REASONING_DISPLAY_NAMES keyed by the same values
in REASONING_OPTIONS) and use that map when rendering the SelectItem label and
when comparing to DEFAULT_REASONING, falling back to a nicer formatter (e.g.,
full word replacements or Title Case) only if a key is missing; update the
SelectItem render to use REASONING_DISPLAY_NAMES[effort] ||
fallbackFormatter(effort).
Remove dark mode background bleed on select triggers and add accent background when popup is open. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
35deea6 to
0a535ae
Compare
* init components * use them * Fix select trigger styling in dark mode and add open state highlight Remove dark mode background bleed on select triggers and add accent background when popup is open. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This reverts commit c51f252.
Add AI usage dashboard with token tracking and rate limits
…03-22 Merge upstream main 2026 03 22
- Add CODEX_INTEGRATION_ANALYSIS.md with detailed protocol flow analysis * Protocol flow architecture and high-level overview * Request-response JSON-RPC sequence diagrams * Event streaming and transformation pipeline * Session state machine and lifecycle events * Provider dispatch routing analysis * 5 critical improvements ranked by priority * Failure scenarios and recovery analysis * Testing and deployment recommendations - Add CODEX_IMPROVEMENTS_GUIDE.md with step-by-step implementation guide * Improvement pingdotgg#1: Method-specific timeout configuration * Improvement pingdotgg#2: Partial stream recovery buffer * Improvement pingdotgg#3: Circuit breaker pattern implementation * Improvement pingdotgg#4: Graceful shutdown with timeout * Improvement pingdotgg#5: Structured observability logging * Integration checklist and testing procedures * 5-week rollout strategy Architecture grade: B+ (strong foundation, operational concerns remain) Expected impact: 10x reduction in false timeouts, 99.9% → 99.99% availability These guides provide actionable recommendations for improving connection robustness, timeout strategies, error recovery, and observability in the Codex App Server integration.
Summary by CodeRabbit
New Features
Theme
Style