fluxy-bot 0.8.9 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -84
- package/bin/cli.js +1717 -6
- package/components.json +18 -18
- package/package.json +98 -109
- package/postcss.config.js +3 -3
- package/scripts/install.ps1 +1 -1
- package/scripts/install.sh +1 -1
- package/scripts/postinstall.js +47 -58
- package/shared/ai.ts +118 -202
- package/shared/config.ts +37 -39
- package/shared/logger.ts +6 -14
- package/shared/paths.ts +10 -16
- package/shared/relay.ts +89 -98
- package/supervisor/backend.ts +77 -89
- package/supervisor/chat/ARCHITECTURE.md +13 -14
- package/supervisor/chat/OnboardWizard.tsx +2194 -3419
- package/supervisor/chat/fluxy-main.tsx +495 -633
- package/supervisor/chat/fluxy.html +24 -36
- package/supervisor/chat/onboard-main.tsx +8 -8
- package/supervisor/chat/onboard.html +10 -13
- package/supervisor/chat/src/components/Chat/AudioBubble.tsx +94 -108
- package/supervisor/chat/src/components/Chat/ChatView.tsx +14 -36
- package/supervisor/chat/src/components/Chat/ImageLightbox.tsx +71 -89
- package/supervisor/chat/src/components/Chat/InputBar.tsx +498 -728
- package/supervisor/chat/src/components/Chat/MessageBubble.tsx +154 -246
- package/supervisor/chat/src/components/Chat/MessageList.tsx +114 -138
- package/supervisor/chat/src/components/Chat/TypingIndicator.tsx +38 -50
- package/supervisor/chat/src/components/LoginScreen.tsx +245 -296
- package/supervisor/chat/src/hooks/useChat.ts +210 -259
- package/supervisor/chat/src/hooks/useFluxyChat.ts +232 -322
- package/supervisor/chat/src/hooks/useSpeechRecognition.ts +126 -148
- package/supervisor/chat/src/lib/auth.ts +20 -23
- package/supervisor/chat/src/lib/ws-client.ts +113 -125
- package/supervisor/chat/src/styles/globals.css +76 -85
- package/supervisor/file-saver.ts +39 -52
- package/supervisor/fluxy-agent.ts +213 -292
- package/supervisor/index.ts +895 -1263
- package/supervisor/scheduler.ts +237 -299
- package/supervisor/tunnel.ts +113 -167
- package/supervisor/vite-dev.ts +51 -61
- package/supervisor/widget.js +135 -147
- package/supervisor/worker.ts +45 -49
- package/tsconfig.json +18 -24
- package/vite.config.ts +48 -55
- package/vite.fluxy.config.ts +34 -34
- package/worker/claude-auth.ts +202 -265
- package/worker/codex-auth.ts +144 -181
- package/worker/db.ts +63 -191
- package/worker/index.ts +601 -842
- package/workspace/MYSELF.md +1 -1
- package/workspace/PULSE.json +6 -6
- package/workspace/backend/index.ts +16 -19
- package/workspace/client/index.html +47 -60
- package/workspace/client/public/manifest.json +21 -21
- package/workspace/client/public/sw.js +29 -31
- package/workspace/client/src/App.tsx +91 -136
- package/workspace/client/src/components/Dashboard/DashboardPage.tsx +68 -72
- package/workspace/client/src/components/ErrorBoundary.tsx +11 -11
- package/workspace/client/src/components/Layout/DashboardLayout.tsx +35 -35
- package/workspace/client/src/components/Layout/Footer.tsx +12 -12
- package/workspace/client/src/components/Layout/MobileNav.tsx +23 -23
- package/workspace/client/src/components/Layout/Sidebar.tsx +81 -81
- package/workspace/client/src/components/ui/avatar.tsx +85 -85
- package/workspace/client/src/components/ui/badge.tsx +40 -41
- package/workspace/client/src/components/ui/button.tsx +56 -57
- package/workspace/client/src/components/ui/card.tsx +75 -75
- package/workspace/client/src/components/ui/dialog.tsx +114 -117
- package/workspace/client/src/components/ui/dropdown-menu.tsx +191 -199
- package/workspace/client/src/components/ui/input.tsx +17 -17
- package/workspace/client/src/components/ui/scroll-area.tsx +47 -47
- package/workspace/client/src/components/ui/select.tsx +145 -151
- package/workspace/client/src/components/ui/separator.tsx +21 -21
- package/workspace/client/src/components/ui/sheet.tsx +102 -102
- package/workspace/client/src/components/ui/skeleton.tsx +10 -10
- package/workspace/client/src/components/ui/switch.tsx +26 -26
- package/workspace/client/src/components/ui/tabs.tsx +69 -69
- package/workspace/client/src/components/ui/textarea.tsx +14 -14
- package/workspace/client/src/components/ui/tooltip.tsx +37 -37
- package/workspace/client/src/lib/utils.ts +1 -1
- package/workspace/client/src/main.tsx +3 -3
- package/workspace/client/src/styles/globals.css +76 -85
- package/workspace/skills/code-reviewer/.claude-plugin/plugin.json +3 -3
- package/workspace/skills/code-reviewer/skills/code-reviewer/SKILL.md +0 -6
- package/workspace/skills/daily-standup/.claude-plugin/plugin.json +3 -3
- package/workspace/skills/daily-standup/skills/daily-standup/SKILL.md +0 -7
- package/workspace/skills/workspace-helper/.claude-plugin/plugin.json +3 -3
- package/workspace/skills/workspace-helper/skills/workspace-helper/SKILL.md +0 -2
- package/bin/cli.backup.js +0 -2138
- package/cli/commands/daemon.ts +0 -42
- package/cli/commands/init.ts +0 -32
- package/cli/commands/start.ts +0 -113
- package/cli/commands/tunnel.temp.ts +0 -206
- package/cli/commands/tunnel.ts +0 -227
- package/cli/commands/update.ts +0 -163
- package/cli/core/base-adapter.ts +0 -156
- package/cli/core/cloudflared.ts +0 -113
- package/cli/core/config.ts +0 -73
- package/cli/core/os-detector.ts +0 -43
- package/cli/core/server.ts +0 -109
- package/cli/core/types.ts +0 -15
- package/cli/index.ts +0 -72
- package/cli/platforms/darwin.ts +0 -146
- package/cli/platforms/index.ts +0 -21
- package/cli/platforms/linux.ts +0 -156
- package/cli/platforms/win32.ts +0 -34
- package/cli/utils/ui.ts +0 -37
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { cn } from
|
|
1
|
+
import { cn } from "@/lib/utils"
|
|
2
2
|
|
|
3
|
-
function Skeleton({ className, ...props }: React.ComponentProps<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
|
|
4
|
+
return (
|
|
5
|
+
<div
|
|
6
|
+
data-slot="skeleton"
|
|
7
|
+
className={cn("bg-accent animate-pulse rounded-md", className)}
|
|
8
|
+
{...props}
|
|
9
|
+
/>
|
|
10
|
+
)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export { Skeleton }
|
|
13
|
+
export { Skeleton }
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { Switch as SwitchPrimitive } from
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Switch as SwitchPrimitive } from "radix-ui"
|
|
3
3
|
|
|
4
|
-
import { cn } from
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
5
|
|
|
6
6
|
function Switch({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
className,
|
|
8
|
+
size = "default",
|
|
9
|
+
...props
|
|
10
10
|
}: React.ComponentProps<typeof SwitchPrimitive.Root> & {
|
|
11
|
-
|
|
11
|
+
size?: "sm" | "default"
|
|
12
12
|
}) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
return (
|
|
14
|
+
<SwitchPrimitive.Root
|
|
15
|
+
data-slot="switch"
|
|
16
|
+
data-size={size}
|
|
17
|
+
className={cn(
|
|
18
|
+
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6",
|
|
19
|
+
className
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
<SwitchPrimitive.Thumb
|
|
24
|
+
data-slot="switch-thumb"
|
|
25
|
+
className={cn(
|
|
26
|
+
"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
|
|
27
|
+
)}
|
|
28
|
+
/>
|
|
29
|
+
</SwitchPrimitive.Root>
|
|
30
|
+
)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export { Switch }
|
|
33
|
+
export { Switch }
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { cva, type VariantProps } from
|
|
3
|
-
import { Tabs as TabsPrimitive } from
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
|
+
import { Tabs as TabsPrimitive } from "radix-ui"
|
|
4
4
|
|
|
5
|
-
import { cn } from
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
6
|
|
|
7
7
|
function Tabs({
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
className,
|
|
9
|
+
orientation = "horizontal",
|
|
10
|
+
...props
|
|
11
11
|
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
return (
|
|
13
|
+
<TabsPrimitive.Root
|
|
14
|
+
data-slot="tabs"
|
|
15
|
+
data-orientation={orientation}
|
|
16
|
+
orientation={orientation}
|
|
17
|
+
className={cn(
|
|
18
|
+
"group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",
|
|
19
|
+
className
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
const tabsListVariants = cva(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
27
|
+
"rounded-lg p-[3px] group-data-[orientation=horizontal]/tabs:h-9 data-[variant=line]:rounded-none group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
|
|
28
|
+
{
|
|
29
|
+
variants: {
|
|
30
|
+
variant: {
|
|
31
|
+
default: "bg-muted",
|
|
32
|
+
line: "gap-1 bg-transparent",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
defaultVariants: {
|
|
36
|
+
variant: "default",
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
40
|
|
|
41
41
|
function TabsList({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
className,
|
|
43
|
+
variant = "default",
|
|
44
|
+
...props
|
|
45
45
|
}: React.ComponentProps<typeof TabsPrimitive.List> &
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
VariantProps<typeof tabsListVariants>) {
|
|
47
|
+
return (
|
|
48
|
+
<TabsPrimitive.List
|
|
49
|
+
data-slot="tabs-list"
|
|
50
|
+
data-variant={variant}
|
|
51
|
+
className={cn(tabsListVariants({ variant }), className)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
function TabsTrigger({
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
className,
|
|
59
|
+
...props
|
|
60
60
|
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
return (
|
|
62
|
+
<TabsPrimitive.Trigger
|
|
63
|
+
data-slot="tabs-trigger"
|
|
64
|
+
className={cn(
|
|
65
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
66
|
+
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
|
|
67
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground",
|
|
68
|
+
"after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
|
|
69
|
+
className
|
|
70
|
+
)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
function TabsContent({
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
className,
|
|
78
|
+
...props
|
|
79
79
|
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
return (
|
|
81
|
+
<TabsPrimitive.Content
|
|
82
|
+
data-slot="tabs-content"
|
|
83
|
+
className={cn("flex-1 outline-none", className)}
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
|
|
89
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import * as React from
|
|
1
|
+
import * as React from "react"
|
|
2
2
|
|
|
3
|
-
import { cn } from
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
4
|
|
|
5
|
-
function Textarea({ className, ...props }: React.ComponentProps<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
6
|
+
return (
|
|
7
|
+
<textarea
|
|
8
|
+
data-slot="textarea"
|
|
9
|
+
className={cn(
|
|
10
|
+
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
11
|
+
className
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export { Textarea }
|
|
18
|
+
export { Textarea }
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { Tooltip as TooltipPrimitive } from
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui"
|
|
3
3
|
|
|
4
|
-
import { cn } from
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
5
|
|
|
6
6
|
function TooltipProvider({
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
delayDuration = 0,
|
|
8
|
+
...props
|
|
9
9
|
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
return (
|
|
11
|
+
<TooltipPrimitive.Provider
|
|
12
|
+
data-slot="tooltip-provider"
|
|
13
|
+
delayDuration={delayDuration}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function Tooltip({
|
|
20
|
-
|
|
20
|
+
...props
|
|
21
21
|
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
|
22
|
-
|
|
22
|
+
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function TooltipTrigger({
|
|
26
|
-
|
|
26
|
+
...props
|
|
27
27
|
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
|
28
|
-
|
|
28
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function TooltipContent({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
className,
|
|
33
|
+
sideOffset = 0,
|
|
34
|
+
children,
|
|
35
|
+
...props
|
|
36
36
|
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
return (
|
|
38
|
+
<TooltipPrimitive.Portal>
|
|
39
|
+
<TooltipPrimitive.Content
|
|
40
|
+
data-slot="tooltip-content"
|
|
41
|
+
sideOffset={sideOffset}
|
|
42
|
+
className={cn(
|
|
43
|
+
"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
|
|
44
|
+
className
|
|
45
|
+
)}
|
|
46
|
+
{...props}
|
|
47
|
+
>
|
|
48
|
+
{children}
|
|
49
|
+
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
|
|
50
|
+
</TooltipPrimitive.Content>
|
|
51
|
+
</TooltipPrimitive.Portal>
|
|
52
|
+
)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
|
55
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
|
@@ -1,125 +1,116 @@
|
|
|
1
|
-
@import
|
|
1
|
+
@import "tailwindcss";
|
|
2
2
|
|
|
3
3
|
@custom-variant dark (&:is(.dark *));
|
|
4
4
|
|
|
5
5
|
@theme inline {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
6
|
+
--color-background: #212121;
|
|
7
|
+
--color-foreground: #f5f5f5;
|
|
8
|
+
--color-card: #2a2a2a;
|
|
9
|
+
--color-card-foreground: #f5f5f5;
|
|
10
|
+
--color-popover: #2a2a2a;
|
|
11
|
+
--color-popover-foreground: #f5f5f5;
|
|
12
|
+
--color-primary: #3C8FFF;
|
|
13
|
+
--color-primary-foreground: #ffffff;
|
|
14
|
+
--color-secondary: #333333;
|
|
15
|
+
--color-secondary-foreground: #f5f5f5;
|
|
16
|
+
--color-muted: #333333;
|
|
17
|
+
--color-muted-foreground: #999999;
|
|
18
|
+
--color-accent: #333333;
|
|
19
|
+
--color-accent-foreground: #f5f5f5;
|
|
20
|
+
--color-destructive: #FD486B;
|
|
21
|
+
--color-destructive-foreground: #ffffff;
|
|
22
|
+
--color-border: #3a3a3a;
|
|
23
|
+
--color-input: #3a3a3a;
|
|
24
|
+
--color-ring: #3C8FFF;
|
|
25
|
+
--color-chart-1: #3C8FFF;
|
|
26
|
+
--color-chart-2: #FD486B;
|
|
27
|
+
--color-chart-3: #F59E0B;
|
|
28
|
+
--color-chart-4: #8B5CF6;
|
|
29
|
+
--color-chart-5: #10B981;
|
|
30
|
+
--color-sidebar: #1c1c1c;
|
|
31
|
+
--color-sidebar-foreground: #f5f5f5;
|
|
32
|
+
--color-sidebar-primary: #3C8FFF;
|
|
33
|
+
--color-sidebar-primary-foreground: #ffffff;
|
|
34
|
+
--color-sidebar-accent: #282828;
|
|
35
|
+
--color-sidebar-accent-foreground: #f5f5f5;
|
|
36
|
+
--color-sidebar-border: #3a3a3a;
|
|
37
|
+
--color-sidebar-ring: #3C8FFF;
|
|
38
|
+
--radius: 0.75rem;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
html {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
touch-action: manipulation;
|
|
43
|
+
-ms-touch-action: manipulation;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
body {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
background-color: var(--color-background);
|
|
48
|
+
color: var(--color-foreground);
|
|
49
|
+
-webkit-font-smoothing: antialiased;
|
|
50
|
+
-moz-osx-font-smoothing: grayscale;
|
|
51
|
+
overscroll-behavior: none;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
::selection {
|
|
55
|
-
|
|
55
|
+
background-color: rgba(175, 39, 227, 0.25);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
::-webkit-scrollbar {
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
::-webkit-scrollbar-
|
|
62
|
-
background: transparent;
|
|
63
|
-
}
|
|
64
|
-
::-webkit-scrollbar-thumb {
|
|
65
|
-
background: #3a3a3a;
|
|
66
|
-
border-radius: 3px;
|
|
67
|
-
}
|
|
68
|
-
::-webkit-scrollbar-thumb:hover {
|
|
69
|
-
background: #4a4a4a;
|
|
70
|
-
}
|
|
58
|
+
::-webkit-scrollbar { width: 6px; }
|
|
59
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
60
|
+
::-webkit-scrollbar-thumb { background: #3a3a3a; border-radius: 3px; }
|
|
61
|
+
::-webkit-scrollbar-thumb:hover { background: #4a4a4a; }
|
|
71
62
|
|
|
72
63
|
.text-gradient {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
64
|
+
background-clip: text;
|
|
65
|
+
-webkit-background-clip: text;
|
|
66
|
+
color: transparent;
|
|
67
|
+
-webkit-text-fill-color: transparent;
|
|
68
|
+
background-image: linear-gradient(135deg, #04D1FE, #AF27E3, #FB4072);
|
|
78
69
|
}
|
|
79
70
|
|
|
80
71
|
.bg-gradient-brand {
|
|
81
|
-
|
|
72
|
+
background-image: linear-gradient(135deg, #04D1FE, #AF27E3, #FB4072);
|
|
82
73
|
}
|
|
83
74
|
|
|
84
75
|
.glow-border {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
0 0 20px -5px rgba(175, 39, 227, 0.15);
|
|
76
|
+
box-shadow: 0 0 0 1px rgba(175, 39, 227, 0.1),
|
|
77
|
+
0 0 20px -5px rgba(175, 39, 227, 0.15);
|
|
88
78
|
}
|
|
89
79
|
|
|
90
80
|
.animated-border {
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
position: relative;
|
|
82
|
+
overflow: hidden;
|
|
93
83
|
}
|
|
94
84
|
.animated-border::before {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
85
|
+
content: '';
|
|
86
|
+
position: absolute;
|
|
87
|
+
inset: -150%;
|
|
88
|
+
background: conic-gradient(
|
|
89
|
+
from 0deg,
|
|
90
|
+
#04D1FE,
|
|
91
|
+
#AF27E3,
|
|
92
|
+
#FB4072,
|
|
93
|
+
#04D1FE
|
|
94
|
+
);
|
|
95
|
+
animation: border-spin 3s linear infinite;
|
|
100
96
|
}
|
|
101
97
|
.animated-border > * {
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
position: relative;
|
|
99
|
+
z-index: 1;
|
|
104
100
|
}
|
|
105
101
|
|
|
106
102
|
.animated-border-slow::before {
|
|
107
|
-
|
|
103
|
+
animation-duration: 5s;
|
|
108
104
|
}
|
|
109
105
|
|
|
110
106
|
.input-glow:focus {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
0 0 4px -1px rgba(4, 209, 254, 0.1);
|
|
107
|
+
border-color: rgba(175, 39, 227, 0.4);
|
|
108
|
+
box-shadow: 0 0 0 1px rgba(175, 39, 227, 0.15),
|
|
109
|
+
0 0 20px -5px rgba(175, 39, 227, 0.25),
|
|
110
|
+
0 0 4px -1px rgba(4, 209, 254, 0.1);
|
|
116
111
|
}
|
|
117
112
|
|
|
118
113
|
@keyframes border-spin {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
100% {
|
|
123
|
-
transform: rotate(360deg);
|
|
124
|
-
}
|
|
114
|
+
0% { transform: rotate(0deg); }
|
|
115
|
+
100% { transform: rotate(360deg); }
|
|
125
116
|
}
|
|
@@ -6,11 +6,9 @@ description: Reviews code changes, provides suggestions for improvement, identif
|
|
|
6
6
|
# Code Reviewer
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
|
-
|
|
10
9
|
This skill helps review code in the Fluxy workspace — identifying bugs, suggesting improvements, and enforcing best practices for the React + Express stack.
|
|
11
10
|
|
|
12
11
|
## When to Activate
|
|
13
|
-
|
|
14
12
|
- User asks to "review", "check", or "audit" code
|
|
15
13
|
- User asks for feedback on their changes
|
|
16
14
|
- User asks about code quality, best practices, or potential issues
|
|
@@ -18,7 +16,6 @@ This skill helps review code in the Fluxy workspace — identifying bugs, sugges
|
|
|
18
16
|
## Review Checklist
|
|
19
17
|
|
|
20
18
|
### Frontend (React + Tailwind)
|
|
21
|
-
|
|
22
19
|
1. Component structure: proper use of props, state, and effects
|
|
23
20
|
2. Performance: unnecessary re-renders, missing memoization
|
|
24
21
|
3. Accessibility: semantic HTML, ARIA attributes, keyboard navigation
|
|
@@ -26,7 +23,6 @@ This skill helps review code in the Fluxy workspace — identifying bugs, sugges
|
|
|
26
23
|
5. Error handling: error boundaries, loading states, fallbacks
|
|
27
24
|
|
|
28
25
|
### Backend (Express + SQLite)
|
|
29
|
-
|
|
30
26
|
1. Route structure: proper HTTP methods, status codes, error responses
|
|
31
27
|
2. Input validation: sanitize user input, check required fields
|
|
32
28
|
3. Database: parameterized queries, proper error handling
|
|
@@ -34,9 +30,7 @@ This skill helps review code in the Fluxy workspace — identifying bugs, sugges
|
|
|
34
30
|
5. Performance: avoid N+1 queries, use appropriate indexes
|
|
35
31
|
|
|
36
32
|
## Output Format
|
|
37
|
-
|
|
38
33
|
When reviewing code, provide:
|
|
39
|
-
|
|
40
34
|
- **Issues**: Bugs or potential problems (with severity)
|
|
41
35
|
- **Suggestions**: Improvements that would help (with rationale)
|
|
42
36
|
- **Praise**: Things done well (reinforces good patterns)
|