46aeff92caa05e82c4366ddf32c8ddd290b9a49b
13
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2bda944581 | feat(inspect): explain why a prompt could not be resolved | ||
|
|
4de839e4e5 | feat(inspect): trace conditioning through supported pass-through and selector nodes | ||
|
|
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. |
||
|
|
048d599386 |
fix(inspect): bound inspection work, not graph size (#244)
* test(inspect): add synthetic inspection parity fixtures and legacy characterization * test(inspect): pin test-time parity vectors and keep fixtures fully synthetic * fix(inspect): bound resolver work instead of graph size * fix(inspect): bound shared-node and stripped-text work in the inspection profile Keep one memo per resolution whose entries carry their unfolded visit cost; a memo hit charges that cost to the current candidate's allowance only. Cache node validation and charge input keys, stripped characters and copied provenance entries to a whole-resolution work budget before doing the work. The default profile is unchanged. * fix(inspect): keep memoized depth honest across inspection candidates A memo entry now records its height below the reusing depth; a hit raises depth-limit exactly where a fresh walk would, so each candidate's outcome matches its anchored result and does not depend on trace or node order. The default profile is unchanged. * test(inspect): pin memo height propagation Three samplers share one chain, each later one hanging below a memo hit. The third candidate must report depth-limit in both trace orders and when anchored; removing the memo-hit height propagation fails this test. The provenance test now asserts a plain subset. * fix(inspect): tolerate ComfyUI node metadata quirks in projections Projections now take a kind. Each prompt node keeps exactly class_type and inputs; _meta, is_changed and other node keys are validated and dropped, so "is_changed": [NaN] no longer marks the whole prompt graph malformed. A nonfinite value inside inputs, anywhere in a workflow, or in a retained carrier member projects to null and is never reported as a number. The carrier applies the prompt/workflow kinds to its members. Exact numbers are unchanged (Decimal spelling, unsafe integers as strings) and duplicate keys are still malformed. The 500-node gate is replaced by a 20,000-node backstop (workflow count includes subgraph definitions). Raw records are untouched. The f14 inspection vector's facts become known; default vectors are unchanged. * fix(inspect): budget metadata per record so large workflows never hide prompts PNG inspection no longer counts every text chunk against one shared 2 MiB budget. Role records (prompt, parameters, the pair execution record) keep a 2 MiB budget together, encoded and decoded, and exceeding it still fails the whole read. A workflow has its own 4 MiB budget: a chunk over it is skipped by seek, and a compressed one stops inflating at budget + 1. Only the workflow is then reported as limited (record format "limited", no raw text, workflow_graph limited); prompts, facts and the prompt graph are unaffected. Each text chunk's keyword is read first (at most 80 bytes). Chunks that are not retained are skipped by length without being read or checksummed, so memory stays bounded. Byte-identical duplicates of a retained record are accepted and do not consume budget; differing duplicates still raise "Duplicate prompt metadata", and a duplicate of a limited workflow stays limited. The chunk-count limit is unchanged. InspectionRead gains limited_records (empty by default). The reader is only used by the inspection routes, so ingestion, scan and import are unchanged. Vectors: f04-inspection (2.5 MB workflow, within the new workflow budget) and f15-inspection (identical duplicate chunks) now read and resolve, with the same outcome and facts as f05-inspection. Default vectors are unchanged. * fix(inspect): keep prompt evidence longest under the response budget * fix(inspect): bound identical duplicate chunk reads * fix(inspect): fail closed when role duplicates exceed their budget * fix(inspect): use the bounded inspection profile end to end Inspection routes resolve with INSPECTION_PROFILE and expose reason_code and node on the resolution; scan, live monitor and admin import keep the default profile (pinned by spies over the real resolver on f03). JS facts drop the entries and workflow node-count gates; per-lookup visit sets and the server's node ceiling bound the work. The validator accepts the textless `limited` workflow format, follows the workflow-first response omission order, and checks the closed reason-code vocabulary. The file inspector labels limited records and disables their workflow download. vectors.json: 12 inspection vectors gain their reason codes; f03 facts become known and f01 facts ambiguous. Default vectors are unchanged. A new parity test asserts vectors.json facts through the workspace JS. * chore(tools): add read-only inspection corpus tool tools/inspection_corpus.py runs the inspection route pipeline and the workspace JS facts of a chosen code tree over a media folder, read-only, and reports the #240 invariants H1 to H8 with aggregate counts. Rows hold statuses and SHA-256 digests of resolved role texts, never file names or prompt text unless --with-paths is given. Outputs inside the root or a code tree are refused. The facts-over-vectors test now fails instead of skipping when CI is set and Node.js is missing. * docs(testing): document bounded inspection work * fix(tools): fail the corpus run when facts or inspection did not run Rows whose facts were never computed (no or exiting Node.js) now fail H3, and a new harness line fails on any tool exception or missing facts, so a run where nothing was measured can no longer exit 0. Unreadable files stay inspector outcomes. A missing --node binary is refused, an exited harness is reaped, H8 has a 50 ms floor for tiny baselines, and JSONL rows are sorted by id. * docs(inspect): correct ceiling wording and bandit annotations Describe the two 20,000-node ceilings (prompt entries, workflow UI plus subgraph nodes) in TESTING.md, and use bare nosec ids so Bandit stops warning about unparsed test names. * test(inspect): make parity observation tuples explicit |
||
|
|
44b6ed2420 |
fix(library): editor follow-ups after storage restore and history selection parity (#243)
* fix(library): close recipe editor follow-ups from the native editor slice - After restored storage, Create text revision and Archive are disabled so they cannot re-read an old numeric ID; only Reload Library remains. - The storage-changed exit in Edit, revision and Add negative states that Reload Library closes the dialog and discards the entries (the concept has no discard confirmation, so the copy stays inline). - When Save becomes disabled after an unconfirmed write or a conflict, focus moves to the recovery action instead of falling to the body; the archive confirmation does the same. - A reuse toast only says the entered parent metadata was not applied when the controller found it differs from the stored metadata. - Prompt history opens on its first negative variant, as the concept does, so the heading Send starts enabled. - "1 linked image" is singular on cards, variant lanes and the embedded gallery count. * fix(library): treat a blank category as equal to a stored uncategorized one A reuse that left the category blank sent "Uncategorized" and compared it with the stored NULL, so the toast claimed the entered metadata was not applied. Both sides now normalize blank and "Uncategorized" the same way before comparing; a genuinely different category still discloses it. * test(coverage): raise frontend coverage floors after editor follow-ups * fix(library): singular counts for one item and honest discard copy - One shared countOf/noun helper (web/js/workspace/plural.mjs) now words linked images, saved negative variants (card chip and history count), distinct recorded runs and the Images toolbar count in the singular for exactly one; every other count keeps its existing wording. - The restored-storage status says "Leaving this dialog discards your entries." because Cancel, the close button and Escape discard the draft too, not only Reload Library. - The new helper gets its coverage floor; no other floor changes. * fix(library): open every prompt history visit on its first negative The concept resets to the first negative variant on every navigation to a prompt (navigate: state.variant = 0) and selects another pair only right after a save names it. The history no longer remembers a clicked variant or an explicit All images choice across visits: the per-visit memory is replaced by a one-shot saved selection that the next history mount (or the same visit's reconciliation) consumes, and a verified pair outside the loaded page is kept only for that saved selection. Within a visit, clicks and All images behave as before. |
||
|
|
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 |
||
|
|
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. |
||
|
|
d9537a726c |
feat(workspace): complete shared inspector and collection viewer (#224)
* feat(inspector): expose bounded physical file evidence * fix(inspector): distinguish ambiguous saved associations * feat(inspector): derive conservative generation facts * fix(inspector): guard fact ancestry and inspection state * feat(inspector): share complete file details and exports * fix(inspector): preserve fact states and touch targets * feat(viewer): navigate the loaded media collection Refs #216 * fix(viewer): refit after current stage geometry changes Ref #216. Observe the current media stage after readiness and wrapped title changes without rebuilding focused controls or resetting transforms at unchanged dimensions. * feat(viewer): add lifecycle-safe slideshow and media preferences * fix(viewer): resume gallery continuation after close (#216) * fix(images): guard source recovery and wrap viewer actions Clear stale root and folder intent, cancel old pages, and wait for current source discovery before loading a refreshed collection. Preserve safe retry through failed, superseded, and disposed discovery. Wrap narrow viewer footer actions and wait for measured gallery viewport settling in responsive checks. Refs #216; addresses PR #224 review. * test(viewer): await gallery layout after viewport changes Require actual inner, root client, and document widths to agree after each responsive-case viewport and CSS zoom transition. Keep the existing exact frame, overflow, focus, and coarse target assertions unchanged. Observed PR #224 CI initial mobile resize at537px before pending card relayout settled to356px. Refs #216. |
||
|
|
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) |
||
|
|
fdba6fd012 |
feat(workspace): group saved negatives in the native Prompt Library (#210)
* feat(workspace): group saved negative variants in native library (#208) * fix(library): preserve full name order and batch previews (#208) |
||
|
|
dc345671ae |
feat(workspace): inspect and send positive and negative prompts (#206)
* feat(workspace): inspect and send positive and negative prompts * docs(workspace): capture complete inspector and viewer previews * docs(inspector): explain the subprocess cleanup race * fix(workspace): defer observed gallery layout writes (#207) * fix(inspector): keep path-only prompt associations unverified |
||
|
|
590aa2cd0e |
feat(workspace): add native Images browsing and infinite scroll (#201)
* feat(workspace): add native image browsing and continuous loading * test(workspace): assert empty collections through their status * fix(workspace): rescan refreshed images and expose ancestor folders |
||
|
|
d4bb5c5ba9 |
feat(ui): add the tested opt-in Prompt Manager workspace shell (#198)
* docs(ui): prototype unified prompt management application * docs(ui): add masonry and per-image tagging to application concept * docs(ui): make gallery concept use continuous infinite scrolling * feat(ui): introduce the tested application workspace shell * fix(docs): preserve concept controls across cached navigation * test(ci): emit Python tracebacks for native test crashes * test(ui): cover workspace restoration across cached navigation |