diff --git a/apps/array/src/renderer/App.tsx b/apps/array/src/renderer/App.tsx
index 18141560..bce9236d 100644
--- a/apps/array/src/renderer/App.tsx
+++ b/apps/array/src/renderer/App.tsx
@@ -1,4 +1,3 @@
-import { CursorGlow } from "@components/CursorGlow";
import { LoginTransition } from "@components/LoginTransition";
import { MainLayout } from "@components/MainLayout";
import { AuthScreen } from "@features/auth/components/AuthScreen";
@@ -67,7 +66,6 @@ function App() {
return (
<>
-
{!isAuthenticated ? (
;
+}
+
+export function TorchGlow({ containerRef }: TorchGlowProps) {
+ const isDarkMode = useThemeStore((state) => state.isDarkMode);
+ const [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(
+ null,
+ );
+ const [isHovering, setIsHovering] = useState(false);
+
+ useEffect(() => {
+ const container = containerRef.current;
+ if (!container) return;
+
+ const handleMouseMove = (e: MouseEvent) => {
+ const rect = container.getBoundingClientRect();
+ setMousePos({
+ x: e.clientX - rect.left,
+ y: e.clientY - rect.top,
+ });
+ };
+
+ const handleMouseEnter = () => setIsHovering(true);
+ const handleMouseLeave = () => {
+ setIsHovering(false);
+ setMousePos(null);
+ };
+
+ container.addEventListener("mousemove", handleMouseMove);
+ container.addEventListener("mouseenter", handleMouseEnter);
+ container.addEventListener("mouseleave", handleMouseLeave);
+
+ return () => {
+ container.removeEventListener("mousemove", handleMouseMove);
+ container.removeEventListener("mouseenter", handleMouseEnter);
+ container.removeEventListener("mouseleave", handleMouseLeave);
+ };
+ }, [containerRef]);
+
+ // Only show in dark mode when hovering
+ if (!isDarkMode || !isHovering || !mousePos) return null;
+
+ return (
+ <>
+ {/* SVG filter for grainy torch light texture */}
+
+
+ {/* Base layer - outer glow */}
+
+
+ {/* Middle layer - offset for irregular shape */}
+
+
+ {/* Inner layer - pulsing flame core */}
+
+ >
+ );
+}
diff --git a/apps/array/src/renderer/features/task-detail/components/TaskInput.tsx b/apps/array/src/renderer/features/task-detail/components/TaskInput.tsx
index 407261a6..3414cd38 100644
--- a/apps/array/src/renderer/features/task-detail/components/TaskInput.tsx
+++ b/apps/array/src/renderer/features/task-detail/components/TaskInput.tsx
@@ -1,3 +1,4 @@
+import { TorchGlow } from "@components/TorchGlow";
import { FolderPicker } from "@features/folder-picker/components/FolderPicker";
import type { MessageEditorHandle } from "@features/message-editor/components/MessageEditor";
import type { ExecutionMode } from "@features/sessions/stores/sessionStore";
@@ -35,6 +36,7 @@ export function TaskInput() {
const { lastUsedLocalWorkspaceMode } = useSettingsStore();
const editorRef = useRef(null);
+ const containerRef = useRef(null);
const [selectedDirectory, setSelectedDirectory] = useState(
lastUsedDirectory || "",
@@ -81,89 +83,100 @@ export function TaskInput() {
});
return (
-
-
+
-
-
- {selectedDirectory && (
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- )}
-
+ {selectedDirectory && (
+
+ )}
+
+
+
-
-
-
+
+
-
+
);
}
diff --git a/apps/array/src/renderer/styles/globals.css b/apps/array/src/renderer/styles/globals.css
index 2d8a3b1e..9a15b72d 100644
--- a/apps/array/src/renderer/styles/globals.css
+++ b/apps/array/src/renderer/styles/globals.css
@@ -113,6 +113,21 @@
animation: campfire-pulse 1s ease-in-out infinite;
}
+/* Torch glow pulse animation for cursor flame effect */
+@keyframes torch-pulse {
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.3;
+ }
+}
+
+.torch-glow-pulse {
+ animation: torch-pulse 1.5s ease-in-out infinite;
+}
+
.radix-themes {
/* Font families */
--default-font-family: