3.9 KiB
Backend architecture
Model Resolver keeps the ComfyUI entry point small and separates HTTP wiring from the feature logic that powers each route.
Runtime flow
__init__.pyexposes the ComfyUI compatibility exports and initializes the extension.core/extension.pyowns runtime state such as progress trackers and starts route registration.core/routes/registry.pyloads the available integrations and builds aRouteContextwith explicit dependencies.- Modules in
core/routes/adapt HTTP requests and responses to service calls. - Services in
core/services/contain feature behavior and receive their dependencies throughRouteContext.
Route registration imports the concrete route modules directly. The actual handlers live in focused route adapters and services; no compatibility grouping layer is kept for this application-only package.
Frontend architecture
The frontend keeps ComfyUI-specific integration at the extension boundary in
web/model_resolver.js and composes the dialog behavior in
web/resolver/resolver_dialog.js. The dialog is assembled from focused method
groups:
web/resolver/shell/owns lifecycle, workflow identity, and tab state.web/resolver/search/owns source selection, search state, aliases, and hash matching.web/resolver/views/owns view-specific state such as missing models and model information.web/resolver/downloads/owns queue storage and download progress policy.web/resolver/utils/owns shared API, keybinding, and browser helpers.
Pure policies and state transitions are exported as small ES modules so they can be tested without booting ComfyUI. The extension entry point and the dialog composition are covered separately as integration contracts.
Adding a route
When adding a feature, keep the request parsing, status codes, and JSON response
in a route adapter. Put reusable behavior in a service and add its dependency to
RouteContext explicitly. Use json_api_endpoint for the common error boundary,
and preserve deliberate aiohttp.web.HTTPException statuses when returning
client errors.
Add a focused route/service test before changing behavior. For changes that touch route registration or shared backend code, run the complete Python suite as well.
Local verification
For frontend changes, run these commands from the project directory:
npm test
npm run test:coverage
npm run lint
test:coverage uses Node's built-in test coverage reporter and prints the
current statement, branch, and function coverage. It is an inspection report,
not a hard threshold, because runtime-only ComfyUI adapters cannot be fully
exercised outside the host application.
Pull request checks
The repository workflow lives in .github/workflows/ci.yml. It runs the
frontend and backend checks for pull requests whose source repository is
outside this repository, which keeps automated validation focused on external
contributions. It does not run for direct pushes to main; local changes by
the maintainer should use the verification commands above before committing.
The workflow uses the tracked package-lock.json with npm ci, has read-only
repository permissions, and does not require secrets. Its two jobs run:
npm testandnpm run lintfor the frontend.pytest, Ruff, andcompileallfor the backend.
The workflow uses pull_request, not pull_request_target, so code from an
external fork is tested with the restricted pull-request token context.
Run these commands with the same Python interpreter used by ComfyUI:
python -m pytest
python -m ruff check __init__.py core
python -m compileall -q __init__.py core
python -m coverage run -m pytest
python -m coverage report -m
The development tools are declared in the dev optional dependency group in
pyproject.toml. Coverage configuration is kept there as well, with branch
coverage enabled and core/ as the measured source.