From cd7b77fb244b080dadf56f7d490c7f0a110b5ef7 Mon Sep 17 00:00:00 2001 From: DemonGatanjieu <1027066412@qq.com> Date: Tue, 4 Aug 2026 22:01:20 +0800 Subject: [PATCH] fix(ui): restore browser entry after recipe parse error --- .agents/logs/ai_changelog.md | 16 ++++++++++++++++ .agents/logs/ai_lessons.md | 8 ++++++++ ARCHITECTURE.md | 6 ++++++ web/modules/ui_recipes.js | 11 ----------- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/.agents/logs/ai_changelog.md b/.agents/logs/ai_changelog.md index 7d62615..7377771 100644 --- a/.agents/logs/ai_changelog.md +++ b/.agents/logs/ai_changelog.md @@ -15,6 +15,22 @@ - `python_embeded/python.exe tests/test_recipe_roundtrip.py` - `git diff --check` +## [Snapshot] 2026-08-04 - Restore browser entry after recipe module parse failure + +**Implemented** + +- Diagnosed the missing plugin icon against a live ComfyUI runtime instead of treating it as a CSS-only issue. +- Confirmed `/extensions/Anomalous_Model_Browser/*` was served and the hash resolver registered, while the main browser extension was absent from ComfyUI's extension registry. +- Removed the duplicate `summaryValue` and `createBadge` declarations in `web/modules/ui_recipes.js`. The duplicate top-level declarations caused `SyntaxError: Identifier 'summaryValue' has already been declared`, which stopped `main.js` from loading and prevented the trigger from being mounted. +- Added the parseability and runtime-entry-point rule to `ARCHITECTURE.md`. + +**Validation** + +- All plugin JavaScript files passed `node --check`. +- Live ComfyUI runtime on port 8199 loaded the plugin and created `#anomalous-trigger-btn` with the established `📦` mark, visible at the bottom-right of the viewport. +- Temporary module probe was removed after diagnosis. +- `git diff --check`. + ## [Snapshot] 2026-08-04 - Restore the original plugin mark - Restored the original 📦 floating trigger mark after the startup-resilience audit; no functional behavior changed. diff --git a/.agents/logs/ai_lessons.md b/.agents/logs/ai_lessons.md index c0df12c..7edc67a 100644 --- a/.agents/logs/ai_lessons.md +++ b/.agents/logs/ai_lessons.md @@ -501,6 +501,14 @@ For a gallery whose source is a directory walk, querying only when the panel ope The floating trigger is the recovery path for the entire extension, so it must not be appended only after every panel has initialized. Mount it first, catch constructor failures, and retry on click. Optional browser APIs such as `IntersectionObserver` must be feature-detected before use; otherwise a nonessential gallery enhancement can make the whole plugin appear to have disappeared. +## 77. A missing icon can be an ES-module parse failure + +**The Problem**: The backend served the extension files and the optional hash resolver appeared in ComfyUI's extension settings, but the visible Anomalous Model Browser entry point was absent. CSS and z-index changes could not fix it. + +**The Cause**: A recipe UI merge left duplicate top-level `summaryValue` and `createBadge` declarations in `ui_recipes.js`. The browser rejected the module with `SyntaxError: Identifier 'summaryValue' has already been declared`; because `main.js` imports that module, its registration and trigger creation never ran. + +**The Practice**: When a plugin entry disappears, inspect the extension registry and isolate-load the main entry before changing presentation styles. Search for duplicate declarations across recently merged modules, run `node --check` over the complete web tree, and verify the actual trigger DOM node in a live ComfyUI session. + ## 76. An optional auto-hook must not own extension startup ComfyUI loads every JavaScript file under a custom node's `WEB_DIRECTORY`. A resolver that assumes the legacy global `LGraph` can fail before the visible browser entry point is initialized. Optional graph hooks must detect the current graph constructor, guard duplicate patching, and return cleanly when the host API is unavailable. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index bb35736..8b0f711 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -258,3 +258,9 @@ The save dialog records recipe identity, notes, tags, cover/source image, and mo The notebook create row contains a text input and a confirmation button. In the 660px docked browser, the notebook sidebar is reduced to 80px, so the input must have `min-width: 0` and the confirmation button must remain a non-shrinking fixed-size item. Otherwise the input's placeholder intrinsic width pushes the check button outside the clickable sidebar. The output gallery is a user-refreshed view of ComfyUI's output directory. Opening the gallery performs one page-one scan, and the toolbar's Refresh button explicitly repeats that scan on demand. There is no background polling; the grid preserves scroll position when manually refreshed. + +## 69. Keep the main browser entry module parseable + +The floating trigger is created by `web/main.js`, but ComfyUI loads every JavaScript file in the custom node's `WEB_DIRECTORY` as an ES module. A syntax or duplicate top-level declaration in any imported module prevents `main.js` from registering and leaves no visible plugin icon, even when the backend routes and the optional hash resolver are healthy. + +When a trigger disappears, verify the browser extension registry and load the main entry in isolation before changing CSS or z-index values. In particular, do not duplicate helper declarations while merging recipe UI changes; shared helpers in `ui_recipes.js` must have one definition per module. `node --check` is required for the affected module, and a real ComfyUI runtime check must confirm that `#anomalous-trigger-btn` is created. diff --git a/web/modules/ui_recipes.js b/web/modules/ui_recipes.js index 500b196..7a1a91d 100644 --- a/web/modules/ui_recipes.js +++ b/web/modules/ui_recipes.js @@ -281,17 +281,6 @@ function createBadge(text, kind = '') { return badge; } -function summaryValue(value, fallback = '—') { - return value === null || value === undefined || value === '' ? fallback : String(value); -} - -function createBadge(text, kind = '') { - const badge = document.createElement('span'); - badge.className = `anomalous-recipe-badge${kind ? ` anomalous-recipe-badge-${kind}` : ''}`; - badge.textContent = text; - return badge; -} - function displayWidgetValue(value) { if (typeof value === 'object' && value !== null) { try { return JSON.stringify(value); } catch (error) { return String(value); }