Files
ComfyAssets-ComfyUI_PromptM…/docs/application-redesign.md
T
Vito e29ff4d4b2 feat(inspect): the Inspect page for local files (#280)
* feat(inspect): local adapter seams in the shared inspector and viewer

The inspection loader calls adapter.read when an adapter reads by itself, so a
file chosen in this browser never reaches the API. The full inspector shows the
D66 local provenance (no Path row, no Show in folder, local association line),
and the viewer uses adapter.mediaUrl exactly, so a blob: URL is never given the
_pm_viewer cache-buster and Retry media reuses it. Rooted and recorded-history
adapters keep their api.get paths and cache-busted originals.

* feat(inspect): owned local selection session

createLocalSession owns one chosen File at a time: it classifies the bytes,
creates the blob: URL only for a classified image or video, and reads it
through a real inspection controller with the local adapter. Replacement,
dispose, parent abort and pagehide each release the URL, the handle and the
record once; a released handle (and every copy) is foreign to the adapter, and
every await is fenced by a generation counter so a replaced read never
publishes. Empty, multiple and directory drops keep the previous selection.
Baseline entry for local-session.mjs; branch floors raised for the touched
inspection-state.mjs and local-inspection.mjs.

* feat(inspect): native Inspect a file page

#/inspect is now the concept's "Inspect a file" page instead of the legacy
handoff. One chosen or dropped image or video previews inline, and the one
heading action, "Open file metadata", opens the shared viewer with the full
inspector on a record read entirely in this browser. Nothing is uploaded,
imported or stored; only an explicit Send crosses the host bridge.

- inspect.mjs mounts the concept DOM (surface, file-drop, #local-preview)
  under the shell heading, owns one local session and the shared viewer and
  prompt sender, and releases media before the session revokes its URL on
  replacement, route change, page leave and dispose (D60-D65).
- A file that cannot be read after choosing opens the inspector's
  unreadable state when the browser declares a supported type, instead of
  the "unsupported" copy; the local adapter maps a browser read failure to
  an unreadable record.
- The route is native; Overview keeps its card to the legacy metadata page,
  which is unchanged.
- workspace-inspect.spec.mjs covers the chooser and viewer rail against the
  Images rail for the same bytes, drop, cancel and reselect, unsupported and
  unreadable files, video, URL ownership, mid-read replacement, exact send
  and the no-request/no-storage rule.

* test(inspect): concept parity and managed-host send for local files

Compare the native Inspect a file page with the immutable concept's
#metadata at 1600x1100 and 390x844 in both themes (initial, selected,
viewer-open), mapping D60-D66 and pinning the concept's CSS values and
the chooser's displayed file name, with a mutation check. Send a local
PNG (explicitly empty negative) and core-tags.webm to a real Prompt
Manager (+/-) node across Classic and Nodes 2.0 switches and reloads;
a connected input rejects the send unchanged. Document D60-D66, the
legacy-floor dispositions and the commands in TESTING.md.

* fix(inspect): reset a released preview video in the next task

On WebKit (GStreamer) a video replaced while its pipeline was still
starting blocked the page: pause, src removal and load() in one task
never returned, so the next chooser selection hung (CI page workflows
webkit shard 2/2, "URLs and media end with their owning session").
The src is still dropped before the URL is revoked; only the load()
reset moves to the next task. A fresh-page regression replaces the
first video as soon as it shows, fifteen times.

* fix(inspect): never reset a preview video that is still starting

Deferring load() to the next task was not enough: CI on b7db4c3 hung
WebKit one step later in the fresh-page regression. Reset with load()
only a settled video (metadata read, or failed); a starting one is
paused, loses its src before the URL is revoked and is removed, then
left to be collected. The ownership workflow waits for the video to
settle before asserting the reset.

* fix(inspect): final review round for the local Inspect page

- Each inline preview owns its listeners, so a released node is never
  pinned; a video released while still starting is reset with load()
  once it reports metadata or an error (I1).
- The viewer's video teardown on a just-started local video is guarded
  by a 15-page WebKit test; it needed no change (I2).
- The chooser keeps naming the current file after a cancelled picker
  and names the dropped file after an accepted drop (I3).
- The unrelated activity-scan.mjs floor raise is reverted (I4).
- The page owns pagehide: the viewer closes and the inline media goes
  before the session revokes the URL, and the chooser is cleared (M1,
  M2); the session gains clear() and the viewer close().
- The "metadata is available" toast shows only for readable metadata
  (M3); a rejected drop is a second, transient alert that never
  replaces the selection's status (M4).
- TESTING.md: D62/D63 updates, the WebKit loadstart follow-up and the
  pair-node follow-up (M5).
2026-10-22 16:06:07 -07:00

8.5 KiB
Raw Blame History

Application Redesign Development Plan

The maintainer approved the interactive concept on 2026-10-17. It is a design reference with simulated operations, not production code. This plan proposes implementation order and acceptance gates.

Delivery status

  • Foundation merged in #198.
  • #200 delivers native Images browsing, physical-file details, infinite scroll, Grid/List/Masonry, Viewer.js and video playback. The workspace opens on Images; original application entry points remain available.
  • Shared role-aware sending and the physical-file prompt inspector merged in #203 and #206.
  • The native Prompt Library merged in #210 for #208: one positive parent, saved negative variants, full selected text and a shared filtered image gallery. It does not invent chronological runs from counters or scan dates.
  • Durable history storage records job attempts and outcomes from #212, frozen prompt contexts from #213, and observed run-owned output locators from #214. Those locators do not verify file bytes or establish gallery-image associations. That association contract and the chronological execution timeline remain pending under #209.
  • #215 brings the shell, Images and natural-height Prompt Library presentation into the approved geometry and themes while retaining their existing operations. #216 adds the shared current-file inspector with exact generation facts, scoped provenance, raw/download evidence and loaded-collection viewer controls, including a slideshow that pauses at native video. This delivery does not establish whole-application parity, change the default entry point or constitute a release. Recorded chronological run/context browsing continues under #209; image tagging/review, System consolidation and remaining organization capabilities continue under #196.
  • Local Inspect (#249, PRs L1–L2) replaces the #/inspect handoff with the concept's native "Inspect a file" page: one local image or video previews inline and opens the shared viewer and full inspector on a record read entirely in the browser, with nothing uploaded, imported or stored. The legacy metadata page (web/metadata.html, served at /prompt_manager/gallery.html) stays reachable from Overview; its capabilities map to the shared inspector, except its one-click COPY ALL summary, whose ruled replacement ("Copy settings summary") is pending. Recorded deviations D60–D66 are in TESTING.md. Local roles equal to the server's resolver follow in PR L3.

Scope and compatibility

Rebuild the standalone application around one shared shell. Preserve existing node schemas, saved workflows, backend capabilities, pinned Viewer.js and the ComfyAssets toolkit. Keep existing application entry points usable during the transition. Do not change the running maintainer instance during automated tests.

Use the concept's feature inventory as a parity checklist. Each row needs an implementation issue, observable acceptance criteria and automated test coverage. Record any intentional behavior change explicitly; no silent feature removal.

Proposed delivery sequence

Use a tracking issue and small issue-linked branches and PRs. Dependencies may require splitting these milestones further.

Milestone Deliverable and acceptance focus
1. Foundation Production shell, routing, shared theme and disposable page-test harness. Verify startup, navigation, dark/light changes, cleanup and existing entry points. Establish discovered-test and coverage baselines before changes.
2. Image workspace Real API-backed filters, Grid/List/Masonry, readable thumbnails, selection and shared Viewer.js inspector. Continuous infinite scroll only, with accessible Load more fallback, stable ordering, retry and restored browsing context. Bound retained DOM and test large datasets.
3. Prompt library and history Real positive/negative associations, selected full negative, run history and shared image filtering. Design any missing execution-history persistence and migration before wiring the timeline; never invent historical runs from incomplete metadata.
4. Send to ComfyUI Shared paper-plane actions wherever prompt text appears; role-specific and pair sends, destination preview, acknowledgement and failure recovery. Cover explicit empty versus unknown negatives and connected inputs. Never queue or replace a workflow.
5. Editing and review Prompt editing, vocabulary management, per-image manual/auto-tag approval and Needs review. Preserve cancellation semantics and distinguish tag approval from prompt-association decisions.
6. System and maintenance Settings, sources/scans, integrations, jobs, diagnostics, backup/restore and maintenance impact previews. Cover existing capabilities before retiring their old controls.
7. Additional organization Favorites independent of ratings, collections, saved views, Activity, scheduled backups and portable import previews. Specify persistence, validation and recovery separately for each capability.
8. Cutover Complete the parity checklist, migration and upgrade validation, accessibility/performance checks, documentation and targeted maintainer live testing. Switch the default only after these pass; preserve compatible URLs.

TDD and test layers

For each behavior, first write and run a meaningful failing test. Implement the smallest working change, verify it passes, then refactor with the suite green. Include failing-before/passing-after evidence in the PR.

  • Unit: filtering and selection state, cursor handling, prompt roles, formatting, validation, navigation and lifecycle cleanup.
  • Integration: real HTTP handlers and disposable SQLite/filesystem fixtures; persistence, migration from supported old schemas, idempotent scans, restore, rollback and reference-safe deletion. Mock inference and external services.
  • Smoke: shipped production pages start and navigate with real fixture APIs; test populated, empty and error states, assets and unexpected console failures.
  • Browser workflows: production HTML/JS across Chromium, Firefox, WebKit and touch; editing/reload, infinite append, viewer cleanup, tagging approval, keyboard access, delayed responses, cancellation and retries.
  • Host integration: pinned disposable CPU ComfyUI, Classic and Nodes 2.0, switching both ways and workflow reload for host-facing changes. Exercise independent and combined pack installations for shared bridge/toolkit changes.

Retain existing test discovery and coverage gates. Carry forward database injection and open-handle checks into new fixtures. Add new frontend modules to coverage measurement and its baseline; do not lower floors or replace existing regression coverage with mockup-only tests.

GitHub and release gates

Extend existing required workflows: the Python 3.10–3.13 matrix on Linux, Windows and macOS; 85% Python coverage; formatting; frontend units and per-file coverage floors; vendor checks; browser workflows; real ComfyUI compatibility. Publish traces, screenshots, logs and coverage artifacts on failures. See TESTING.md for commands and fixture isolation requirements.

Every PR must map acceptance criteria to tests, report relevant checks and include screenshots for visual changes. All required checks must pass before merging. Use maintainer live review at meaningful visual and host-integration milestones; capture discovered regressions in automated tests. Notify the maintainer when Python changes require a ComfyUI restart.

Keep version/publication changes separate from intermediate UI work: the existing registry workflow publishes on main/master changes to pyproject.toml or manual dispatch. Do not trigger a release merely to preview a redesign milestone.