Thanks to visit codestin.com
Credit goes to github.com

Skip to content

holo-q/oomfi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

199 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oomfi

A native ComfyUI workflow editor built on vibekit, targeting .NET 10 with Dear ImGui.

Read order for new agents. This README → git log --oneline -n 40 in this repo → vibekit/README.md if you'll touch the platform layer → Read files only after that.

Getting Started

Prerequisites: .NET 10 SDK

Sibling dependency: oomfi depends on vibekit via path reference. Clone it alongside:

git clone https://github.com/holo-q/vibekit ../vibekit

Build:

dotnet build

Project topology — TWO projects, not five

The earlier README claimed Oomfi.Client / Oomfi.Graph / Oomfi.Gui / Oomfi.Session / Oomfi.Prefs as separate projects. They are not. The real layout is:

Oomfi              (executable)   composition root, GUI shell, windows, chrome, prefs UI
   ↓
Oomfi.Platform     (library)      ComfyUI SPI: Net (HTTP+WS), Graph, Render, Ids, Workspace
   ↓
Vibekit (Core, Platform, Widgets.{Canvas,Nodes}, Tracing, sourcegen analyzers)

Slnx: Oomfi.slnx. Both projects target net10.0.


Boot sequence

Program.cs           AppKit.Launch(new OomfiApp())
       ↓
OomfiApp.OnSetup()   (in OomfiApp.cs)
   1. Prefs migrate  (ServerConfig, Editor, Theme, Keybinds, ...)
   2. Build OmfiKeybindStore (generated [Command] actions + persisted overrides)
   3. CreateWorkspace() → OomfiWorkspace ; bootstrap blank tab
   4. New ComfyNet (client + WSListener + node/model catalogs)
   5. Build HistoryUI shared context
   6. CreateWindows() — 12 long-lived BaseWindows (see Windows table below)
   7. menu.AddProvider(this)             (sourcegen-emitted RegisterGeneratedMenu)
   8. chrome.AddProvider(execution + theme providers)
   9. theme.Apply(prefs)
  10. net.StartListening()              (WS loop)
  11. if ServerConfig.AutoConnect → net.Connect()

OomfiApp — partial-class layout

OomfiApp is split into 9 files, one concern each. Mirrors the Python mixin pattern (app_*.py).

File Owns
OomfiApp.cs Composition root: ctor, OnSetup, prefs roots, Quit, accessors
OomfiApp.Handlers.cs AppKit lifecycle: OnPersistState, OnFrameBegin, OnGUI, OnShortcuts, OnCleanup, OnFileDrop
OomfiApp.Menu.cs [Command]-decorated handlers: Open/Save/SaveAs/NewWorkflow/DeleteTab/... + GUI_MenuTabs strip
OomfiApp.Layouts.cs BuiltinLayoutBlueprints (Nodes / Bench presets), per-window config, layout migration
OomfiApp.Windows.cs Window field slots + CreateWindows() builder
OomfiApp.Workspace.cs File I/O state, AutoLoadStartupFile, Open, OpenFromPng, SaveAs, drag-resolve
OomfiApp.NodeRender.cs Node renderer lifecycle: BuildNodeRenderer, RefreshNodeRenderer, LiveEditorWindow, tab activation hook
OomfiApp.Dnd.cs File-drop classification + modifier capture (JSON→workflow, PNG→workflow-or-media, image→LoadImage)
OomfiApp.Media.cs Image artifact store wiring, texture lookup, reveal routing

Implements: AppKit, IKeybindProvider, IActionProvider, IMenuProvider.


Oomfi.Platform — embeddable ComfyUI SPI

