SOF-8024: workflow designer UX — review, plan, and portions 1, 3, 6 (plus 4 and 5 started) - #12
Open
timurbazhirov wants to merge 36 commits into
Open
SOF-8024: workflow designer UX — review, plan, and portions 1, 3, 6 (plus 4 and 5 started)#12timurbazhirov wants to merge 36 commits into
timurbazhirov wants to merge 36 commits into
Conversation
Same exercise as the materials-designer UX pass: current-state captures from the standalone demo, a W1-W12 issue inventory, five HTML mockups (shell relayout, Important Settings rebuild, add-unit palette and step library, input editor, labeled Compute form), quick wins, and phasing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Adds AGENTS.md from mat3ra/agents, introduces the plan/ folder per its section 6 conventions, and files a phased implementation plan for the UX review (quick wins, settings/editing depth, shell relayout) with per-item touchpoints, dependencies, and acceptance criteria. Updates branch references after the rename to claude/ux-improvements-msn5h2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Splits the single plan into a main overview (WFD-UX-0) and six portion documents, each independently executable and movable through the plan/ lifecycle. Adds a new design-language portion (WFD-UX-2) grounded in an audit of the current @mat3ra/cove theme: brand palette confirmation, semantic and designer-specific tokens (unit types, canvas, states), a real dark palette, typography roles, and adoption steps replacing the pinned legacy theme and hardcoded colors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
…dd LFS attributes Renames the plan set to sof-8024-ux-<n>-<title>.md per the Jira tracker SOF-8024, adds created/updated timestamps to each document, updates cross-links, and introduces .gitattributes tracking raster images with Git LFS. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
… note Public repositories reference a private tracker, so ticket keys move out of filenames into document headers and filenames carry the creation date instead (yyyy-mm-dd-short-title.md). Adds a docs/ux management section (self-contained mockups, LFS-tracked captures, refresh workflow) and syncs AGENTS.md with the updated conventions (LFS rule, docs/ux assets, plan naming). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
…ty state SOF-8024 portion 1, local items: - Label planewave cutoff fields (Wavefunction/Charge density cutoff) via provider field labels in importantSettingsFormUtils - Title the unit dialog with the unit name and type; stop showing the flowchartId in the dialog header - Replace instant unit/subworkflow deletion with snackbar-undo (10 s snapshot restore) at both workflow and subworkflow levels - Rename subworkflow tabs to Units / Settings / Outputs / Compute and render the units flowchart above the Details accordion - Label the compute override switch with behavior text - Track unsaved changes in the container (post-render baseline, reset on save), expose onDirtyChange, surface an Unsaved changes chip in the standalone demo Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
wove derives /images/brillouin_zone/<lattice>.png from the material and renders it via an injectable component, but that asset ships in no npm package — only the web app serves it — so every other consumer showed a broken image, and the absolute path cannot resolve under a non-root deployment base. The lattice type is already known there, so compute the zone instead: brillouinZoneGeometry builds the first Brillouin zone as the Wigner-Seitz cell of the reciprocal lattice, and BrillouinZone renders it as inline SVG. ImportantSettings uses it only as the default when no component is injected, so hosts with their own artwork are unaffected; unmodelled lattice types still fall back to the image. Validated against known crystallography: FCC gives a truncated octahedron, BCC a rhombic dodecahedron, CUB a cube, HEX a hexagonal prism, all closed (V - E + F = 2). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The lattice type alone underdetermines the cell: non-cubic systems have c/a and angle freedom, so the per-type table was standing in representative ratios. The context provider carries the material, so read its reciprocal vectors via made's ReciprocalLattice and build the zone from those instead — a graphene monolayer and bulk GaN are both HEX but now render with their real proportions. The per-type table remains only as a fallback for callers with no material. Records in the plan where this code should actually live: geometry in @mat3ra/made next to ReciprocalLattice, renderer in @mat3ra/move next to BrillouinZoneImage, with wove passing the lattice through instead of a type string and a dead image path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
This was referenced Aug 16, 2026
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The tab scientists touch most was a flat scroll of unlabelled forms: nothing said which unit a setting belonged to, whether it still held its default, or how to get back to that default, and finding one meant scrolling past the rest. Settings are now grouped into cards carrying a real title, the scope they apply to (whole subworkflow vs a named unit), a modified badge and a Reset control. A sticky index lists the units that carry settings with a count of how many are modified, and a filter matches titles, unit names, field names and engine keywords, so searching ecutwfc finds the planewave cutoffs. Reset reads defaults from the provider's schema where they are declared and falls back to getDefaultData(): providers try to publish defaults onto the schema through getPatchedSchemaById, but the patch addresses <field>.default while the schema keeps fields under properties.<field>, and esse skips paths it cannot resolve — so those defaults never land. Subworkflow-scoped panels keep the compact field styles; unit-scoped providers keep RJSF's labelled layout, as before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Field-level (1.3): a changed field now says what its default was and offers to put that one field back, via an RJSF FieldTemplate reading the provider's defaults through context. Resetting a field leaves the group's other edits alone, and the group's modified badge clears only once every field is back to its default. Compute (1.6): the tab restates the selection in the units people reason about — total cores, wall time, queue, cluster — instead of leaving nodes times cores-per-node to be multiplied by eye. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Adding to a workflow required knowing what you were adding. The unit picker listed the bare enum strings and hid their meaning behind an info popover; the header offered "Add subworkflow", which made an empty one, and "Paste subworkflow", a JSON textarea that failed silently on a typo. The unit picker now lists described cards — unitTypeCatalog.ts carries a one-line description, colour and glyph per type. "Add step" opens StepLibrary: the 76 standata subworkflows, searchable across step name, application and unit names, filtered by application, with a preview of the exact units to be inserted. Pasting JSON survives as the second tab and now reports parse errors. Adding an empty unit stays available. Search and entry shaping sit in stepLibraryEntries.ts so tests/stepLibrary.tests.ts covers them without a DOM. The demo's header stub renders the actions dropdown, so these flows are reachable outside the web app. Part of SOF-8024 portion 6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The generated array form gave a routine FCC path eleven identical point/steps rows — over 600px of form for one line of physics — while leaving two things unsaid: a point's `steps` describes the leg leaving it, so the last one is read by nobody, and nothing totalled the k-points the path costs, which is what sets the runtime. The path is now a chain of chips, Γ 10→ X 10→ W, with the count on each leg, insert on a leg, remove on a chip, and a line reading "10 legs · 101 k-points along the path". Points are chips rather than a select plus a bare ✕, because "Γ ✕ 10" reads as multiplication; the chip label keeps a minimum width so the delete icon does not own the spot a pointer lands on first. Bound through ui:field at the schema root, which also drops the schema's own title and "coordinates are derived at render time" note. Matched by schema shape, so q-path and i-path providers get the same editor. The path is also drawn inside the Brillouin zone and labelled at each high-symmetry point — what a per-lattice PNG could never do. BrillouinZone now exposes the projection it fits the solid with so the path lands in the same view, and the call site resolves point names through ReciprocalLattice.symmetryPoints, reading the path at render time so editing a leg redraws the picture. Labels are offset radially from the zone centre, since high-symmetry points sit in one irreducible wedge and a fixed offset stacks them. Also titles `ipath` and `igrid`, which had been rendering as "Ipath". Swept all 55 standata workflows: 12 show the chain editor, 8 draw the path, no new page errors. Editing rules are covered by tests/kPath.tests.ts. Part of SOF-8024 portion 3, item 1.5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The k/q/i-grid cards rendered "gridMetricValue" and "preferGridMetric" verbatim. PointsGridFormDataProvider does title them, but through a dependencies.gridMetricType .oneOf branch of its jsonSchemaPatchConfig, and esse's applyPatchWithDotNotation drops the whole dependencies key — verified directly against getPatchedSchemaById, which discards the sibling gridMetricType.default from the same patch config too. It is the same silent skip that hides the planewave cutoff defaults. withFieldTitles adds titles to named fields without disturbing the layout the unit-scoped forms rely on, so dimensions, shifts and the ratios get sentence case as well. preferGridMetric reads "Derive dimensions from the metric" rather than wode's intended "prefer KPPRA", because that is what setting it does: the dimensions are computed from the metric and their inputs go read-only. Part of SOF-8024 portion 3, which this completes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The classic layout gives four twelfths of the screen to a flowchart of the same steps
the right-hand panel already has open, so a three-step workflow needs a wide screen and
its name renders three times. The studio shell replaces that column with a rail that
says what each step is — "01 · CP-MD · espresso · 1 unit" — and hands the rest of the
width to the work. Status chips appear only when a step is not idle, so a workflow being
designed spends no pixels on job runtime state.
Rollout first: layoutVariant ("classic" | "studio") is plumbed from the container
through Workflow to the layout, defaulting to classic, so every host renders what it
renders today until it opts in; anything unrecognized resolves to classic rather than to
a broken layout. The demo gets a Layout selector, which is also how the two get compared.
To stop the shells drifting, the editing surface they share — validation alert, header,
and the subworkflow / map / error content — moved into WorkflowUnitPanel, rendered with
identical props by both. Classic was re-checked after the extraction and is unchanged.
Select, rename, remove and Add step all go through the container callbacks the classic
layout already used, so no new container surface. Not pinning the legacy theme, the
studio shell also picks up the ambient one.
Also fixes two defects in the step library from the previous commit, which rendered but
could never insert: standata stores a subworkflow's application as a bare {name} stub
while its units carry the full record, so wode's validation blanked the designer on
insert; and the position argument was inverted against UnitPaste's 0-append/1-prepend
convention, landing every insert before the current step.
Part of SOF-8024 portion 5, items 1.1 and 1.5.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Four LFS captures at 1440×900: classic vs studio layout, the rebuilt Settings tab with the k-path chain and the path drawn on the zone, and the step library. The review text gains an "After" table pointing at them, so a reader can compare against the original findings without running the demo. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
With the rail naming every step and switching between them, the panel header rendered the same name a third time, plus a step pager the rail makes redundant. SubworkflowHeader takes showStepIdentity, default true so the classic layout renders exactly what it did. The studio layout passes false and gets a compact header: the step's actions, and in the space the name freed, what the step actually computes with — espresso · DFT/GGA/PBE · pseudopotential/us, which nothing showed before. Part of SOF-8024 portion 5, item 1.4. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The unit form showed a "Next" selector and, beside it, a disabled FlowchartId box holding the same value spelled as a UUID — half the width of the form spent restating the field next to it. UnitPointerField takes showFlowchartId, off by default. Pairs with ave#8, which moves the selector itself into an Advanced section so the dialog opens on the input template. Part of SOF-8024 portion 4, item 1.5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Portion 4 items 1.3 and 1.4 landed in ave#8. Notes what the plan got wrong about the
failure mode — nunjucks renders an unknown variable as the empty string, so a typo
leaves nothing to notice rather than a visible `{{ }}` — what the check deliberately
does not flag, and the one item not built: insertion at the cursor, which needs cove to
expose the editor's EditorView.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
They were written at the repo root to run the parser over every standata template and against injected typos; the results are recorded in the portion-4 plan document, and the scripts themselves do not belong in the tree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The audit in §1 claimed the light and dark palettes were identical. They are not — dark deliberately uses the lighter brand purple. The real defect was that the dark palette omitted the border, icon and unitTypes groups entirely, so keys cove declares on the palette were undefined in dark mode and three styled components threw on them. Contrast was also worse than §2 estimated: three of the four semantic contrastText values were unreadable on their own main, the worst at 1.49, hidden behind alpha that looks fine when read as a hex. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Two hardcoded colours were wrong on a dark canvas regardless of which brand palette wins, so they did not need the sign-off the rest of adoption waits on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Part of portion 5 item 1.2: cards state the engine and flavor they run, with the unit type's icon beside the accent. The edge "+" from the same item still needs the canvas work the portion owes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The zone labelled only the points the path goes through. For FCC, HEX, CUB, TET, BCC, TRI and ORC that happens to be all of them — the default path reaches every point made knows — so the gap was invisible on the common materials. It is not true lower down: rhombohedral misses L1 and P2, monoclinic four, base-centred monoclinic six. Those points existed, were selectable in the path editor, and appeared nowhere in the picture. Unvisited points now draw as small faint markers with quiet labels; the path's own stay solid and bold, so the picture answers both where the path goes and where it could. Checked across FCC silicon, HEX graphene and RHL sapphire: the first two show no extras, as expected, and sapphire shows exactly L1 and P2. Part of SOF-8024 portion 3, item 1.5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The GitHub Pages job only runs on `main`, so there is no way to try a branch before it merges. Netlify builds a URL per pull request once the repo is linked, and `netlify.toml` gives it the build without a token needing to live anywhere. Netlify serves the demo from the domain root while GitHub Pages serves it under /workflow-designer/, so vite's `base` reads VITE_BASE_PATH and keeps the Pages subpath as its default. Verified by building with VITE_BASE_PATH=/ and loading the bundle from a static server: assets resolve at the root, and the page renders the workflow tree, the renamed tabs, and the k-path drawn on the Brillouin zone with no console or request errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
✅ Deploy Preview for mat3ra-workflow-designer ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
The repo is already linked to the mat3ra-workflow-designer Netlify site, so the previous wording asking someone to link it was wrong; previews build per pull request at deploy-preview-<number>--mat3ra-workflow-designer.netlify.app. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Direction for separating the pure view capability (owned by wove) from the designer's load/edit/save: one graph model and measurement-free layout feeding a static SVG renderer, a read-only WorkflowViewer, and a steps list, with the designer re-based on the viewer plus injected actions. Covers the Jupyter story (SVG for saved notebooks, iframe viewer for live ones, shared golden fixtures against a Python layout mirror) and cuts the work into five portions across wove, this repo, and api-examples. Grounded in the current code: editable is a flag threaded through the full designer rather than a capability; the cards already read plain JSON fields; layout is the one DOM-coupled step (reactflow-measured sizes feeding d3). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The first draft was written without seeing wove#14, which had already built the JSON boundary (createWorkflowFromConfig, with a plain-JSON fallback when the wode entity rejects a config), the read-only WorkflowViewer, the window.renderWorkflow global on the wave.js contract, and the notebook recipe using the same helpers that embed wave.js. Planning a static-SVG foundation on top of that was proposing to redo settled work. What the plan now says instead: keep that interactive path as the default where JavaScript runs, and add the measurement-free layout underneath it so the same graph can also be drawn as static SVG — which is what makes a *saved* notebook show anything, since GitHub and nbviewer never execute the Javascript display the bundle arrives through. The notebook helper emits both as one mimebundle. Also records what wove#14 leaves open: the designer still mounts the whole designer to show a workflow, layout still needs a live DOM, there is no compact rendering for linear workflows, no size budget, and the config-rejected fallback only warns to a console nobody reads in a notebook. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Both were snapshots taken before agents#4, #5 and #6 merged, so this repo's agents were working without the section that matters most right now: §1.8.1, which says @mat3ra/* packages do not commit dist/ and that a not-yet-merged commit is consumed through a `[release]`-triggered wip-<sha> tarball rather than a hand-built one. That is the convention the rest of this branch was just brought in line with. Also picks up the Python docstring guidance and the plan/context durability split — tracked files are durable reference, `plan/context/session/` is gitignored working notes, hence the .gitignore entry. Nothing in the old copies was repo-specific; canonical was strictly newer in every hunk, so both are taken wholesale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Two things made the picture hard to read. The projection yawed about y and put y on screen-vertical, but the lattice data puts the c axis along z — HEX's six-fold axis is [0,0,1.6], TET's long axis is [0,0,1.4]. So every uniaxial zone was drawn lying on its side: the hexagonal prism balanced on a corner rather than standing on its hexagon. Yaw now turns the zone about c, and c projects straight up. The faces were also all drawn, translucent, sorted far-to-near — so back faces showed through the front and a cube read as a wireframe with two possible orientations. The zone is convex, so the faces it can show are exactly those whose outward normal points at the viewer; the rest are now culled. The viewport fit still measures every face, so nothing shifts as faces turn away. Verified by rendering all fourteen lattice types, and end-to-end in the demo: Si (FCC) and Bi (HEX) both draw their k-path on a zone that now reads as a solid. Tests cover the invariants the change rests on — c vertical, depth growing toward the viewer, three distinct axis directions, outward normals, and exactly half the faces visible, which is what a centrosymmetric zone owes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The layout gave its two columns `md` and `lg` widths but no `xs`. A MUI Grid item with no breakpoint at or below the current one falls back to auto sizing, so under `md` (900px) the columns stopped filling the row and shrank to their content: the tabs and the flowchart sat in a ~470px column with empty space beside them, while the subworkflow list above still spanned the full width. Measured before and after at six viewport widths; the right column now tracks the viewport (800px viewport → 800px column, was 468px) and the 4/8 split above 1200px is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Clicking Edit under Outputs → unit → Properties unmounted the whole page. `buildNamedEntitySchema` points `items` at `#/definitions/Property` but omits the `definitions` block entirely when handed nothing to choose from, so for an executable that declares no results RJSF got a dangling `$ref`, threw "Could not find a definition for #/definitions/Property" during render, and — with nothing catching it — React tore down the tree. The schema is now checked before a form is built from it: `isSchemaResolvable` walks it for local `$ref`s that no definition answers, and `buildUnitPropertiesSchema` returns null rather than something RJSF will throw on. With no properties to choose from there was never a form worth offering, so the panel says that instead of showing an Edit button that breaks the page. A `RenderErrorBoundary` around the form is the second layer: schemas here come from application registries and user JSON, so the panel that fails should be the only thing lost. Note the demo has no executable declaring results, so the boundary is defence-in-depth that its data cannot exercise; the schema check that actually fixes the reported crash is covered by tests. Verified across all 57 standata workflows: Edit no longer appears where it would break, and no click blanks the page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Three things were working against the path, which is the whole point of the picture. It rendered in `secondary.main` — a mid grey in this theme, and the least visible thing on screen. Measured against every ground it crosses (the halo under it, the page, and the faces at the <=0.5 opacity they drop to whenever a path is drawn), grey bottoms out at 1.87:1. No single colour clears 3:1 on both light and dark, so the path now follows the theme the way the edge colour already does: #8d3200 on light (worst 3.30), #f5a623 on dark (worst 4.45). Labels sat on top of each other. High-symmetry points crowd into one irreducible wedge — a base-centred monoclinic lattice puts seventeen of them in a corner — so a radial offset alone still stacked them. They are now separated in the plane, path and unvisited points together since they share that wedge, each staying within 14 units of its own marker so it remains attributable. The drawing was a fixed 240px inside a 655px panel; it now scales to the width it is given, up to 420px, which is where the room to separate comes from. Also stops cropping: the viewport was fit to the zone's faces, so a marker outside them was silently clipped at the edge. The window now widens to hold whatever is drawn. That matters because points *do* land outside the zone for the monoclinic lattices (MCL 3 of 18, MCLC 10 of 21; FCC, HEX, RHL and TET have none), which is not physically expected and wants showing, not hiding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket: SOF-8024.
A UX review of the workflow designer, an implementation plan cut into six portions, and the portions that are built. Everything was verified in the standalone demo with Playwright rather than by inspection; each portion document carries its own Status section with what was found and what is still open.
Review and plan
docs/ux/README.md— the review: twelve findings (W1–W12), quick-win table, and an After section pointing at captures of what is now built.docs/ux/mockups.html— self-contained interactive mockups A–E.plan/upcoming/2026-08-16-ux-0-overview.md— the main plan document, with a §0 progress table; one detailed document per portion.AGENTS.md— imported conventions, plus local sections on Git LFS and on managingdocs/uxassets.What is built
Portion 1 — quick wins. All ten, here and in wove#12: field labels, undo on removals, tab renames (Units / Settings / Outputs / Compute), dirty tracking, humanized property names, a zoom floor so nodes stay readable.
Portion 3 — Settings tab. Complete. Scoped cards per provider with a "modified" badge and per-group Reset, a sticky unit index with per-unit modified counts, a filter matching titles, unit names, field names and engine keywords (
ecutwfcfinds Planewave Cutoffs), per-field "default X · reset field", and a compute summary reading "Requests N cores · up to T · queue Q · on<cluster>".The k-path is now a chain of chips —
Γ 10→ X 10→ W— instead of eleven identical rows, with the leg count and the k-point total the array form never showed. The path is drawn inside the Brillouin zone, labelled at each high-symmetry point, and redraws as you edit it.Portion 6 — add flows. "Add step" opens a library of the 76 standata subworkflows, searchable across step name, application and unit names, with a preview of the exact units to be inserted; pasting JSON survives as a second tab. The unit picker lists described cards instead of raw enum strings.
Portion 5 — shell (started).
layoutVariant: "classic" | "studio", defaulting toclassic, so every host renders what it renders today until it opts in. The studio shell replaces the duplicated flowchart column with a steps rail (01 · CP-MD · espresso · 1 unit) and stops the panel header repeating the name the rail carries. The shared editing surface moved intoWorkflowUnitPanelso the two shells cannot drift.Portion 4 — input editor (started). The redundant
FlowchartIdbox is gone; ave#8 movesNextinto an Advanced section so the dialog opens on the input template.Bugs found and fixed along the way
/images/brillouin_zone/<lattice>.png, an asset no package ships, at an absolute path that cannot resolve under a non-root base. Fixed by computing the zone from the material's own reciprocal lattice — validated against known polyhedra, and correct where a per-type PNG is not (a graphene monolayer and bulk GaN are both HEX with very different zones).applyPatchWithDotNotationsilently skips patch paths it cannot resolve, soPlanewaveCutoffDataManager's 40/200 and the wholedependenciesblock ofPointsGridFormDataProviderare dropped. Worked around locally; worth fixing in wode.{name}stub while its units carry the full record, so wode's validation blanked the designer; and the position argument was inverted againstUnitPaste's convention.ipathandexplicitKPath2PIBA) — fixed in wove#12.Unrelated and pre-existing: selecting "Valence Band Offset (2D)" blanks the demo with
(unknown path), reproduced with these changes stashed.What is not built
Portion 2 (design language) is not started: its token definition is unblocked, but adoption waits on confirming the canonical brand palette with design/marketing — the platform says purple
#7c5fcd, the marketing site leans dark-navy + green, andsuccess #72E128fails WCAG AA on white regardless. Portion 5's canvas and inspector, and portion 4's render check and variables panel, remain; both need releasedwove/ave.Upstream
made#295 · move#5 · wove#12 · ave#8 · agents#3
Once made and move land, this repo drops its local copy of the zone geometry and renderer.