Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,7 @@
"paths": [
{
"name": "lucide-react",
"message": "lucide-react is retired — import from @/lib/icons instead."
},
{
"name": "@phosphor-icons/react",
"message": "Import icons from @/lib/icons, not @phosphor-icons/react directly."
}
],
"patterns": [
{
"group": ["@phosphor-icons/react/*"],
"message": "Import icons from @/lib/icons, not @phosphor-icons/react directly."
"message": "Import icons from @/lib/icons, not lucide-react directly."
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
"@corbits/workflows": "workspace:*",
"@intx/types": "workspace:*",
"@isomorphic-git/lightning-fs": "4.7.0",
"@phosphor-icons/react": "^2.1.10",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-slot": "^1.2.3",
"@tanstack/react-query": "catalog:",
"arktype": "catalog:",
"buffer": "^6.0.3",
"isomorphic-git": "catalog:",
"lucide-react": "^1.49.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-joyride": "^2.9.3"
Expand Down
24 changes: 0 additions & 24 deletions apps/web/src/lib/icons/index.test.tsx

This file was deleted.

101 changes: 49 additions & 52 deletions apps/web/src/lib/icons/index.tsx
Original file line number Diff line number Diff line change
@@ -1,88 +1,85 @@
// Sparkle/Sparkles is banned outright — it read as a generic "AI" cliché.
// A curated re-export, not a full pass-through, so a stray import can't
// reach for an off-list icon or tiptoe around the bold-weight rule.
import { IconContext, type Icon, type IconProps } from "@phosphor-icons/react";
// reach for an off-list icon or tiptoe around the stroke-width rule.
import { LucideProvider, type LucideIcon, type LucideProps } from "lucide-react";
import type { ReactNode } from "react";

export type { Icon, IconProps };
export type Icon = LucideIcon;
export type IconProps = LucideProps;

export {
Archive,
ArrowBendUpLeft,
ArrowClockwise,
ArrowDown,
ArrowLeft,
ArrowsDownUp,
ArrowsIn,
ArrowsOut,
ArrowSquareOut,
ArrowRight,
ArrowUp,
ArrowUpDown as ArrowsDownUp,
Bell,
BookBookmark,
CaretDown,
CaretLeft,
CaretRight,
ChartBar,
ChatCircle,
ChatCircleDots,
BookMarked as BookBookmark,
Bot as Robot,
Check,
CircleNotch,
ChartColumn as ChartBar,
ChevronDown as CaretDown,
ChevronLeft as CaretLeft,
ChevronRight as CaretRight,
CircleAlert as WarningCircle,
CircleUser as UserCircle,
CirclePlay as PlayCircle,
Clock,
Compass,
CornerUpLeft as ArrowBendUpLeft,
Copy,
Cpu,
DotsThree,
FileDashed,
Diff as GitDiff,
Ellipsis as DotsThree,
FileText,
FlowArrow,
FileQuestionMark as FileDashed,
FolderOpen,
GitBranch,
GitDiff,
GitPullRequest,
Hash,
Key,
Lightning,
LinkSimple,
ListBullets,
Layers as Stack,
LayoutGrid as SquaresFour,
Link as LinkSimple,
List as ListBullets,
LoaderCircle as CircleNotch,
Lock,
MagnifyingGlass,
Microphone,
MoonStars,
PaperPlaneRight,
LogOut as SignOut,
Maximize2 as ArrowsOut,
MessageCircle as ChatCircle,
MessageCircleMore as ChatCircleDots,
Mic as Microphone,
Minimize2 as ArrowsIn,
MoonStar as MoonStars,
Paperclip,
PencilSimple,
PlayCircle,
Pencil as PencilSimple,
Pin as PushPin,
PinOff as PushPinSlash,
Plug as Plugs,
Plus,
Plugs,
PushPin,
PushPinSlash,
Repeat,
Robot,
RotateCw as ArrowClockwise,
Search as MagnifyingGlass,
Send as PaperPlaneRight,
Shield,
SignOut,
SlidersHorizontal,
Smiley,
Stack,
Smile as Smiley,
Square as Stop,
SquareArrowOutUpRight as ArrowSquareOut,
Star,
Stop,
SquaresFour,
TriangleAlert as Warning,
User,
UserCircle,
UserPlus,
Users,
Warning,
WarningCircle,
Workflow as FlowArrow,
X,
} from "@phosphor-icons/react";
Zap as Lightning,
} from "lucide-react";

// `IconContext.Provider` replaces Phosphor's whole context value rather
// than merging it, so every library default (`size`) must be restated
// alongside the override — dropping it silently un-sizes bare glyphs.
export const boldIconContextValue = { size: "1em", weight: "bold" } as const;

/** Wraps a subtree so every Phosphor icon under it defaults to bold weight
* without repeating `weight="bold"` at each call site. Mounted once at each
* app's root (see `apps/web/src/app.tsx`). */
/** Wraps a subtree so every icon under it defaults to a 2px stroke without
* repeating it at each call site (the `1em` default size is `tailwind.css`).
* Mounted once at each app's root (see `apps/web/src/app.tsx`). */
export function BoldIconProvider({ children }: { children: ReactNode }) {
return <IconContext.Provider value={boldIconContextValue}>{children}</IconContext.Provider>;
return <LucideProvider strokeWidth={2}>{children}</LucideProvider>;
}
11 changes: 5 additions & 6 deletions apps/web/src/pages/diff-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import { Badge, Table, TableBody, TableCell, TableRow } from "@corbits/react-ui";
import { diffText } from "@/lib/text-diff";
import type { DiffLine } from "@/lib/text-diff";
import { useMemo } from "react";
import { ArrowRight, DotsThree } from "@/lib/icons";
import { useMemo, type ReactNode } from "react";

const MARKER: Record<DiffLine["kind"], string> = {
const MARKER: Record<DiffLine["kind"], ReactNode> = {
context: " ",
added: "+",
removed: "-",
skipped: "⋯",
skipped: <DotsThree aria-hidden="true" className="mx-auto" />,
};

const ROW_CLASS: Record<DiffLine["kind"], string> = {
Expand Down Expand Up @@ -104,9 +105,7 @@ export function DiffHeading({
return (
<div className="flex flex-wrap items-center gap-2 text-xs">
<Badge tone="neutral">{beforeLabel}</Badge>
<span aria-hidden="true" className="text-muted-foreground">
→
</span>
<ArrowRight aria-hidden="true" className="text-muted-foreground" />
<Badge tone="info">{afterLabel}</Badge>
</div>
);
Expand Down
7 changes: 5 additions & 2 deletions apps/web/src/pages/insights-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
type BadgeTone,
type RunStatus,
} from "@corbits/react-ui";
import { ChartBar } from "@/lib/icons";
import { ArrowRight, ChartBar } from "@/lib/icons";
import { runOutcomeStatus, runStatusLabel, withListingAbandoned } from "@corbits/workflows/client";
import type * as React from "react";
import { useEffect, useState } from "react";
Expand Down Expand Up @@ -274,7 +274,10 @@ function RecentRunRows({
))}
<TableRow {...onRowActivate(onOpenRuns)}>
<TableCell colSpan={2} className="font-semibold text-primary-emphasis">
All runs →
<span className="inline-flex items-center gap-1">
All runs
<ArrowRight aria-hidden="true" />
</span>
</TableCell>
</TableRow>
</TableBody>
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/pages/new-workbench-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import { Button, toast } from "@corbits/react-ui";
import { useDismissablePopover } from "@corbits/react-ui/hooks/use-dismissable-popover";
import { PaperPlaneRight } from "@/lib/icons";
import { Check, PaperPlaneRight, X } from "@/lib/icons";
import { CHAT_STRINGS, WorkbenchLoadingState } from "@/chat";
import { isMyraAgent, listChatAgents } from "@/chat/threads-api";
import { useMemo, useRef, useState } from "react";
Expand Down Expand Up @@ -228,7 +228,7 @@ export function NewWorkbenchPickerRoute() {
aria-label={`Remove ${agent.name}`}
onClick={() => toggleAgent(agent.id)}
>
×
<X aria-hidden="true" />
</button>
</span>
))}
Expand Down Expand Up @@ -326,7 +326,7 @@ export function NewWorkbenchPickerRoute() {
<span className="new-workbench-agent-option-name">
{agent.name}
</span>
{selected ? <span aria-hidden="true">✓</span> : null}
{selected ? <Check aria-hidden="true" /> : null}
</button>
);
})}
Expand Down
7 changes: 7 additions & 0 deletions apps/web/src/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
--font-mono: "Space Mono", "Fira Code", Monaco, Consolas, monospace;
}

/* Icons default to the surrounding text size; `:where` keeps zero specificity
so a size-* utility on the icon still wins. */
:where(svg.lucide) {
width: 1em;
height: 1em;
}

/* Workspace UI packages are source-only (no build step): their .tsx files
carry className utilities and artifact-ui's kind-color.ts returns palette
class strings. Tailwind v4's auto-detection stays inside apps/web, so each
Expand Down
2 changes: 1 addition & 1 deletion apps/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function manualChunks(id: string): string | undefined {
if (id.includes("@corbits+react-ui") || id.includes("@corbits/react-ui")) {
return "react-ui";
}
if (id.includes("@phosphor-icons/react")) return "icons";
if (id.includes("lucide-react")) return "icons";
if (id.includes("@tanstack")) return "query-vendor";
return undefined;
}
Expand Down
Loading
Loading