Skip to content

Commit 5dd48e1

Browse files
PurpleDoubleDclaude
andcommitted
feat: execution time display, logo removal, README update
- Show real ComfyUI execution time in output info bar after generation - Store lastGenTime in createStore (persists across renders) - Remove CPU/SVG logo from header and onboarding (text only) - Update README: add Workflow Finder, Dynamic Builder, Model Marketplace, Privacy First, VRAM Management. Mark RAG/Voice/Agents as work in progress. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 19356b9 commit 5dd48e1

10 files changed

Lines changed: 5155 additions & 14 deletions

File tree

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,20 @@ Tired of switching between Ollama for chat, ComfyUI for images, and another tool
6363
- **Uncensored AI Chat** — Run abliterated models locally with zero restrictions
6464
- **Image Generation** — Text-to-image via ComfyUI with full parameter control
6565
- **Video Generation** — Text-to-video with Wan 2.1/2.2 and AnimateDiff support
66+
- **Workflow Finder** — Auto-detects your model type and builds the right ComfyUI workflow. Search CivitAI or use built-in templates.
67+
- **Dynamic Workflow Builder** — No hardcoded pipelines. Queries ComfyUI's available nodes and constructs the optimal workflow automatically.
68+
- **Model Marketplace** — Search and download models from CivitAI directly into ComfyUI. One click, right folder, auto-detected.
6669
- **25+ Personas** — From Helpful Assistant to Roast Master, ready out of the box
6770
- **Model Manager** — Browse, install, and switch models with one click
68-
- **Discover & Install Models** — Browse and one-click install text, image, and video models directly in the app
6971
- **Thinking Display** — See the AI's reasoning in collapsible blocks
70-
- **Dark/Light Mode** — Beautiful glassmorphism UI that actually looks good
72+
- **Dark/Light Mode** — Deep black dark mode with sharp contrasts, clean light mode
73+
- **Privacy First** — Zero external tracking. All API calls proxied locally. No Google Fonts, no CDN scripts, no analytics.
7174
- **100% Local** — Everything runs on your machine, nothing touches the internet
7275
- **Conversation History** — All chats saved locally in your browser
73-
- **Document Chat (RAG)** — Upload PDFs, DOCX, or TXT files and chat with your documents. Hybrid search with confidence scores.
74-
- **Voice Chat** — Talk to your AI with push-to-talk and hear responses with text-to-speech. Sentence-level streaming.
75-
- **AI Agents** — Give your AI a goal and watch it plan, search the web, read/write files, and execute Python code autonomously.
76+
- **VRAM Management** — Unload models from GPU memory with one click after generation
77+
- **Document Chat (RAG)** *(work in progress)* — Upload PDFs, DOCX, or TXT files and chat with your documents.
78+
- **Voice Chat** *(work in progress)* — Talk to your AI with push-to-talk and hear responses with text-to-speech.
79+
- **AI Agents** *(work in progress)* — Give your AI a goal and watch it plan, search the web, and execute code autonomously.
7680
- **Standalone Desktop App** — Full Tauri v2 Rust backend. Download the .exe, run it — no terminal, no dev server, no Node.js.
7781

7882
## Tech Stack

