The context panel reads mesh.quality's reply as the counts (an area only for a surface mesh),
each metric's min, mean and max over its histogram (the bad end warm), and its worst element: a
click selects and frames it. Invalid and undetermined elements have a button that selects
and frames them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
file.new replaces the session with an empty one: no design, mesh, definitions, results or
journal, nothing to save, the undo history empty. The File menu and Cmd/Ctrl+N run it, asking
first over unsaved changes. A sample name the app does not know (a typo, an old ?sample= link)
opens the samples to choose from, and the status names it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
One formatter (four significant digits, thousands separators, round-off as
0) and the model's units through every results readout:
- legend title with its unit, a mode shape normalised; Max/Min with units,
clickable to show and probe the node; markers at both in the viewport
(#321, #330)
- the deformation scale field shows the scale Deformed would use, never 0,
in the shared format; true scale named (#325, #326)
- setup symbols off over results by default (Show › Loads & BCs), and then
only the shown step's (#327)
- reaction sums in the results panel however they are run: per set and in
all, force and moment with units, applied beside reacted (#328)
- the probe: U [mm], |U|, Mises, stresses and principals with units, the
label kept inside the viewport, rows in the results panel (#329)
- hiding the mesh over a plot hides the element edges, not the contours
(#317); a hidden body's contours go with it, the range follows what is
shown (#365)
- the solve summary: peaks with units, n/a rows left out, counts grouped,
internals under Details (#321, #319)
- the energies plot: axes with units, a cursor at the frame (click or drag
to move it), hover to read (#331)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
- Select: Vertices picks the design's B-rep vertices (meshed or not), and
a selected vertex is marked (#346).
- Use selection on Datum Point (vertex, edge, face, or a hole's centre)
and Reference Point (geometry.centre: a hole's centre, a vertex, nodes)
(#346, #351).
- Partitioned Mesh: Use selection takes the picked bodies as cells; the
cell list has All, None and Invert; hovering a cell's row (or its method
row) highlights the cell in the viewport (#344).
- Rigid Wall's form takes its set from the selection; the Interactions
branch lists the explicit steps' rigid walls, each opening its step
(#350).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
- A solve or a mesher runs as a job with one progress mechanism: the overlay
shows the step, stage, count and elapsed time with a bar when bounded, OK
waits while it runs, and the status sums it up (elements, smallest angle,
time) (#322, #357).
- Over the control channel such a command is a job too: answered when it
ends however long it runs, or at once with wait: false, then job.status,
job.wait, job.cancel; ui.inspect gives job; MCP waits for it (#367).
- A command that cannot run yet lists what it misses in the context panel,
each with a button to the command that provides it (#323).
- A cancelled or refused solve stays in its workspace (#324, test).
- A mesher form starts from the parameters of the mesh it would replace (#343).
- Seed Edges and edge/vertex/face datum points switch the selection filter
while open and restore it (#341).
- Datum forms draw the datum live, the Partition form shows its datum, and
new datums and partitions get the next free name (#347).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
- describe.rs: a definition's fields in its form's labels and units (sets by
members and what they resolve to), for the context panel.
- reply::done: status lines that say what changed ("Showing Load deformed",
"Mode 2: 1637 Hz", "Added material Al").
- The context panel puts the form and the selection above reports; opening
another document clears both; what a form makes is selected.
- Use selection reuses a set with the same members, otherwise names one made
on OK; Cancel leaves the model unchanged. The Target's set row is labelled.
- The browser's state marks sit in one column at its left edge; a right click
selects the row its menu acts on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Every half hour the page fetches its own address past the browser's cache; when it loads
another content-hashed build of the app than the running one, the status bar offers "Reload
to update" (the page's unsaved-changes question still guards the reload). Rust only, no
service worker: the browser build has no other update path and none of the desktop's
download code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The window checks at start-up at most once a day when automatic checks are on (Settings and
the first run's question), never while that question is open and never without a host, so the
browser and tests make no network call. A newer release shows a quiet notice in the status bar
("FieldCraft X is available — What's new · Install · Skip"); Install downloads and verifies
through the host, then asks to restart, saving or asking about unsaved changes first, and the
host swaps the release in after the window closes. A .deb/.rpm install offers the system's
installer and the command instead. Skip this version is kept in the preferences.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The first run asks whether to share anonymous usage (only when the host
says this run may), the answer and a random install id are kept in the
preferences, and Help › Settings… changes it. Commands are counted by
where they came from (ui, palette, script; mcp when the MCP server says
so), and cancelled forms and clicks on commands that cannot run yet are
recorded. The preferences go through a PrefsStore (a file, or the
browser's storage). Control channel: ui.settings, ui.prompt answers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
A datum plane is drawn as the model's extent within it (where it cuts the
model's box, in the plane's axes) plus a 5 % margin, a datum axis along the
model's extent plus the margin, instead of squares 1.2 diagonals wide.
Fit, Home, the standard views and headless pictures frame the model
without the datums (they stay inside the clipping radius). The datum
selected in the browser is drawn highlighted and on top, even when hidden.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The desktop app installs the crash reporter and a log file at start
(both in a temporary folder in --control and CI runs, #266), journals
the window's commands (background jobs included) and every control
request's method, and ends the journal on a clean exit. A start after a
crash asks: "FieldCraft closed unexpectedly", Report It… or Not Now.
Help › Report a Bug (also Tools › Help and ui.start
diagnostics.bug_report) shows exactly what the GitHub bug form will be
filled with: the version, the OS, the last error, and for a crash where
it happened. Share my session adds the replayable commands, Include the
model file the model. Open GitHub Issue opens the form in the browser
through the system's opener; files to attach are saved to
bug-reports/<time>/ and a long session goes on the clipboard. Nothing is
sent without that click and the user's submit on GitHub.
The control channel answers the new prompts (crashed: report, close;
report_bug: set, close) and ui.inspect shows the draft; it never opens
the browser.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The Start card and File › Samples show a grid of sample cards (thumbnail, name,
one-line description, the full text on hover) in a scroll area with a solid
scrollbar; Help › Samples keeps rows in the same order. The card stays clear of
the view cube and the navigation bar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Right-click on any browser item (body, surface, datum, partition, set,
material, section, step, boundary condition, load, reference point,
coupling, contact, fluid domain) opens its menu: Edit…, Hide/Show,
Isolate, Show All, Active in step (boundary conditions and loads) and
Delete…. A right click on a datum or a partition's cut face in the
viewport opens the same menu. Each item the viewport draws on its own
has an eye; hidden items are neither drawn nor picked. Datums and
partitions are selectable with properties. Delete… and the Delete key
ask first (the prompt lists what uses the item: a datum's partitions
are deleted with it, other definitions in use are refused); ui.prompt
answers it. Every entry runs the same command as the ribbon and forms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Boundary condition, load and interaction symbols are wireframes (thin lines,
no shaded cones), so they never hide the mesh or a contour plot:
- a crossed wire triangle per constrained translation, tip on the node,
coming from outside the part where the set's faces say which side that is;
a held rotation adds a smaller triangle behind it (the double mark); fixed
shows all three axes, a symmetry plane only its normal;
- forces as open-headed arrows ending on the node, as long as four support
units at one place and 2.5 over a set, so loads and supports stay in
proportion (#78); moments as an axis line and a right-handed curved arrow
(#79); contact and tie surfaces as small squares on their faces;
- a constant size on screen at any zoom (#80): the symbol unit is the size
setting (View > Symbol size, `ui.set {symbol_size}`, 14 pt by default)
times the model length a pixel spans, rounded to a quarter of a doubling;
- spread evenly on a grid a few symbol units across, so their density follows
the screen, never more than 400 per definition;
- a layer of their own on the desktop (GPU and CPU): zooming rebuilds and
uploads the symbols only, never the mesh's scene; framing leaves them out;
- colour per kind from the theme's tokens (a new contact colour), and the
definition selected in the browser drawn in the selection colour, wider;
- depth-tested against the model with the line bias that keeps them on their
own surface; a load at a reference point or a single node and a reference
point's cross are drawn over the part (#78).
Headless pictures (MCP screenshot, `ui.render`) frame the camera first and
draw the symbols at the default size for it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
A scene's `on_top` lines are drawn after every depth-tested layer, over the
model, so a concentrated load at a point inside the part can be seen from any
side (#78). `render_layers` takes a list of overlays (the setup's symbols and
the selection highlight become separate layers), and draws every layer's
labels. `Camera::length_per_pixel` is the model length a pixel spans at the
target: the scale symbols of a fixed screen size are drawn at.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
An orbit turns about the model point under the press (the pick ray's
first hit on the plot, the mesh or the design), or the centre of what is
drawn when it starts on empty space, keeps that point still on screen and
marks it while orbiting. The wheel and a pinch zoom toward the point
under the cursor; the wheel's delta is read as it arrives, so a notch
zooms in full in orthographic and perspective views alike (#273).
Mouse presets and reverse zoom come from SolidCraft (prefs.rs NavPreset,
NAV_PRESETS; MIT OR Apache-2.0): FieldCraft's own (left drag per the
navigation bar) stays the default, Ctrl + left drag from empty space
orbits in every preset. They are chosen in the display menu, settable
with ui.set and kept in prefs.json beside recent.json (the browser build
keeps them for the page's run); an older prefs.json still loads.
Fixes#262, fixes#273.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The setup checklist card (#265), its show_setup view setting, the View
menu checkbox and the preferences file that only remembered it go; the
tree's marks and ghost rows replace them. Session::progress and
model.check's progress stay for agents. An old prefs.json is no longer
read.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The ~40 parameter checks give a ProblemKind instead of text; Session::execute looks the problem
up in the command's form (a group's missing field becomes that field's own path). Replies still
name keys; forms phrase the same problem by label. A test refuses every field of every form and
checks each refusal names a field of that form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Every fit frames what is drawn (the deformed shape and the setup's symbols
included) with Camera::fit_in in the part of the viewport the overlays
leave free: the results legend, the selection bar, the gizmo and the
navigation bar (framing::free_part). Standard views fit too, so a long
beam's front view keeps both ends (#147); fit and home leave the legend
clear (#76). The view frames itself in the home view when another model,
sample or design is opened (Session::opened; the same design opened again
after an edit keeps the camera) (#233), and when results come up with part
of the model out of sight (#223). ui.inspect's layout reports the legend.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The first look at a solved static step draws the von Mises contours on the
true geometry; the deformed shape comes when asked for (Deformed,
results.deformed, results.animate), at the automatic scale. Frequency steps
still open on mode 1 deformed and explicit steps at true scale, as the
owner's notes in #77 ask; a 0.24 mm deflection drawn as 10 mm no longer
reads as a failed part.
Fixes#77
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Once a model has geometry or a mesh, the browser shows the analysis stages from the engine's
checklist, each ticked, next, dashed (optional) or open; a click starts the stage's command and a
blocked stage's hover says what it waits for. The × hides it and View › Setup checklist shows it
again; the choice is kept in the per-user prefs.json.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
schema::Problem now holds the &'static Field it is about and a ProblemKind
(Required, NotANumber, Below, Above, NotAChoice, UnknownVariant, ...).
Problem::for_form phrases it by the field's label, Problem::for_agents by
its JSON path, from the same data. The form no longer rewrites problem
text by string matching or re-walks the field tree; field_at moves to
schema.rs for the engine's own Param errors. The forms test matches
EngineError::Param { key, .. } directly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Every problem reads with the field's label ("Material: choose a material")
beside its field, once it was edited or OK was tried; a click on the greyed
OK shows them all, and its tooltip lists them. A parameter the command
refuses shows beside its field, by its label, in the form and status bar.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
A seed draws a tick at each node it puts on its edge, so a bias shows as ticks
crowding toward an end. The browser lists the seeds under Mesh; a click
selects the seeded edge. The Seed Edges form takes the selected edges with
Use selection. The toolbar entry is ready (its icon renamed with it).
Part of #230.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The viewport keeps each drawn body's B-rep edges; with Select: Edges a click
picks the nearest visible one (before and after meshing), hover and the
selection draw it wide, and multi-select works as for faces.
Part of #230.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
A reference field (a material, set, step…) with no items was a free-text box; it is now a greyed
drop-down ("No materials yet") with a button that opens the command making one (the
collection's requirement provider). That form comes back to this one on OK, with the new item
picked, or as it was on Cancel. A required reference with one candidate, or with the browser's
selection of its kind, starts picked when the form opens, so the fields and the JSON view agree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Commands run from the UI whose reply had no `summary` printed their raw
JSON into the status bar (Check Model, Step Table, Model Info, Bodies,
Find Contacts, the solve steps...). The status bar now gets one sentence
for every reply, and a reply with more to it opens in the context panel:
Check Model as its diagnostics with severity marks and a button to each
fix, the Step Table as a grid of loads and BCs against steps, any other
reply as labelled rows and tables. Check Model and the Step Table follow
the model as it changes. Programmatic replies stay JSON.
Fixes#217
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Datum planes draw as a hatched square around the model, axes as a line through
it, each with its name, in the desktop viewport and the headless render. The
browser's Geometry node lists the datums and the partitions with the datum
each cuts by.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The ribbon buttons, drop-down rows, command search and the title bar's Solve read
Session::availability: greyed, with what is missing (and where to get it) in the tooltip.
Starting such an entry opens no form; the status bar names what is missing. ui.toolbar
reports each entry's `enabled` and `unavailable`, ui.inspect the Solve button's.
Fixes#220
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
CommandSpec gains `requires: &[Requirement]` (crates/engine/src/requirement.rs): an open
design, geometry, nodes, a mesh, something to analyse, materials and sections for the
elements, sets, the definition an edit or delete acts on, a step, a result. Session::execute
checks them before running, so a command missing one fails at once with no partial work,
naming each missing piece and the toolbar entry that provides it ("Needs a material —
Properties › Material"). Requirements are real prerequisites (the model's own reference
checks and model.check's rules), never a workflow order. engine.commands / list_commands
list them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Opening (File > Open, a drop, the recent list) a design that has none of the
bodies the model's mesh and sets are on now asks, like the unsaved-changes
prompt: Start a new model with this design (default, Enter), Keep the
current model (the status names what no longer resolves), or Cancel. The
opened session waits for the answer; the same design opens without asking.
ui.inspect shows the prompt as {"design": path}; ui.prompt answers it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
While result contours are shown, the hovered item's face fill is left out
and only its outline, edges and nodes are drawn, so the hover never hides
the colours under the pointer. Picker::hover is the hover's own overlay.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
The context panel's form shows typed fields instead of the JSON text: numbers
with the model's units, drop-downs of choices and of the model's sets,
materials, steps and bodies, checkboxes, vectors, groups and one-of variants
(a load's type switches its fields), lists of rows. Defaults are filled in,
required fields are marked, a value the schema finds wrong is noted under its
field, and OK waits while a field holds text that is not a value. The JSON
text stays as the Advanced view. fields.rs holds the generic widgets (row,
number, drop-down, text), adapted from SolidCraft's dialog rows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
Quality from the ribbon printed its whole JSON report into the status
bar, cut off after the first metric's histogram, so a user saw braces
and no answer. The report now carries a `summary` line ("30676 elements,
all valid; scaled Jacobian min 0.305, mean 0.963", with the invalid and
undetermined counts when there are any), and the status bar shows a
reply's summary instead of its JSON whenever it has one. The CLI and MCP
get the same line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
OK on a mesher's form ran the command on the window thread: octree hex
on the bolted assembly froze the window for over a minute, with no
progress and no way to stop it. The tet and hex meshers' forms now run
their command as a background job on a copy of the session, as opening
a file and solving do: the window keeps drawing with the job's name and
Cancel, the form closes when the mesh is in and shows the error when it
is not. ui.dialog {run} stays synchronous for programmatic callers.
The new test walks a first-time user's path: Open picks a SolidCraft
design, Tet Mesh opens its form, OK with the defaults meshes the part,
and a mapped hex mesh of a holed plate says why it does not fit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
The Open dialog is a native picker the control channel cannot click, so
nothing could walk a person's open path end to end: ui.start file.open
opens the command's JSON form instead. ui.drop {paths} hands the paths
to the next frame with the window system's drops, which open them
through the same route a picked file takes (open_path: by type, in the
background, the unsaved-changes prompt, the recent list). At most 16
paths of at most 4096 bytes each.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
A click in the viewport picks what is under the pointer through the
selection filter (the selection bar, top centre): geometry faces, edges,
vertices and bodies, or mesh nodes, element faces and elements. Shift
adds, Cmd/Ctrl adds or removes, a click on nothing clears, Escape
clears; with Box on, a left drag selects the visible nodes, element
faces or elements inside the box. What a click would pick is
highlighted under the pointer with its name beside it.
The selection is kept in the model's persistent terms: geometry by name
(GeometryRef, named through the mesh's geometry tags or the drawn
bodies' face names), so it survives a remesh, and the mesh by label
(labels the model loses drop out). It reads as a set's members.
Picking runs on the CPU against the triangles both renderers draw. The
selection and the hover are drawn as an overlay in the theme's new
pick_selected and pick_hover colours (light and dark), outlined; the GPU
draws it as a second small layer, so a hover change uploads only that.
Command forms that apply to part of the model (sets, boundary
conditions, loads, sections, couplings) get a Target row whose Use
selection fills the members, or makes a set of the selection and names
it. A right click offers Create set from selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
The setup's symbols (fieldcraft_render::glyphs) are built with the display
data and drawn over the model in every style, at the drawn nodes (a results
plot's deformed shape), muted over results; the clipping radius holds them.
Theme tokens give their colours in light and dark. The browser's Loads & BCs
and Interactions rows get eye toggles (ui.set show_loads, show_interactions),
also in the view menu. The GPU viewport draws reference point names with the
interface's font; the bottom left says which definitions are sampled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
A command run by a script, the control channel, MCP, the command search
or the browser left the ribbon on whatever tab it showed, so an agent's
session never showed the stage it was at. `catalogue::stage_tab` is the
rule, from the catalogue: a command's entry tab, none for the Tools tab
(files, history, the model summary). The app follows it after a command
that changed the model or the results display (queries leave the ribbon
alone); a script follows its last command with a stage. A ribbon click
runs a command of the tab shown, so it never moves the ribbon: a test
checks every entry and drop-down command against its tab.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
Crates fieldcraft-*, binaries fieldcraft and fieldcraft-cli, the .fieldcraft file (format tag
fieldcraft/1, manifest fieldcraft.json), FIELDCRAFT_* environment variables, the MCP server
name, egui widget ids (fc_*), the app icon document FieldCraft.icon and its generated family,
docs and licences. No compatibility shim: no files of the earlier name exist.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* Native file pickers, background opening, drag and drop and recent files
Open (models, SolidCraft designs and tagged meshes in one picker), Save, Save As, Write
Deck and Recover go through the host's file pickers (rfd in the desktop app, injected as
Services so the UI crate stays portable and tests answer them). Files open on a copy of the
session in a worker thread and replace it only on success; files dropped on the window or
named on the command line open the same way. A recent-files list, an unsaved-changes prompt,
Cmd/Ctrl+O/S/Shift+S. Programmatic calls never open a picker: ui.start opens the form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* Samples and one-click Solve: results reachable from the window
file.sample {name} opens a ready-to-run sample (the two parts, the cantilever with static and
frequency steps, the bar impact) in place of the model; solve.run solves every step in order.
Help > Samples, the empty viewport's start screen and the Tools > Samples entry open them
(asking first over unsaved changes); Solve runs in the background like a file opening and the
Results tab comes up. --sample [parts|cantilever|impact] on the command line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* The Craft-family shell: title bar, workspace ribbon, browser, context panel, timeline
The window now follows SolidCraft's and VectorCraft's layout and themes:
- title bar with the mark, quick actions (File menu, save, undo, redo, Solve, search,
theme, help), the model's document tab and the version; integrated under the macOS
traffic lights, own caption buttons and resize zones elsewhere (titlebar.rs);
- workspaces (Prepare, Model, Analysis, Results) with their tabs, and panels of icon
buttons whose labelled drop-downs list the whole catalogue, coming-soon entries greyed
with their milestone; panels collapse, then go into a » menu, when narrow;
- the browser: geometry and mesh with eye toggles, definitions with counts, results;
- no permanent Commands list: command search (S, Cmd/Ctrl+K) and a command line;
- the context panel on the right only with context: the command form, results controls,
the selected definition's properties with Edit and Delete;
- navigation bar and orientation gizmo in the viewport; the journal timeline at the bottom
with undo positions;
- SolidCraft's light and dark tokens; craft-ui (IconButton, Tab, WidgetPalette).
Menus and the search are view state (ui.set {menu, palette}), so captures show them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* Shell polish, docs and licences
Menus painted as the family's (flat File menu with recent files, decks and samples), the
legend sized to its text, two-line panel labels inside the ribbon, glyphs the UI font has,
offscreen captures without fade-in, ui.start runs in-window file actions (samples, recover,
solve) but never a native picker, ui.select. Control protocol, architecture, ROADMAP, AGENTS
and ATTRIBUTION updated; THIRD-PARTY-LICENSES.txt with craft-ui and rfd.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* Title bar mark from the application icon; fluid steps and domains in the shell
The title bar draws the app icon's bracket (assets/app-icon/icon-small.svg's faces) as
SolidCraft draws its mark; the window keeps its title-bar flags after the rebase.
solve.run solves fluid steps too (solve.fluid); the browser lists fluid domains.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* Simplify: cached per-frame data, one command per timeline roll, workspace setters
- Icon textures are kept per pixel size (the shell draws several sizes a frame; the cache
used to clear on every size change and rasterise again).
- Opening a model or recovering one starts from an empty session instead of copying the
current one; the replaced session is freed off the window thread.
- Element counts, timeline items, search results and the selected definition's properties
are cached until what they show changes; timeline tooltips are built on hover; long lists
in properties are summarised.
- edit.undo and edit.redo take a count: a timeline click is one command.
- solve.run dispatches on the step's procedure (no string round trip) and reports its name.
- The workspace and tab change together through UiState::select_tab/select_workspace
(ui.set {workspace} alone now sticks); no per-frame syncing.
- One busy guard, Kind::verbs, a fit flag for background jobs, ModelApp::home_view, the title
bar's actions as an enum, dead code removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* Title bar: Solve and tools at the right end; no traffic-light inset in full screen
The owner's feedback on the title bar: Solve, search, theme and help sit at its right end
before the version; on macOS the left group (mark, name, quick actions) moves into the
traffic lights' room in full screen, where there are none, and back when leaving it. The
layout is a pure function (bar_layout) tested for both states, narrow windows and custom
caption buttons. ui.fullscreen {on} for agents.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* Caps labels in Inter SemiBold
egui has no bold weight of its default font, so the ribbon's tabs and panel labels, the
workspace switcher and its menu, menu headings, the browser header, the context panel's
headers and the Solve label were thin, especially in the light theme. They now use a label
font family: Inter SemiBold 4.1 (SIL OFL 1.1, unmodified, fonts/OFL.txt, ATTRIBUTION.md),
with egui's fonts as fallback, installed with the theme on the live and offscreen contexts.
theme::label_font falls back to the default font until the family is bound (fonts take
effect from the next pass), so nothing can panic. Panels widen to their label's longest word.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
* docs: regenerate features.md after rebase
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
---------
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>