- Privacy diagnostics: the provider name is None for unknown endpoints
and when no base URL is set; calling .lower() on it raised and dropped
every issue of the check, including the warning for privacy_mode=none
with an unknown remote endpoint.
- Telemetry: the pattern allowlist built a PatternLoader without its
required directories, so it was always empty and every pattern label
became __unknown__. It now reads ids from the shared loader through a
new PatternLoader.get_pattern_ids().
- Error summary: the LLM context builder read the category from a nested
pattern_match key that the pattern stage never writes; it now reads the
top-level category (nested key kept as a fallback).
- Sidebar: an error delivered before the sidebar panel existed (it waits
for UI text) threw on auto-open, and so did the menu toggle. Visibility
is now applied when the panel is created.
- OpenAPI info.version now matches the package version, and the version
metadata test enforces it.
- A missing optional patterns/custom directory is logged at debug level
instead of a warning; missing built-in directories still warn.
The markdown and code-highlighting libraries were requested from the
absolute path /extensions/ComfyUI-Doctor/lib/. ComfyUI serves an
extension under its install folder name, so any other folder name got
404s and silently loaded unpinned copies from cdn.jsdelivr.net into the
ComfyUI origin; offline, assistant replies rendered as blank bubbles and
the failed load surfaced as an unhandled promise rejection.
Asset URLs are now resolved relative to the rendering module, and the
CDN fallback is removed. A missing asset logs one warning and the load
never rejects. The chat island shows a reply as plain text while marked
is unavailable and re-renders it as markdown once the assets settle.
The E2E test server also serves the extension under a lowercase install
folder, and the harness can load Doctor through a host-shaped
/extensions/<folder>/ entry. Host-asset tests cover both folder names,
missing assets and late asset loading, with CDN requests blocked.
The chat panel logged stream failures to the console only, so HTTP
errors, in-stream error events, network failures and empty replies left
the pending "..." reply on screen forever. Every request now settles its
pending reply: failures become a localized, text-only error (partial
replies are kept), a new Stop button ends a reply with a stop notice,
and an empty reply reports a stream error.
Error and notice bubbles render as plain text and are never sent back to
the model as conversation history; the request history now carries only
user and assistant turns as role/content pairs.
Fix suggestions come from model output and can be steered by prompt
injection. Button labels and titles are now set as text, buttons are only
offered on assistant replies, node ids must match a live node exactly
(execution paths walk real subgraph hosts only), and suggested values are
parsed strictly per widget type (number range, toggle literals, combo
membership, bounded text) before anything is changed. Undo and highlight
use the resolved node instead of re-parsing the id.
Adds a Playwright spec that streams a hostile fix block through the chat
island and covers role gating, exact-id resolution and value rejection.
The analyze, chat, verify-key and model-list routes sent server-side
requests to a caller-supplied base URL guarded only by a pre-flight
denylist. Callers could choose arbitrary hosts and paths, reach shared
address space and metadata ranges, drive local LLM write APIs, and use
DNS rebinding to deliver server-held keys to loopback services.
Requests now select an entry of an immutable destination registry built
at startup from the built-in provider catalog, local Ollama/LM Studio,
and operator environment variables (DOCTOR_LLM_ALLOWED_BASE_URLS and the
existing base URL variables). Outbound URLs are built from the approved
entry, resolved addresses are checked at connect time inside the shared
connector, redirects are never followed or treated as success, and error
responses no longer reflect upstream bodies or network details. The UI
shows localized operator guidance, a static rule enforces disabled
redirects and policy-managed sessions, and .comfyignore keeps tests and
tooling out of the published archive.
Add a reusable backend harness that executes the real package entrypoint
host-style, serves the registered PromptServer routes on loopback through
aiohttp's test server, captures provider requests in-process, and refuses
non-loopback connects and unknown DNS lookups. Characterization tests pin
current handler behavior and the harness's process-state restoration.
Map /extensions/ComfyUI-Doctor/ onto web/ in the E2E server, confined to
web/, so vendored rendering assets load the way ComfyUI serves them and the
default lane no longer falls back to CDN downloads. A focused spec asserts
local asset loading, markdown rendering of a chat reply, and alias
confinement.
Refresh exact frontend lanes and relocated host contracts while preserving
Desktop settings behavior. Recognize first-party Switch nodes and optional
branches without suppressing required-input or broken-link diagnostics.
Revalidate canvas, workflow and target identity across focus navigation;
cancel stale requests on newer actions and sidebar teardown. Keep legacy
positioning and nested graph traversal covered by action-level regressions.
Validation: 75 source contracts, 84 frontend unit tests, Windows full gate
with 871 backend tests and 125 subtests, and 149 mocked browser E2E tests.
Seven existing backend skips remain. No live-host certification is claimed.
Pass the concrete tab pane through activation hooks and release late async renders after manager destruction. Keep Chat island activation, unmount, and vanilla status updates bound to their owning container.
- doctor_ui.js: Extract traceback array, current_inputs, and current_outputs from new execution_error structure
- Extend handleNewError data payload with 'execution_context'
- Add Playwright E2E test to verify tracebacks and inputs are parsed properly
- Add detect-secrets whitelist for dummy key in roadmap.md
- Mark R23 completed with planning URLs