- Updated the build script in `build-release.ts` to set `NODE_ENV` and `VITE_USER_NODE_ENV` to production, ensuring proper environment configuration. - Refined the styling of various components including `approvals-view.tsx`, `dashboard/view.tsx`, `tasks-view.tsx`, and others to improve visual consistency with rounded borders and adjusted background colors. - Enhanced the `PendingApprovalRow` and `PoliciesPanel` components for better user interaction and layout.
Unified · Split
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | "scripts": { |
| 6 | 6 | "with-env": "bun run --env-file=../../../.env --", |
| 7 | 7 | "dev": "bun with-env vite dev --port 4312", |
| 8 | − "build": "bun with-env vite build", | |
| 8 | + "build": "NODE_ENV=production bun with-env vite build --mode production", | |
| 9 | 9 | "start": "bun with-env env PORT=5312 HOSTNAME=127.0.0.1 node dist/server/server.mjs", |
| 10 | 10 | "lint": "eslint", |
| 11 | 11 | "typecheck": "bunx --package @typescript/native-preview tsgo --noEmit -p tsconfig.json", |
| @@ -67,7 +67,7 @@ function ApprovalCard({ · 66 unmodified lines | ||
| 67 | 67 | ); |
| 68 | 68 | |
| 69 | 69 | return ( |
| 70 | − <Card className="bg-card border-border border-l-2 border-l-terminal-amber glow-amber"> | |
| 70 | + <Card className="rounded-none bg-card/40 border-border/50 border-l-2 border-l-terminal-amber glow-amber"> | |
| 71 | 71 | <CardContent className="p-4 space-y-3"> |
| 72 | 72 | {/* Header */} |
| 73 | 73 | <div className="flex items-start justify-between gap-3"> |
| @@ -180,7 +180,7 @@ export function ApprovalsView() { · 106 unmodified lines | ||
| 180 | 180 | ))} |
| 181 | 181 | </div> |
| 182 | 182 | ) : count === 0 ? ( |
| 183 | − <Card className="bg-card border-border flex-1"> | |
| 183 | + <Card className="rounded-none bg-card/40 border-border/50 flex-1"> | |
| 184 | 184 | <CardContent className="flex flex-col items-center justify-center py-20 gap-3"> |
| 185 | 185 | <div className="h-12 w-12 rounded-full bg-terminal-green/10 flex items-center justify-center"> |
| 186 | 186 | <CheckCircle2 className="h-6 w-6 text-terminal-green/60" /> |
| @@ -11,7 +11,7 @@ function PendingApprovalRow({ approval }: { approval: PendingApprovalRecord }) { · 10 unmodified lines | ||
| 11 | 11 | return ( |
| 12 | 12 | <button |
| 13 | 13 | onClick={() => navigate("/approvals")} |
| 14 | − className="w-full flex items-center gap-3 px-3 py-2.5 rounded-md hover:bg-accent/50 transition-colors text-left group" | |
| 14 | + className="group flex w-full items-center gap-3 px-3 py-2.5 text-left transition-colors hover:bg-accent/20" | |
| 15 | 15 | > |
| 16 | 16 | <div className="h-2 w-2 rounded-full bg-terminal-amber pulse-dot shrink-0" /> |
| 17 | 17 | <div className="flex-1 min-w-0"> |
| @@ -33,7 +33,7 @@ export function DashboardPendingApprovalsCard({ · 15 unmodified lines | ||
| 33 | 33 | const navigate = useNavigate(); |
| 34 | 34 | |
| 35 | 35 | return ( |
| 36 | − <Card className="bg-card border-border"> | |
| 36 | + <Card className="rounded-none border-border/50 bg-card/40"> | |
| 37 | 37 | <CardHeader className="pb-3"> |
| 38 | 38 | <div className="flex items-center justify-between"> |
| 39 | 39 | <CardTitle className="text-sm font-medium flex items-center gap-2"> |
| @@ -63,7 +63,7 @@ export function DashboardPendingApprovalsCard({ · 23 unmodified lines | ||
| 63 | 63 | No pending approvals |
| 64 | 64 | </div> |
| 65 | 65 | ) : ( |
| 66 | − <div className="space-y-0.5"> | |
| 66 | + <div className="divide-y divide-border/30"> | |
| 67 | 67 | {approvals.map((approval) => ( |
| 68 | 68 | <PendingApprovalRow key={approval.id} approval={approval} /> |
| 69 | 69 | ))} |
| @@ -46,7 +46,7 @@ export function DashboardView() { · 45 unmodified lines | ||
| 46 | 46 | /> |
| 47 | 47 | )} |
| 48 | 48 | |
| 49 | − <Card id="mcp-setup" className="bg-card border-border min-h-0 flex flex-col"> | |
| 49 | + <Card id="mcp-setup" className="rounded-none bg-card/40 border-border/50 min-h-0 flex flex-col"> | |
| 50 | 50 | <CardHeader className="pb-3"> |
| 51 | 51 | <CardTitle className="text-sm font-medium flex items-center gap-2"> |
| 52 | 52 | <Server className="h-4 w-4 text-primary" /> |
| @@ -77,7 +77,7 @@ export function TasksView() { · 76 unmodified lines | ||
| 77 | 77 | |
| 78 | 78 | <div className="flex min-h-0 flex-1 flex-col"> |
| 79 | 79 | <div className="grid h-full min-h-0 gap-6 lg:grid-cols-[minmax(360px,440px)_1fr]"> |
| 80 | − <Card className="bg-card border-border min-h-0 flex flex-col"> | |
| 80 | + <Card className="rounded-none bg-card/40 border-border/50 min-h-0 flex flex-col"> | |
| 81 | 81 | <CardHeader className="pb-3"> |
| 82 | 82 | <CardTitle className="text-sm font-medium flex items-center gap-2"> |
| 83 | 83 | Task History |
| @@ -126,7 +126,7 @@ export function TasksView() { · 42 unmodified lines | ||
| 126 | 126 | onClose={() => selectTask(null)} |
| 127 | 127 | /> |
| 128 | 128 | ) : ( |
| 129 | − <Card className="bg-card border-border h-full"> | |
| 129 | + <Card className="rounded-none bg-card/40 border-border/50 h-full"> | |
| 130 | 130 | <CardContent className="flex items-center justify-center py-24"> |
| 131 | 131 | <p className="text-sm text-muted-foreground"> |
| 132 | 132 | Select a task to view logs, output, and approval actions |
| @@ -92,7 +92,7 @@ export function CredentialsPanel({ · 91 unmodified lines | ||
| 92 | 92 | }, [credentials]); |
| 93 | 93 | |
| 94 | 94 | return ( |
| 95 | − <section className="mx-auto flex h-full min-h-0 w-full max-w-6xl flex-col border border-border/50 bg-card/40"> | |
| 95 | + <section className="mx-auto flex h-full min-h-0 w-full max-w-6xl flex-col rounded-none border border-border/50 bg-card/30"> | |
| 96 | 96 | <div className="flex items-center justify-between border-b border-border/40 px-4 py-3 sm:px-5"> |
| 97 | 97 | <div className="flex items-center gap-2"> |
| 98 | 98 | <div className="flex h-7 w-7 items-center justify-center border border-border/60 bg-background/80"> |
| @@ -140,6 +140,7 @@ export function CredentialsPanel({ · 41 unmodified lines | ||
| 140 | 140 | <div |
| 141 | 141 | key={connection.key} |
| 142 | 142 | className="group flex items-center gap-3 border border-border/50 bg-background/70 px-3 py-2.5 transition-colors hover:border-border hover:bg-accent/20" |
| 143 | + style={{ boxShadow: "inset 2px 0 0 0 color-mix(in oklch, var(--border) 70%, transparent)" }} | |
| 143 | 144 | > |
| 144 | 145 | <div className="flex h-8 w-8 shrink-0 items-center justify-center border border-border/60 bg-muted/50 overflow-hidden"> |
| 145 | 146 | {firstSource ? ( |
| @@ -336,17 +336,29 @@ export function ToolExplorer({ · 335 unmodified lines | ||
| 336 | 336 | }, [maybeLoadToolDetails, setFocusedSourceName]); |
| 337 | 337 | |
| 338 | 338 | const handleSourceClick = useCallback((sourceName: string) => { |
| 339 | + const key = `source:${sourceName}`; | |
| 340 | + const wasFocused = focusedSourceName === sourceName; | |
| 339 | 341 | const source = sourceByName.get(sourceName); |
| 342 | + | |
| 343 | + if (wasFocused) { | |
| 344 | + setSourceFocusState(null, null); | |
| 345 | + setExpandedKeys((prev) => { | |
| 346 | + const next = new Set(prev); | |
| 347 | + next.delete(key); | |
| 348 | + return next; | |
| 349 | + }); | |
| 350 | + return; | |
| 351 | + } | |
| 352 | + | |
| 340 | 353 | setSourceFocusState(sourceName, source ?? null); |
| 341 | 354 | // Ensure the source group is expanded |
| 342 | 355 | setExpandedKeys((prev) => { |
| 343 | − const key = `source:${sourceName}`; | |
| 344 | 356 | if (prev.has(key)) return prev; |
| 345 | 357 | const next = new Set(prev); |
| 346 | 358 | next.add(key); |
| 347 | 359 | return next; |
| 348 | 360 | }); |
| 349 | − }, [sourceByName]); | |
| 361 | + }, [focusedSourceName, setSourceFocusState, sourceByName]); | |
| 350 | 362 | |
| 351 | 363 | const handleAddSource = useCallback(() => { |
| 352 | 364 | setSourceFocusState(null, null); |
| @@ -748,7 +748,7 @@ function PolicyCard({ · 747 unmodified lines | ||
| 748 | 748 | const [showTools, setShowTools] = useState(false); |
| 749 | 749 | |
| 750 | 750 | return ( |
| 751 | − <div className="group relative rounded-lg border border-border/60 bg-card hover:border-border transition-colors"> | |
| 751 | + <div className="group relative rounded-none border border-border/60 bg-card/60 hover:border-border transition-colors"> | |
| 752 | 752 | <div className="px-3.5 py-2.5"> |
| 753 | 753 | {/* Header row */} |
| 754 | 754 | <div className="flex items-start gap-2.5"> |
| @@ -1321,7 +1321,7 @@ export function PoliciesPanel({ · 566 unmodified lines | ||
| 1321 | 1321 | ))} |
| 1322 | 1322 | </div> |
| 1323 | 1323 | ) : policies.length === 0 ? ( |
| 1324 | − <div className="rounded-lg border border-dashed border-border/50 py-10 flex flex-col items-center gap-2.5"> | |
| 1324 | + <div className="rounded-none border border-dashed border-border/50 py-10 flex flex-col items-center gap-2.5"> | |
| 1325 | 1325 | <Shield className="h-8 w-8 text-muted-foreground/30" /> |
| 1326 | 1326 | <div className="text-center"> |
| 1327 | 1327 | <p className="text-xs text-muted-foreground">No tool policies configured</p> |
| @@ -1377,7 +1377,7 @@ export function PoliciesPanel({ · 49 unmodified lines | ||
| 1377 | 1377 | |
| 1378 | 1378 | <Separator className="bg-border/40" /> |
| 1379 | 1379 | |
| 1380 | − <details className="group rounded-lg border border-border/60 bg-card/40"> | |
| 1380 | + <details className="group rounded-none border border-border/60 bg-card/30"> | |
| 1381 | 1381 | <summary className="flex cursor-pointer list-none items-center justify-between gap-3 px-3 py-2.5"> |
| 1382 | 1382 | <div> |
| 1383 | 1383 | <h4 className="text-sm font-medium">Policy Set Manager</h4> |
| @@ -1391,12 +1391,12 @@ export function PoliciesPanel({ · 7 unmodified lines | ||
| 1391 | 1391 | |
| 1392 | 1392 | <div className="px-3 pb-3"> |
| 1393 | 1393 | {!canManageRoles ? ( |
| 1394 | − <div className="rounded-lg border border-dashed border-border/50 p-4 text-xs text-muted-foreground"> | |
| 1394 | + <div className="rounded-none border border-dashed border-border/50 p-4 text-xs text-muted-foreground"> | |
| 1395 | 1395 | Organization owner/admin role required to manage tool policy sets. |
| 1396 | 1396 | </div> |
| 1397 | 1397 | ) : ( |
| 1398 | 1398 | <div className="grid grid-cols-1 gap-4 lg:grid-cols-[280px_1fr]"> |
| 1399 | − <div className="space-y-3 rounded-lg border border-border/60 bg-card p-3"> | |
| 1399 | + <div className="space-y-3 rounded-none border border-border/60 bg-card/50 p-3"> | |
| 1400 | 1400 | <Label className="text-xs text-muted-foreground">Create policy set</Label> |
| 1401 | 1401 | <Input |
| 1402 | 1402 | value={roleForm.name} |
| @@ -1455,7 +1455,7 @@ export function PoliciesPanel({ · 52 unmodified lines | ||
| 1455 | 1455 | </div> |
| 1456 | 1456 | </div> |
| 1457 | 1457 | |
| 1458 | − <div className="space-y-4 rounded-lg border border-border/60 bg-card p-4"> | |
| 1458 | + <div className="space-y-4 rounded-none border border-border/60 bg-card/50 p-4"> | |
| 1459 | 1459 | {!selectedRole ? ( |
| 1460 | 1460 | <p className="text-xs text-muted-foreground">Select a policy set to manage its rules and assignments.</p> |
| 1461 | 1461 | ) : ( |
| @@ -447,9 +447,11 @@ async function buildWebArtifact(rootDir: string, releaseDir: string, checksums: · 446 unmodified lines | ||
| 447 | 447 | EXECUTOR_WEB_CONVEX_SITE_URL: "http://127.0.0.1:5411", |
| 448 | 448 | VITE_CONVEX_URL: "http://127.0.0.1:5410", |
| 449 | 449 | VITE_CONVEX_SITE_URL: "http://127.0.0.1:5411", |
| 450 | + NODE_ENV: "production", | |
| 451 | + VITE_USER_NODE_ENV: "production", | |
| 450 | 452 | }; |
| 451 | 453 | |
| 452 | − await runCommand(["bunx", "vite", "build"], { | |
| 454 | + await runCommand(["bunx", "vite", "build", "--mode", "production"], { | |
| 453 | 455 | cwd: webAppDir, |
| 454 | 456 | env: webBuildEnv, |
| 455 | 457 | }); |