Commit Graph
14 Commits
Author SHA1 Message Date
Vito 9d398f9862 feat(workspace): concept shell — sidebar, topbar, heading and footer on the approved mock's CSS (#256)
* build(workspace): vendor the approved concept stylesheet with a drift check

* refactor(workspace): adopt the concept stylesheet as the workspace base

* feat(workspace): concept sidebar with real navigation counts

* feat(workspace): concept topbar with Theme and ComfyUI link

* refactor(workspace): one concept heading and footer for every route

* fix(workspace): keep the canvas link on the proxy mount

A resolver failure no longer stops the shell from mounting: the ComfyUI link falls back to the root read from the page's own mount path (never another origin). Tests cover a non-standard /ComfyBackendDirect mount, including that no request escapes it.

* test(workspace): concept fixture and shell comparison

* test(workspace): concept fixture carries the concept inspector facts

* fix(workspace): match the concept brand name and compare shell hover states

* test(workspace): shell comparison mutation check and docs

Add mutate() to the shared concept inventory and a shell mutation check: a
nav-row min-height rule and a removed .breadcrumbs each make the comparison
fail with the changed path. Harden the resolver-failure guard test with an
injection count, make the overlay lint fail when workspace.css is missing,
mark the library.css .row-actions leftovers for PR E, and document the
concept CSS base, the overlay lint, the comparison method and the recorded
shell deviations in TESTING.md.

* fix(workspace): focus the page title on a route change

A sidebar or history navigation now focuses #page-title, as the concept
does on every hashchange (app.js 1168), so a screen reader announces the
page heading instead of the main region. The first render leaves focus
alone and the skip link still focuses main. The heading module's comment
now describes what the shell does.

* fix(workspace): give the Overview nav entry its own home glyph

Overview reused the concept's Activity pulse byte for byte, so once the
Activity row lands two entries would share one icon. Overview now has an
outline home glyph. The shell comparison takes it from the D28 ruling
instead of the concept's activity path, and the icon test checks that
every approved glyph is distinct.

* test(workspace): accept only #249 decision markers and state the lint scope

The overlay lint accepted any D-number, so another issue's ruling such
as "D5 (#245)" could mark a concept override. A marker now has to be a
D-number with no other issue cited; the vocabulary rule that cited #245
reads "#245 decision 5". TESTING.md now states that the lint covers
workspace.css only, lists the unmarked overrides still in images.css,
and says PRs C and D run the lint over each page sheet they keep.

* perf(workspace): re-read only Library and Tags counts after a Library write

A confirmed Library or vocabulary write cannot change the Images count,
but it re-read all three, including the Images output listing. It now
re-reads only the Library and Tags counts. Each count has its own read,
so a write never cancels an Images read that is still in flight.
2026-10-19 23:04:40 -07:00
Vito cbf46a7573 feat(vocabulary): native Tags & categories screen (#245)
* feat(vocabulary): add workspace vocabulary state

* feat(vocabulary): render the native Tags & categories screen

* feat(vocabulary): add guarded vocabulary dialogs

* fix(vocabulary): recover unconfirmed deletes and list every category in Manage

* refactor(vocabulary): use the shared plural helper

* test(vocabulary): compare the native screen with the approved concept

* fix(vocabulary): wrap long tag names so row actions stay visible on narrow screens

* docs(vocabulary): document the native vocabulary screen and gates

Also aligns the shell link focus-ring offset with the concept (3px) and makes
the chrome comparison poll the document title.

* fix(vocabulary): refresh lists when a write lands after its dialog closes

A rename, delete, create or category apply that commits after its dialog
was disposed (Chromium force-closing the modal on a repeated Escape, or
Back while the write is in flight) returned before onInvalidate, so the
lists were never re-read and a cached Library shelf kept showing the old
names. Like the recipe editor, a disposed command now still reports any
outcome that may have changed storage (receipt, conflict, restore,
unconfirmed) without rendering; only a failed write stays silent.

* fix(vocabulary): give the Manage categories datalist its own id

The proposed-name datalist reused the recipe editor's `categories` id. It was safe only because routes dispose each other's dialogs; it is now `vocabulary-category-options`.

* docs(vocabulary): correct vocabulary testing notes

Name the Tag column and the Create tag heading action, say that a failed Load more moves focus to Retry, place bulk actions on the admin page, describe late writes after a closed dialog, Browse's exact filter and the full deviation list, and use a test port that is not the live concept server's.

* test(vocabulary): raise the vocabulary dialog branch floor

coverage:update after the late-write and datalist fixes: workspace/vocabulary-dialog.mjs branches 87 -> 88. No floor is lowered.

* fix(vocabulary): keep 390px row actions visible regardless of font metrics

The one-column Tags table reserved a fixed 6em for the tag name. With
CI's stock DejaVu Sans fallback (about 9% wider than the pinned image's)
Tag + Prompts + Images + stacked actions needed 351px of a 336px wrap,
so Browse and Rename / merge were pushed out of view on every row.