src/Oomfi.Platform/
├── OomfiWorkspace.cs       Workspace<WorkflowTab> ; tab/artifact/prompt routing
├── WorkflowTab.cs          one open workflow + its artifacts + run history + fallback schemas
├── Graph/                  workflow model + serde
│   ├── WorkflowGraph.cs        the NodeGraph that Vibekit.Widgets.Nodes renders
│   ├── WorkflowIO.cs           api-format ↔ web-format ↔ disk
│   ├── ComfyPromptDocument.cs  parsed JSON envelope
│   ├── ComfyPromptNode.cs      (ClassType, Inputs, Title, Flags) record
│   ├── ComfyValue.cs           sealed-record sum: Null|Bool|Number|Text|Array|Object|Link
│   ├── ComboHelpers.cs / JsonHelpers.cs / TypeConversion.cs / ComfyPinMetadata.cs / WorkflowNodeFactory.cs
├── Ids/                    strong-typed identities — implicit string in, explicit string out
│   ├── WorkflowId.cs           tab/workflow handle
│   ├── PromptId.cs             one ComfyUI execution
│   ├── NodeId.cs               node within a workflow
│   └── ArtifactId.cs           generated image (10-char GUID via .New())
├── Net/                    (was monolithic; reorganized 2026-04-27 by transport)
│   ├── Catalog/                NodeCatalog (object_info schema), ModelCatalog (checkpoints/...)
│   ├── Client/                 ComfyClient (HTTP + WS), WSListener (semantic event dispatcher)
│   ├── Http/                   typed schema records + result records (renamed from "Responses" 2026-04-27)
│   ├── Ws/                     ComfyWsMessage hierarchy, BinaryType enum, RunError
│   ├── Runs/                   QueueController, PromptRun, RunMode, ExecutionProgress
│   ├── Media/                  ImageArtifactStore, NodeImageStore, pending-* async picker types
│   └── Utils/                  AsyncThread
├── Render/                 ComfyUI-flavoured node rendering (lives outside Vibekit.Widgets.Nodes)
│   ├── ComfyNodeRenderer.cs    INodeRenderer impl ; missing-node badges, gallery drops, balloons
│   ├── ComfyParamRenderer.cs   widget dispatch (multiline editor state owned per renderer)
│   ├── ComfyDynamicComboRender.cs  schema-driven combo boxes
│   ├── ComfyWidgets.cs / ComfyLayout.cs / ComfyRenderImage.cs / ComfyPinControls.cs
│   └── INodeParamHost.cs / ComfyDelegateTracing.cs
└── WorkflowTab.cs / OomfiWorkspace.cs (top-level)

Oomfi — the GUI shell

src/Oomfi/
├── Program.cs               AppKit.Launch(new OomfiApp())
├── OomfiApp.*.cs            (9 partials — see table above)
├── CommandAttribute.cs      [Command(path, Icon=..., EnabledWhen=...)]
├── GlobalUsings.cs          Vec2/3/4, Mat4, ig=ImGui, TraceLogger, Notifier, Prefs aliases
├── Chrome/                  execution chrome, theme, keybind store, queue+runner gizmos
│   ├── OmfiKeybindStore.cs / OmfiTheme.cs / Theme.cs
│   ├── OmfiExecutionChromeProvider.cs / OmfiThemeChromeProvider.cs
│   ├── QueueGizmo + Config + Placement + PeekState + TopToolbarMode
│   ├── RunnerGizmo + Config
│   ├── CanvasChromeRouting.cs / NodeToolsGui.cs
├── Prefs/                   sealed prefs sections + Tabs/ UI
│   ├── ServerConfig / EditorPrefs / GalleryPrefs / KeybindPrefs / OmfiThemePrefs
│   ├── PerformancePrefs / StartupPrefs / WorkflowSessionPrefs
│   └── Tabs/ — AppearanceTab, EditorTab, ServerTab, KeybindsTab, PerformanceTab + PreferenceTabs.cs builder
├── Session/                 WorkflowNaming.cs (skeleton; persistence not yet ported)
├── Widgets/                 HistoryUI.cs (shared timeline embedded in 3 windows)
└── Windows/                 12 docked windows (see table)

Windows

Window Concern
NodesWindow Multi-tab NodeEditorWidget + node palette sidebar + toolbar gizmos
QueueWindow /queue poll, running/pending list, errors, clear/interrupt
RunnerWindow RunMode (Manual/Queue/AutoQueue) + BatchCount + cached/executed counters
BenchWindow MediaCanvasWindow subclass — active workflow's artifact, pan/zoom
PreviewWindow live-preview frames as they arrive
HistoryWindow HistoryUI instance (scope: global/workflow ; presentation: table/strip)
DrawerWindow Per-node param editor via ComfyParamRenderer
PropertiesWindow Node metadata (type, category, ...)
ConsoleWindow Execution messages / warnings / errors
GalleryWindow Filesystem/artifact browser; drag image to LoadImage pin
ModelBrowserWindow Browse available checkpoints/models from ModelCatalog
PreferencesWindow Vibekit generic prefs window + PreferenceTabs.Build() tab list