src-tauri/gen/schemas/acl-manifests.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"default":{"identifier":"default","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["core:default","core:window:default","core:webview:default","shell:allow-spawn","shell:allow-stdin-write","shell:allow-kill"]}}

src-tauri/gen/schemas/desktop-schema.json

Lines changed: 2564 additions & 0 deletions
Large diffs are not rendered by default.

src-tauri/gen/schemas/windows-schema.json

Lines changed: 2564 additions & 0 deletions
Large diffs are not rendered by default.

src/components/create/OutputDisplay.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { getImageUrl } from '../../api/comfyui'
55
import { useCreateStore, type GalleryItem } from '../../stores/createStore'
66

77
export function OutputDisplay() {
8-
const { isGenerating, progress, progressText, gallery } = useCreateStore()
8+
const { isGenerating, progress, progressText, gallery, lastGenTime } = useCreateStore()
99
const [fullscreen, setFullscreen] = useState<GalleryItem | null>(null)
1010
const [copiedSeed, setCopiedSeed] = useState(false)
1111
const latest = gallery[0]
@@ -132,6 +132,12 @@ export function OutputDisplay() {
132132
</button>
133133
<span>·</span>
134134
<span>{latest.width}x{latest.height}</span>
135+
{lastGenTime && (
136+
<>
137+
<span>·</span>
138+
<span>{lastGenTime}</span>
139+
</>
140+
)}
135141
</div>
136142
</div>
137143

src/components/layout/Header.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Menu, Settings, Cpu, Sun, Moon, MessageSquare, Film, Layers, Bot } from 'lucide-react'
1+
import { Menu, Settings, Sun, Moon, MessageSquare, Film, Layers, Bot } from 'lucide-react'
22
import { useUIStore } from '../../stores/uiStore'
33
import { useSettingsStore } from '../../stores/settingsStore'
44
import { useChatStore } from '../../stores/chatStore'
@@ -29,8 +29,7 @@ export function Header() {
2929
}}
3030
className="flex items-center gap-2 text-gray-800 dark:text-gray-200 hover:opacity-80 transition"
3131
>
32-
<Cpu size={20} />
33-
<span className="font-bold text-sm tracking-wider hidden sm:inline">LOCALLY UNCENSORED</span>
32+
<span className="font-bold text-sm tracking-wider">LOCALLY UNCENSORED</span>
3433
</button>
3534
</div>
3635

src/components/onboarding/Onboarding.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useState } from 'react'
22
import { motion, AnimatePresence } from 'framer-motion'
3-
import { Cpu, Sun, Moon, ArrowRight, Download, Check, ChevronRight } from 'lucide-react'
3+
import { Sun, Moon, ArrowRight, Download, Check, ChevronRight } from 'lucide-react'
44
import { useSettingsStore } from '../../stores/settingsStore'
55
import { useModels } from '../../hooks/useModels'
66
import { ONBOARDING_MODELS, type OnboardingModel } from '../../lib/constants'
@@ -59,9 +59,6 @@ export function Onboarding() {
5959
animate={{ opacity: 1, y: 0 }}
6060
exit={{ opacity: 0, y: -20 }}
6161
>
62-
<div className={`w-20 h-20 rounded-2xl flex items-center justify-center mx-auto ${isDark ? 'bg-white/10' : 'bg-gray-100'}`}>
63-
<Cpu size={40} className={isDark ? 'text-gray-300' : 'text-gray-600'} />
64-
</div>
6562
<h1 className="text-3xl font-bold">Locally Uncensored</h1>
6663
<p className={isDark ? 'text-gray-400' : 'text-gray-500'}>
6764
Private, local AI chat. No servers, no tracking, everything stays on your machine.

src/hooks/useCreate.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ export function useCreate() {
241241
const comfyTime = startMsg?.[1]?.timestamp && endMsg?.[1]?.timestamp
242242
? ((endMsg[1].timestamp - startMsg[1].timestamp) / 1000).toFixed(1)
243243
: null
244-
setProgress(100, comfyTime ? `Done in ${comfyTime}s` : 'Complete!')
244+
setProgress(100, 'Complete!')
245+
useCreateStore.getState().setLastGenTime(comfyTime ? `${comfyTime}s` : null)
245246

246247
const outputs = history.outputs ?? {}
247248
let found = false

src/stores/createStore.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ interface CreateState {
4545
progressText: string
4646
currentPromptId: string | null
4747
error: string | null
48+
lastGenTime: string | null
4849
gallery: GalleryItem[]
4950
promptHistory: string[]
5051

@@ -66,6 +67,7 @@ interface CreateState {
6667
setProgress: (progress: number, text?: string) => void
6768
setCurrentPromptId: (id: string | null) => void
6869
setError: (error: string | null) => void
70+
setLastGenTime: (time: string | null) => void
6971
addToGallery: (item: GalleryItem) => void
7072
removeFromGallery: (id: string) => void
7173
clearGallery: () => void
@@ -96,6 +98,7 @@ export const useCreateStore = create<CreateState>()(
9698
progressText: '',
9799
currentPromptId: null,
98100
error: null,
101+
lastGenTime: null,
99102
gallery: [],
100103
promptHistory: [],
101104

@@ -120,6 +123,7 @@ export const useCreateStore = create<CreateState>()(
120123
setProgress: (progress, text) => set({ progress, progressText: text ?? '' }),
121124
setCurrentPromptId: (id) => set({ currentPromptId: id }),
122125
setError: (error) => set({ error }),
126+
setLastGenTime: (time) => set({ lastGenTime: time }),
123127
addToGallery: (item) => set((s) => ({ gallery: [item, ...s.gallery].slice(0, 200) })),
124128
removeFromGallery: (id) => set((s) => ({ gallery: s.gallery.filter((g) => g.id !== id) })),
125129
clearGallery: () => set({ gallery: [] }),

0 commit comments

Comments
 (0)