At 700px and below the Tag column now has no fixed minimum and the
actions ask for no more than their stacked width, so all remaining space
goes to the tag name: short names stay on one line wherever the
concept's own table fits, and a wider font wraps the name instead of
clipping an action. A new test widens the metrics with letter spacing
and fails without this change in every engine.

* ci: run browser jobs in the pinned Playwright image

Concept comparisons measure geometry, which follows the fonts a browser
falls back to. The concept names Inter, which neither environment ships:
the pinned image falls back to WenQuanYi Zen Hei, a stock ubuntu-latest
runner to DejaVu Sans. Under DejaVu the concept's own Tags table needs
more than a 390px viewport (its page scrolls sideways and, under touch
emulation, the widened layout viewport resizes its dialogs), so the
390px comparisons failed in CI while passing locally.

Both browser jobs now run in mcr.microsoft.com/playwright:v1.64.1-noble,
the image local runs use, instead of installing browsers on the runner.
A tooling test keeps the tag equal to @playwright/test in the lockfile.

* fix(vocabulary): ignore a category preview edited while it is pending

Editing the Category or proposed name while a slow Preview was in flight
was a no-op in the saving phase, so the late response still became an
applicable preview: the form showed the new values while Apply would
submit the old source and target.

An edit during a pending preview now marks it stale. Its late result
returns the dialog to idle (Preview again) instead of showing an impact
or offering Apply; a plain failure of a stale preview is not shown
either, while a restore or conflict still is, since it describes
storage. The inputs stay editable during the request, as in the recipe
editor, which disables only its actions while saving.

* ci: use the image's Python and Node in containerized browser jobs

Inside mcr.microsoft.com/playwright:v1.64.1-noble, actions/setup-python
failed before any test ran: `spawn /__t/Python/3.12.15/x64/bin/pip
ENOENT`. The toolcache builds come from the runner, and their entry
points name host interpreter paths that do not exist in the container.

