${operation("3 ambiguous image links", "Review metadata before assigning a positive / negative pair.", "go-review", "Review metadata")}${operation("Backup status", "Last sample backup today at 09:30 · verification passed.", "system-tab", "View backups", 'data-value="backups"')}${operation("No missing thumbnails", "Generate only missing previews when necessary.", "job", "Review thumbnails", 'data-job="Thumbnail check"')}
Workspace preferences
${operation("One display configuration", "Grid, density and paging settings are shared across views.", "system-tab", "Appearance", 'data-value="appearance"')}${operation("2 sample output sources", "Monitoring and enrichment share one source list.", "system-tab", "Manage sources", 'data-value="sources"')}${operation("Statistics", "Usage by prompt, category, tag and date.", "stats", "Explore")}
`;
break;
case "appearance":
body = `
Browsing & display
One set of defaults; toolbar changes apply to the current view.
${setting("default-view", "Default layout", "Choose your starting image layout.", "select", ["Grid", "List"])}${setting("density", "Thumbnail size", "Readable previews by default; no fixed column-count setting.", "select", ["Comfortable", "Large", "Compact"])}${setting("loading", "Loading behavior", "One choice replaces separate page-size and infinite-scroll controls.", "select", ["Load more on scroll", "Paged results"])}${setting("batch-size", "Results per batch", "Controls request size, independent of thumbnail size.", "select", ["50", "100", "200"])}${setting("metadata-auto", "Load metadata on selection", "Use the same inspector in the gallery and image viewer.")}${setting("metadata-cache", "Cache metadata in this browser", "Reuse fetched metadata until it changes or you clear this cache.")}${setting("image-quality", "Image loading quality", "Preserve original / optimized / fast image-loading preferences.", "select", ["Optimized", "Original", "Fast"])}${setting("video-auto", "Autoplay videos", "Videos stay within the same gallery and use native playback controls.")}${setting("video-muted", "Mute videos by default", "Keep playback quiet while browsing.")}${setting("video-loop", "Loop videos", "Repeat a selected clip until you navigate away.")}${setting("paths", "Show file paths", "Paths appear under File & provenance, not across every card.")}${setting("open-mode", "Open from ComfyUI", "Keep the node pack’s popup / new-tab preference.", "select", ["New tab", "Popup window"])}${setting("timeout", "Node search auto-hide (seconds)", "Node search behavior only. Use 0 to keep results visible.", "number", [30])}`;
break;
case "sources":
body = `${state.notice ? `
Bring older images into your prompt history
The schema upgrades automatically. An optional metadata scan links existing positives and negatives without regenerating all thumbnails.
${setting("monitoring", "Watch for new outputs", "New files enter the same library. Existing scans do not count as new runs.")}${setting("workers", "Worker threads", "Balance background scans and thumbnail work against generation.", "range", [4])}${operation("Enrich existing metadata", "Resolve both prompts, deduplicate recipes, preserve uncertain links.", "scan-review", "Review scan")}${operation("Thumbnail generation", "Generate missing previews; rebuilding all is a separate explicit option.", "thumbnail-review", "Review options")}`;
break;
case "integrations":
body = `
ComfyUI
One send contract across cards, prompt history and every metadata view.
${setting("send-destination", "Default send destination", "A destination picker previews both roles before applying.", "select", ["Ask each time", "Selected Prompt Manager node", "Create a Prompt Manager (+/-) node"])}${setting("renderer", "Host compatibility", "Use the shared compatibility layer for Classic and Nodes 2.0.", "select", ["Follow host renderer", "Classic", "Nodes 2.0"])}${setting("return-canvas", "Return to canvas after send", "Apply text without queuing generation.")}
LoRA & resources
Preserves LoraManager detection, data import and positive-only trigger injection.
${setting("lora-enable", "LoraManager integration", "Sample detection: available. Production would detect the installed extension.")}${setting("lora-triggers", "Automatically include trigger words", "Trigger words apply only to positive text; connected node inputs remain authoritative.")}${setting("civitai-key", "CivitAI API key", "Credentials stay in the server configuration. Do not enter a real key into this mock.", "password", [""])}${operation("LoRA reference data", "Review and import resource metadata.", "job", "Simulate import", 'data-job="LoRA reference import"')}`;
break;
case "tagging":
body = `
Auto-tagging
One tagging configuration for images and prompt-library actions. Every result can be reviewed before applying.
${setting("tag-model", "Tagging model", "Preserve all current engines; show download size and loaded status together.", "select", ["WD14 SwinV2 · ~400 MB", "WD14 ViT · ~400 MB", "Ollama · local model", "HuggingFace · ~16 GB"])}${setting("tag-existing", "Existing tags", "Skipping remains the default; replace and merge are explicit.", "select", ["Skip already tagged", "Merge with existing", "Replace after review"])}${setting("threshold-general", "General-tag confidence", "Current WD14 default: 0.35.", "number", [0.35])}${setting("threshold-character", "Character-tag confidence", "Current WD14 default: 0.85.", "number", [0.85])}
One home for database and media maintenance. Scanning is separate from changing or removing records.
${button("Run health checks", "health-check", "", "ca-primary")}
Database
${operation("Integrity & relationship checks", "Validate foreign keys, text hashes, pair uniqueness and image associations.", "health-check", "Check")}${operation("Duplicate prompt text", "Review canonical text reuse and dependency-safe merging.", "maintenance-plan", "Review plan", 'data-plan="duplicate prompts"')}${operation("Optimize database", "Reclaim unused SQLite space. This does not delete prompts or media.", "maintenance-plan", "Review plan", 'data-plan="database optimization"')}${operation("Unused prompt components", "Preview unreferenced components. Pair references and history remain protected.", "maintenance-plan", "Review plan", 'data-plan="unused prompt components"', true)}
Images & cache
${operation("Missing-file links", "Remove stale database links only. Files on disk are never deleted by this operation.", "maintenance-plan", "Review plan", 'data-plan="missing-file links"', true)}${operation("Duplicate image files", "Find matching file content, review groups and choose what to keep. Separate from duplicate prompt text.", "duplicates", "Find duplicates")}${operation("Thumbnail cache", "Generate missing thumbnails or explicitly rebuild all.", "thumbnail-review", "Review options")}${operation("Metadata cache", "Clear only Prompt Manager metadata cached by this browser.", "maintenance-plan", "Review plan", 'data-plan="browser metadata cache"')}`;
break;
case "backups":
body = `
Database backup
A complete recovery snapshot, including prompt pairs, metadata and image links. Media files are separate.
${setting("backup-before", "Create a safety backup before maintenance", "Preview a verified backup before applying operations that change records.")}${setting("backup-schedule", "Scheduled database backups", "Production feature proposal; backup storage must be configured first.", "select", ["Manual only", "Daily", "Weekly"])}
A restore would be staged, migrated and validated before replacing live data.
`;
break;
case "diagnostics":
body = `
Diagnostics
${button("Run checks", "health-check")}
Database
Healthy · sample status
Sources
2 configured · sample status
Viewer.js
1.15.2 · pinned vendor
Host renderers
Classic / Nodes 2.0
${button("Download sample diagnostic report", "diagnostic-export")}${operation("Image-link diagnostics", "Check a file-to-prompt association without changing it.", "metadata-demo", "Inspect sample")}
09:42:18 INFO Scan completed: 12 enriched, 0 duplicate links\n09:42:18 WARNING 3 images have ambiguous prompt metadata\n09:39:04 INFO Database backup verified\n09:38:52 INFO Source monitor started: output
${setting("runtime-level", "Runtime log level", "One control replaces a separate gallery debug toggle.", "select", ["INFO", "WARNING", "DEBUG", "ERROR"])}${setting("console-log", "Console logging", "Keep routine browser and server output quiet unless requested.")}Log files & retention
prompt_manager.log · 1.4 MB · rotated copies: 3
${button("Review log cleanup", "maintenance-plan", 'data-plan="rotated logs"')}`;
break;
}
$("main").innerHTML =
heading(
"System",
"Configuration, maintenance and recovery—with browsing kept in the workspace.",
'Sample configuration',
) +
sectionNav(systemSections, state.system, "system-tab") +
`
${body}
${state.settingsDirty ? "Unsaved changes in this prototype" : "Changes apply to this browser tab only."}${button("Save preferences", "save-settings", "", "ca-primary")}
${button("Leave for later", "go-images")}${button("Apply sample association", "resolve-review", "", "ca-primary")}
`;
}
const featureMap = [
[
"Admin prompt cards / per-prompt gallery",
"Prompt library + one prompt history workspace",
"Retained, rebuilt",
],
[
"Standalone image gallery / Admin image modal",
"One Images workspace + shared Viewer.js viewer",
"Consolidated",
],
[
"Video playback, autoplay / mute / loop, viewer slideshow and transforms",
"Shared media viewer; playback controls in Appearance; same image navigation",
"Retained",
],
[
"Metadata page / viewer sidebar / full-text popups",
"One reusable metadata inspector; inline complete prompt text",
"Consolidated",
],
[
"Prompt add, edit, rating, notes, copy, delete",
"Recipe editor, shared details, contextual bulk actions; reference-safe archive",
"Retained, clarified",
],
[
"Categories, tag rename / merge, autocomplete",
"Tags & categories; same vocabulary in every editor",
"Retained",
],
[
"Grid/list, thumbnail size, columns, pages/infinite scroll",
"One Appearance configuration; contextual layout / density overrides",
"Simplified",
],
[
"Scan, rescan, monitoring directories, worker threads",
"Sources & scans; explicit metadata enrichment vs thumbnail work",
"Consolidated",
],
[
"Ollama, HuggingFace, WD14 variants, thresholds, review",
"One Auto-tagging configuration and review flow",
"Retained",
],
[
"Thumbnail quality, size limit, metadata cache, paths",
"Appearance + cache controls in Maintenance",
"Retained",
],
[
"Prompt dedup, hash checks, consistency, unused prompts",
"Maintenance plan with dependency checks and impact preview",
"Retained, safer flow",
],
[
"Image dedup, orphan image links, browser cache",
"Separate reviewed operations in Maintenance",
"Retained",
],
[
"Database backup / restore, JSON export",
"Backup & export; recovery and portable recipes clearly distinguished",
"Retained",
],
[
"Diagnostics, image-link checks, logs, rotation, log levels",
"System → Diagnostics & logs",
"Retained",
],
[
"LoRA detection/import, trigger injection, CivitAI key",
"System → Integrations; positive-only triggers",
"Retained",
],
[
"Statistics / counts",
"System overview + usage breakdown; context counts in the workspace",
"Retained",
],
[
"Send prompts to ComfyUI from every prompt surface",
"Role-aware paper-plane action + destination / overwrite preview",
"New proposal",
],
[
"Reusable negatives / approved branch timeline",
"Prompt history with selected negative directly beneath positive",
"Approved concept",
],
[
"Favorites, saved searches, project collections",
"Sidebar views; collections do not duplicate recipe text",
"New proposal",
],
[
"Ambiguous metadata review, source provenance, run comparisons",
"Needs review queue; recorded vs inferred evidence; pair/run selection",
"New / expanded",
],
[
"Unified jobs, cancellation, resumable progress visibility",
"Activity center; cancellation distinguished from hiding progress",
"New proposal",
],
[
"Scheduled backups, pre-change safety snapshots",
"Explicit recovery policy after storage configuration",
"New proposal",
],
];
function renderDesign() {
$("main").innerHTML =
heading(
"A workspace for the whole prompt lifecycle",
"Design review · current functionality mapped to its proposed home",
) +
`
Discover an image. Understand its recipe. Compare an experiment. Send exactly the text you want back to ComfyUI. The same controls, vocabulary and inspector follow that journey.
This is an interactive proposal, not a production migration. All data is illustrative. Existing backend routes, node schemas and vendored libraries remain unchanged. The approved timeline is preserved alongside this new concept.
One original, simple paper-plane outline in ComfyUI blue. A role-labelled action on every displayed positive or negative, plus a pair action. The picker previews the target node and changed fields. Sending does not queue a generation or load an entire workflow.
What deserves adding
Saved searches, project collections, metadata review, an activity center and explicit recovery plans. A favorites toggle is separate from the existing 1–5 quality rating. These are proposals to evaluate, not promised features.
Feature inventory & redesign map
Today
Proposed home / behavior
Disposition
${featureMap.map((row) => `
${row.map((text) => `
${text}
`).join("")}
`).join("")}
Implementation boundaries
Keep Viewer.js 1.15.2 and the shared ComfyAssets toolkit as pinned artifacts. This mock runs the actual vendored viewer. Production work should reuse controllers and services, replace overlapping UI shells, and preserve the existing test matrix.
New services would be needed for persisted execution history, saved searches/collections, job history and the ComfyUI send bridge. The bridge must detect disconnected tabs, reject incompatible or linked target inputs, and never guess a positive/negative destination. Unknown metadata remains unknown; an explicitly empty negative is a deliberate value.
The maintained node layouts are out of scope for this application rebuild. Each implementation slice needs regressions first, page workflows, and relevant Classic / Nodes 2.0 host tests. No test or coverage gate is removed.
`;
}
function openSend(p, role = "pair", variant = 0) {
clearInterval(slideTimer);
slideTimer = null;
sendPayload = { p, role, variant };
dialog(
"Send to ComfyUI",
`
Prototype: destinations are illustrative. Nothing will be sent to your running ComfyUI.
${role === "pair" ? "Both prompt fields will be replaced together." : `Only ${role} text will change. The other prompt stays untouched.`} Connected inputs would be checked before applying.
Image inspection, output scanning and recipe import have different effects. Choose the workflow you want.
${operation("Inspect a local image", "Read embedded metadata before deciding to add it.", "inspect-file", "Open inspector")}${operation("Scan an output folder", "Discover and enrich existing files using the configured sources.", "scan-review", "Review scan")}${operation("Import portable recipes", "Proposed: preview conflicts and reuse existing text before applying.", "sample-import", "Preview sample")}