ComfyUI run lifecycle (file map)

1. user clicks Queue                            → OomfiApp.Menu.Queue() / RunnerWindow
2. enqueue                                      → ComfyNet.Enqueue → QueueController.Enqueue
3. POST /prompt                                 → ComfyClient.PostPrompt           (Net/Client/ComfyClient.cs)
4. server sends WS frames                       → ComfyClient WS loop
5. parse semantic events                        → WSListener                       (Net/Client/WSListener.cs)
6. fan to GUI                                   → QueueWindow / RunnerWindow / NodesWindow
7. binary preview frame                         → ComfyClient OnPreview → ImageArtifactStore.StageLivePreview()  (Net/Media/)
8. result image fetched (/view?filename=…)      → ImageArtifactStore.StageResultImage()
9. drain pending textures on frame              → ImageArtifactStore.Drain()       (called from OomfiApp.OnGUI via OomfiApp.Media.cs)

Where to add things

Want to add… Where
Menu item w/ keybind hint [Command("File/Foo", Icon="fa-x")] void Foo() { } in any OomfiApp.*.cs partial
Plain menu item (no action) [Menu("View/Foo")] void Foo() { } likewise
Plain keybind [Shortcut("ctrl+s")] void Save() { } likewise
New window Add file under Windows/ subclassing BaseWindow, BaseWindow<TState>, or BaseWindow<TPrefs,TState>; inject exact collaborators in OomfiApp.Windows.cs
New ComfyUI WS message type Net/Ws/Messages/... + handler in WSListener
New prefs section Sealed class in Prefs/; tab in Prefs/Tabs/; register in PreferenceTabs.Build
New layout preset Add to BuiltinLayoutBlueprints in OomfiApp.Layouts.cs
New gallery / drag behavior OomfiApp.Dnd.cs (Classify + modifier dispatch)

Currently in flux (weight things-in-motion vs things-stable)

Trajectory at 2026-04-27. The structure above is correct; these specific surfaces are mid-rename and will move:

  • "Surface" vocabulary purgeRemove stale surface vocabulary (6ee2807), Rename history surface context (abc43ba), Rename Comfy parameter surface renderer (bd3a6c7). Don't introduce *Surface names.
  • History → image artifactsRename output history to image artifacts (aa46494), Separate live previews from output history (04edc64), Rename history actions to artifacts (4a69f19). The Python-era word "output history" is gone.
  • HTTP "Responses" → "Results"Rename Comfy HTTP responses to results (bc68f9b).
  • Node-definition providers — schema lookups routed through INodeDefinitionProvider (vibekit a9e23bf/6260b85). Tab boundary owns fallback schemas (1575972/819987b). Active provider concept still settling — Use active node provider for model targets (1160b3e).
  • Typed runtime IDsType websocket runtime ids (f14a838), Type WorkflowGraph internals (ac80274), and many sibling commits in vibekit. New code should use the typed-key types, never strings.
  • Workspace tab boundary — fallback schemas + media + outputs all migrating onto the WorkflowTab (6c2eb4d, a54ac97, 4ff36c4, 819987b). If you're tempted to put per-workflow state on OomfiApp, put it on the tab instead.
  • Runner / runtime injectionInject runner window server (70a7355), Clarify runner server wiring (19f73a7), Collapse runner execution view into ComfyNet (a84f1c1). The runner-vs-net seam is still being narrowed.
  • AppKit Connect* collapsefollow AppKit Connect* collapse (43a79c4). Old ConnectLayout/Menu/... ceremony was deleted; everything goes through OnSetup + interface auto-wire now.
  • Property→field demotion / Statestate — public-data-class fields, not properties; lowercase state field on BaseWindow<TState,_>. Many small commits Apr 24.

Reference

  • Python source: ../../repositories/oomfi/src/oomfi/ — authoritative for parity gaps; we're translating, not rearchitecting (see root AGENTS.md).
  • Vibekit platform: ../vibekit/README.md.
  • ComfyUI mirrors (read-only) under references/ComfyUI/ and references/ComfyUI_frontend/ — for understanding the upstream protocol surface.

Releases

No releases published

Packages

 
 
 

Contributors

Languages