The jobs now use the image's Python 3.12 and Node 24. The image has no
ensurepip and the job runs as uid 1001 without root, so a checksum-pinned
pip wheel bootstraps a user-space venv for requirements-dev.txt; a step
checks that the image Node is 24. The tooling test forbids setup-python
and setup-node in these jobs and requires the pinned bootstrap.
2026-10-19 12:05:27 -07:00
Vito 8bcde4fbe4 feat(library): native recipe editor UI, pair archive browsing and export (#235)
* feat(library): manage native editor drafts and recovery

* fix(library): fence pair archive retries against restored storage

* feat(library): add native recipe editor dialogs

* fix(library): read archive counts through the editor controller

* feat(library): reconcile editor saves and archived pairs

Wire the concept's heading actions (Library Export and + New prompt, Images New prompt, history ← Prompt library, Edit metadata and pair Send to ComfyUI) and the Negative variants + Add negative and Show archived controls. Saves navigate or reconcile in place through createLibraryDetail.accept, invalidate cached shelf state by write generation, browse and restore archived pairs, and offer an explicit Library reload when storage was restored.

* fix(library): refresh archived pairs and align editor outcomes

* test(library): enforce approved native editor presentation

* test(library): verify editor host and coverage compatibility

Adds the rejected connected-target host assertion, pins the stock host listing at 80 cases, documents the native editor, and keeps Save/Archive focus after a failed write.

* docs(testing): correct host case totals and cover archive focus

* fix(library): fence editor reloads after restore and settle outcome copy
2026-10-19 01:46:33 -07:00
Vito ecd21165a7 feat(history): add chronological runs and exact output inspection (#227)
* feat(history): add bounded chronological read projections (#209)

* fix(history): validate internal continuation positions (#209)

* feat(history): expose fenced history windows and run details (#209)

* fix(history): release retired projection connections (#209)

* feat(history): resolve reported outputs through current authorization (#209)

* fix(history): reject invalid inspection targets (#209)

* feat(history): add scoped history state and current-file adapter (#209)

* fix(history): preserve slideshow and clear stale reentry actions (#209)

* feat(history): render recorded executions and frozen run details (#209)

* fix(history): recover receipts and refresh capture evidence (#209)

* test(history): verify chronological history across restore and host modes (#209)

* fix(history): enforce chronological marker visual parity (#209)

* fix(history): resolve final chronological review findings

Address #209 recovery, bounded visit restoration, exact receipt availability, and portable regression coverage.

* test(history): repair Windows fixtures and review feedback

Address #209 and PR #227 native path, cleanup, media and review-comment expectations. Document Windows portability preflight without changing production behavior.

* ci: raise the viewerjs job budget for the larger browser suite

The cross-browser workflows suite grew from 396 to 496 tests on this
branch, which pushed the whole viewerjs job to about 25.5 minutes
against the 25 minute cap set in #181. Two exact-head runs on this
branch timed out without any test failing: run 39173019283 was killed
on test 474 of 496, and run 39175125474 printed "496 passed (12.8m)"
and was then cancelled during Playwright shutdown.

Raise only the job budget. Browser projects, workers and per-test
timeouts are unchanged. Splitting the browsers into parallel jobs is
tracked separately.
2026-10-18 17:17:05 -07:00
Vito e7cfcc2bfb style(workspace): align browsing with the approved concept (#219)
* style(workspace): align approved shell and visual fixtures

* test(workflows): preserve evidence across browser projects

* style(workspace): match approved image browsing geometry

* style(workspace): match natural library card layout

* fix(workspace): retain wheel motion during row correction

* fix(workspace): contain zoomed controls and image metadata (#215)
2026-10-18 02:53:26 -07:00
Vito 4ef236aaf7 feat(history): persist exact run output references (#214)
* feat(history): define bounded output reference contracts

* feat(database): migrate execution output evidence to schema v3

* feat(history): persist immutable run output references

* test(history): isolate mocked node gallery monitor

* feat(history): capture bounded output descriptors with shared leases

* fix(history): authenticate payload owners and release failed captures

* feat(history): attach output evidence to exact finalized attempts

* test(history): verify run output evidence on real ComfyUI

* fix(history): release idle worker payload references

* docs(history): clarify defensive lease cleanup

* test(history): align output fixtures with native path styles

* test(history): separate restore completion from writer drain

* test(history): bound batch drains by progress and total time
2026-10-17 23:26:37 -07:00
Vito bae542c9ac feat(history): persist exact execution prompt contexts (#213)
* feat(history): define exact bounded execution contexts

* fix(history): retain observable sources and validate evidence

* feat(history): migrate execution contexts to schema v2

* feat(history): persist immutable execution context snapshots

* fix(history): preserve package identity for execution contexts

* feat(history): bound context payloads beside lifecycle finalization

* fix(history): fence context commits and resolve stored run identity

* fix(history): bound persisted identifier bytes before restore reads

* feat(history): bind exact runtime context to execution attempts

* test(history): discover owner invalidation callback regression

* feat(history): capture cached prompt strings without mutating host caches

* test(history): verify durable contexts on real ComfyUI hosts

* fix(history): scope transforms to captured source paths

* test(ci): update execution context tooling fixtures (#209)

* fix(history): harden context validation and worker fixtures (#209)

* fix(history): honor close deadlines after early joins (#209)
2026-10-17 19:51:22 -07:00
Vito 763e6b37b1 feat(history): record durable ComfyUI execution attempts (#212)
* feat(history): normalize bounded execution evidence (#209)

* fix(history): bound lifecycle kind checks before hashing (#209)

* feat(history): persist execution attempts with restore fencing (#209)

* test(api): bootstrap standalone backup restore fixtures (#209)

* feat(history): isolate bounded asynchronous ledger writes (#209)

* feat(history): observe actual queue attempts without altering execution (#209)

* fix(database): honor package-scoped configuration (#211)

* test(history): exercise real cached and headless executions (#209)

* fix(history): reject unsupported uniqueness and isolate package fixtures (#209)

* test(history): support Python 3.10 package fixture cleanup (#209)
2026-10-17 16:42:07 -07:00
Vito 76e9b51079 feat(bridge): add acknowledged ComfyUI prompt destinations (#203)
* feat(bridge): add guarded PromptManager prompt destinations

* fix(ci): install shared contracts before frontend unit tests

* test(comfyui): wait for paired editor resize before measuring layout
2026-10-17 13:14:02 -07:00
Vito a52ff4e052 feat(ui): add Focused Prompt Manager with shared autocomplete (#191)
* feat(ui): add Focused Prompt Manager node (#186)

* feat(ui): autocomplete saved Focused metadata with shared controls (#186)

* feat(ui): autocomplete Focused library filters (#186)
2026-10-17 05:31:24 -07:00
Vito 035e816db6 feat(ui): adopt shared toolkit for Prompt Manager Classic (#190)
* feat(ui): adopt shared toolkit for Prompt Manager Classic (#186)

* test(ui): retain Text node Web UI coverage alongside Classic

* fix(tooling): reject lookalike toolkit download URLs (#186)
2026-10-16 22:18:18 -07:00
Vito f98f6fa08d test(ci): validate shared toolkit in real PromptManager hosts (#189)
* test(ci): prove shared toolkit with real PromptManager host coverage

* test(ci): match KikoTools Python 3.13 compatibility coverage
2026-10-16 20:56:50 -07:00
Vito f1b1d4731b test: exercise real page workflows and enforce frontend coverage (#181) 2026-10-16 06:45:20 -07:00
Vito cf0cef3f25 feat: vendor Viewer.js reproducibly and automate release updates (#170)
Refs #169. Pin and verify pristine distribution assets, upgrade to 1.15.2, and add tested maintainer tooling plus desktop and touch browser checks.
2026-10-16 04:56:25 -07:00