Skip to content

feat(viewer): desktop-style UI features in core, pop-out panels, and ada desktop dev mode, remote servers and SSO - #501

Merged
Krande merged 34 commits into
mainfrom
feat/ui-followups
Nov 6, 2026
Merged

Krande merged 34 commits into
mainfrom
feat/ui-followups

Conversation

@Krande

@Krande Krande commented Nov 6, 2026 •

Copy link
Copy Markdown
Owner

Follow-ups to #495. Generic features that alternative UI shells previously had to build themselves now live in core, so a shell's docked UI can be pure configuration. The built-in Desktop UI (?ui=desktop) uses all of them. The desktop app (ada desktop) gains a dev mode, remote servers and single sign-on.

Viewer-core and plugin API go from 1.14.0 to 1.15.0. Every change is additive, and one combined changelog entry is in viewer-core/index.ts and plugins/registry.ts.

Viewer

Shell switching and global commands

  • In-place UI shell switches. Composed shells switch without a reload and keep the loaded model. Shells that need a reload carry the scene through a deep link. This covers the intent of fix(viewer): a UI shell switch keeps the loaded model #484.
  • Command palette on Ctrl+K in every UI. Core now owns the palette. A shell can disable it or add keys with chrome.commandPalette. Classic has no palette button; the shortcuts dialog lists Ctrl+K.
  • "Customisable panels" is stored per UI shell. Composed shells require it (UiShellLayout.customisablePanels).
  • Core commands for desktop-style menus:
    • open a local file, also by dropping it on the canvas;
    • select all and invert selection;
    • the named camera views;
    • export the selection or the model;
    • About.

FEA features

  • FEA sets and properties in the Scene tree, in every UI. Isolating several sets shows their union, can be undone, and can show the rest of the model as a wireframe.
  • Number labels. FEA node and element ids drawn over the view. The count is bounded: only selected elements when there is a selection, otherwise a sample, thinned per screen area and capped at 400 labels.
  • Colour by property. Colours elements by FEA property fields (section, material, thickness) or gives each loaded model its own colour, with a legend. Plugins add sources with registerColorBySource.

Interaction and modes

  • Marking menu. Hold the right mouse button, or press Shift+E. A quick right-click still opens the context menu, and a right-drag still pans.

  • Customisable tool rail (chrome.rail), saved per shell.

  • Mode toolbars from core. A shell lists them with UiShellMode.toolbars, or mounts the components itself:

    Toolbar Contents
    playback result transport, step slider, period, deformation scale
    section per-axis planes, flip, offset, clear
    representation edges, wireframe context, result colours, element edges, undeformed outline, labels
    colorBy picker and reset
    build procedural builder: undo/redo, compile, commit, close

    Every button is also a core command, so the palette, rail and marking menu can reach it. When a command doesn't apply, it is disabled and says why.

  • Build mode. UiShellMode.requires: "builder" offers a mode only while a procedural model is open. The Desktop UI uses it for a Build mode that docks the builder.

Pop-out windows

Simulation (Results tab), Result data and Scene info (Model tab) now work in a separate window:

  • the main window publishes their state on core:fea-controls, core:fea-table and core:scene-info;
  • each control sends a checked command back;
  • the table publishes the first 2000 matching rows.

The pop-out tree gains the Systems tab and the row-menu actions. Panels that still need the scene in their own window keep refusing "Move to window".

Desktop app (ada desktop)

  • pixi run desktop: a dev mode with hot reload. Vite runs inside the native window, with uvicorn --reload.
  • Hosted server. --server URL|NAME connects to a hosted server, with saved profiles (ada desktop servers add|list|remove). --dev --backend runs the local frontend source against a hosted server. Pixi tasks: desktop-server and desktop-backend.
  • Sign-in:
    • Microsoft Entra ID sign-in completes inside the window: Microsoft's sign-in hosts are allowed and form posts are kept.
    • Windows single sign-on uses the OS account (--no-sso turns it off).
    • Sign-in pages never get IPC.
  • 3D mouse: support turns on by itself when a device is found, until the user chooses in Options.
  • Faster builds: an unchanged shell no longer relinks on every build.

Known gaps

  • No annotation tools: core has no measure, label or markup tools.
  • No scene-wide wireframe or transparency switch.
  • Labels only for FEA meshes, and without an occlusion test.
  • Colour-by is not kept across a reload.
  • The pop-out tree has no Sources tab.
  • The Systems tab and related actions in a pop-out are covered by unit tests only.

Verification

  • tsc --noEmit is clean.
  • npm test: 2520 tests, with only the 3 known baseline failures (tab, fade, WebGPU pick).
  • npm run build passes, and the bundle provenance check prints "OK: all".
  • Desktop: Rust and Python tests pass.
  • Browser smoke test with Playwright on ?ui=desktop covered:
    • the modes and toolbars;
    • the palette and menus;
    • loading a GLB, sections and representation;
    • Build mode with a test model;
    • pop-out tree, Scene info and Simulation with fake results.
  • Sign-in was verified against a real Entra-protected server.

Supersedes #484.

🤖 Generated with Claude Code

https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP

Krande and others added 29 commits November 6, 2026 13:25
…ktop

ada desktop --dev runs the viewer under uvicorn --reload, the frontend under
Vite (HMR) with a config that proxies /api (websockets included), /config.js
and /healthz to the viewer, and opens the native shell on Vite. --frontend-url
opens an already running Vite instead; --dev-port picks the Vite port.

pixi run desktop (new desktop-dev environment: viewer-api's closure and solve
group, so only that environment is added to the lock) builds the shell
(incremental) and the frontend dependencies through task dependencies on the
desktop-shell and frontend environments, then starts ada desktop --dev.
Windows only for now; other systems get a clear message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…ut as core commands

The built-in Desktop UI's menus lacked these; each is now a core command
(CORE_COMMAND_IDS) any composed shell can name, and the Desktop UI's menus
list them.

- File -> Open... (core:open-file, Ctrl+O): GLB / glTF read in the browser
  and loaded straight into the scene, no upload, in any viewer. Other
  formats go through storage on a converting REST server (asked first,
  then uploaded and loaded through the load queue) and are refused with
  the reason elsewhere. Files dropped on the 3D view open the same way,
  added to the scene.
- Edit -> Select all (Ctrl+A) / Invert selection: the shown elements of
  the loaded models, hidden ones and switched-off models never taken; one
  undo entry each.
- View -> Camera -> Top / Bottom / Front / Back / Left / Right / Isometric
  view: the model framed from that side (Z up, or turned for Y up),
  animated with camera-controls.
- File -> Export selection... / Export model...: a dialog of scope and
  format over the server's existing STEP / IFC export (the selection scope
  reuses the object info panel's control); greyed off a REST viewer.
- Help -> About: the viewer's build, the API versions, the UI, the
  connection, the server's reported image tags, documentation links.

The upload extensions move to a light module so the picker needs no
upload code; the selection export's wiring is shared by the panel and
the dialog. VIEWER_CORE_API_VERSION and PLUGIN_API_VERSION 1.14.0 (Ctrl+A
and Ctrl+O are now core's reserved chords).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…e check finds it

The JSX entity &apos; is a plain apostrophe in the built bundle, which the
provenance check compares literally. Bundle rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
… reloading switch

A switch between core's own UI and composed shells (Classic <-> Desktop, and
any plugin shell without `load`) no longer reloads the page. UiShellHost keeps
one root of core's mounted (CoreShellRoot: provider, canvas, layout) and tells
it which shell to show; ComposedLayout installs the new shell (modes,
arrangements, top bar, panel overrides, look) after undoing the previous one
(its palette command, and a plugin shell's own commands, shortcuts and HUDs,
parked until it returns). The canvas, the models, the selection and the camera
stay. ?ui= is dropped from the address bar; the multi-window dashboard stays
the shell the page booted in (bootUiShellId), and new pop-outs boot into it.

A shell with `load`, or one that sets the new `reloadOnSwitch`, is still
switched by a reload. That reload now carries a deep link (#484's design:
carryOnShellSwitch / shellSwitchUrl / deepLinkCarry, ui never carried, a
closed model not brought back, a throwing carry skipped) and marks itself so
the scene restore brings stored models, the camera, hidden objects and the
selection back even with "restore after reload" off.

Inside a shell, leaving a shell (not a mode) no longer hides its placed
panels, and leaving a shell hands a mode's scene colouring back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
Core's root mounts one palette host (CorePaletteHost) under AppRoot, so it
survives an in-place shell switch and is never mounted twice. It binds the new
core shortcut core:command-palette (Ctrl+K, reserved; not while typing in a
field), registers the palette's command and draws the palette over
listCommands(). Core's own UI now registers core's commands as well and gets a
palette button in its top bar; the shortcuts dialog lists Ctrl+K.

UiShellChrome.commandPalette: absent means on; `keys` adds a chord of the
shell's own beside Ctrl+K (a shell using Shift+K keeps it); `false` turns the
palette off while the shell is active. A composed shell no longer mounts a
palette of its own. "Reset every mode's layout" is greyed with its reason in a
UI without modes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…sed shell

With the setting off in the classic UI, the Desktop UI's docked layout fell
apart: it is built on the split grid that setting turns off. The setting is
now the user's per UI shell (LayoutPrefs.customisablePanelsByShell; the one
setting of before moves to core's own UI's on load), and a composed shell
requires it (UiShellLayout.customisablePanels: "required", the default, or
"optional"): always on there, with the Options toggle on, disabled and
explaining why. Every reader (the classic preset's zones, the grid, windows,
zone keys, the exclusive-group rule, the shortcuts dialog, Options) goes
through one selector, layout/customisable.ts, which follows the served shell
through an in-place switch, so Classic (off) -> Desktop -> Classic comes back
off and the Desktop UI looks as designed in between.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
… a plugin shell's registrations again

An in-place switch installed the incoming shell while ComposedLayout was
rendering, which notified the mode store's subscribers (the menu bar) mid-render
("Cannot update a component while rendering a different component"). The first
install still runs before the first render; a switch now installs in a layout
effect, before the browser paints. The incoming plugin shell's baseline (what
its plugin had before the shell came up) is read while rendering, before its
chrome's chunks run, and before parked registrations come back, so those are
taken down again the next time the shell is left.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
… and the core palette

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
Ctrl+K opens it in every UI and the shortcuts dialog lists it; the button is
not needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
Until the user chooses in Options, a 3D mouse the page may already use (the
desktop app's native reader, or a device the site was granted before) switches
support on, as does one plugged in later. getDevices() only, so it never
prompts. Choosing on or off in Options is kept from then on. A stored false from
before counts as the old default, not a choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
ada desktop --server URL|NAME (or ADA_DESKTOP_SERVER) opens a hosted
deployment in the native window instead of starting the local viewer. The
page runs on the server's own origin, so sign-in, the API and uploads work
as in a browser tab. Named profiles live in a per-user servers.json
(ada desktop servers list|add|remove); https is required except for
loopback or an explicit --insecure.

The shell takes --trust-origin and --auth-origin: windows show only the
trusted origin (identity provider origins for navigation only, discovered
from /api/config and the issuer's OIDC metadata), and native events are
granted to the trusted origin alone through a runtime capability that
replaces the static loopback one. Origin logic is unit tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…lation, in every UI

While an FEA result is loaded, core adds "Sets" (element sets and node sets,
with counts; node sets are informational, since nodes name no faces) and
"Properties" (each property field's values and how many elements carry each,
read from the field's blobs the first time the rows or a pick need them) to the
Scene tree after the models. Selecting element-set or value rows isolates their
union: the isolated elements keep their result colours and deformation, the
legend measures what is drawn, and the rest is hidden or drawn as its element
edges. Each change is one undo entry, the isolation a slice of it.

- Rows: utils/scene/fea/feaTreeRows (pure), feaTree (provider, `core:fea-tree`
  mirror topic, reset on a result change), feaIsolation (scene actions),
  feaPropertyMembership (lazy reads), state/feaIsolationStore.
- TreeNodeData.informational / marked / title; an FEA row menu (isolate, add,
  remove, clear, rest as wireframe, hide / show); a right-click on an FEA row
  does not select (and so isolate) it.
- Core commands fea-isolate-sets, fea-isolate-selection-sets,
  fea-clear-isolation, fea-toggle-context-wireframe (palette; Desktop UI's
  View -> FEA sets), through new scene actions with mirror commands, so pop-out
  windows act on the main window's scene.
- The Selected Object panel's fea-sets section: a picked element's values and
  sets, each with Isolate.
- groupVisibility: applyFeaIsolationOverlays (what undo / redo re-apply), and the
  overlay rule imported from streaming/visibility instead of the loader.
- Facade exports on @/viewer-core/scene, 1.14.0 changelog, UI_SHELLS.md and the
  Ada Studio FE results section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…default and the palette button

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
Vite serves the local frontend with HMR on http://localhost:<fixed port> and proxies
/api (websockets included), /healthz and /config.js to a hosted server (TLS verified,
Host/Origin presented as the server's, cookies forwarded). The window trusts only the
localhost origin plus the identity provider origins discovered from /api/config, and the
command prints the SPA redirect URI to register. /config.js is fetched and any absolute
address of the server rewritten to the dev origin. --dev --server is an alias; plain --dev
stays local. New pixi tasks desktop-server NAME and desktop-backend NAME. Fixes the
"only apply" grammar in the local-only flag error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…op UI

Marking menu: a wheel of up to eight commands, with a short list under it,
at the pointer over the 3D view. Hold the right button still for 300 ms
and it opens; flick towards a command and release to run it, or release
in place and click, or use the arrows and Enter. Shift+E (core shortcut
core:marking-menu, now reserved) opens it from the keyboard. A quick
right click is still the Scene menu and a right drag still pans: the
gesture is a small state machine (MarkingGesture) that holds a
press-time contextmenu back until it knows which of the three a press
is. Once open, the camera's drag is cancelled and the flick's moves are
kept from it. Commands that cannot run are greyed in place with the
reason. Shells configure it with UiShellChrome.markingMenu (items, more,
submenus, gesture). It is off by default in the classic UI, where
Options -> Theme turns it on, and the choice is kept per shell in the
layout prefs.

Tool rail: UiShellChrome.rail may now be {tools} (command ids and
separators) instead of a lazy component, which still works. Each button
takes the command's icon (core's commands have icons now) and shows its
label and chord as a tooltip. It is pressed while a toggle is on, and
greyed with the reason while the command cannot run. Users can remove a
tool from its context menu. The customise dialog adds any command,
reorders, adds separators and resets to the shell's list. The user's
rail is kept per shell in LayoutPrefs.rail; a tool the shell adds later
is put in beside its neighbour.

The Desktop UI has both, with Window -> Customise tool rail… and
View -> Display -> Marking menu. Only the main window has them, since a
pop-out has no 3D view and draws no shell chrome.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…users

UI_SHELLS.md gains a section on each. The marking menu section covers
the gesture and why it is a hold, the platform contextmenu handling,
items and slots, the defaults, and where it is on and why. The tool rail
section covers the data form of chrome.rail, the user's list and how it
is upgraded, and the customise dialog. The Desktop UI's tables list its
rail, its marking menu and the new menu items. Ada Studio's user page
says how to use both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
… the shell

tauri-build watches the capabilities folder; once the static capability file
went (the capability is built at startup), the missing folder left the crate
always dirty and every build relinked it (about a minute). A placeholder keeps
the folder; an unchanged build is a no-op again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…e tool rail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…ws single sign-on

A sign-in against an Entra ID tenant failed with AADSTS900561 ("the endpoint only
accepts POST requests"): after the authorize page the provider POSTs to
login.microsoft.com (passkey / Windows Hello step, /fido/get), a host the window
was not allowed to show. The shell cancelled that navigation and handed the URL to
the system browser, which re-issued it as a GET.

Navigation policy (origin.rs):
* when a sign-in origin is a Microsoft login host, a documented built-in set of
  Entra ID sign-in hosts is allowed too (https, default port only);
* once a window has gone from the app to a sign-in page, the provider may send it
  on to any https page (federation, MFA) until it is back on the trusted origin;
  tracked per window, so federated providers need no --auth-origin per host;
* sign-in pop-ups open as native windows WebView2 navigates itself (opener and
  POST bodies kept); no sign-in page ever gets IPC;
* every sign-in navigation is logged with host and path only.

Single sign-on: the shell creates the WebView2 environment with
AllowSingleSignOnUsingOSPrimaryAccount (webview2-com, passed to wry with
with_environment) in the profile folder tauri uses anyway; on by default,
--no-sso (shell and ada desktop) turns it off. A clear error replaces the panic
when another window with other options holds the profile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
A mode's toolbar slot now comes with content from core. UiShellMode.toolbars
names core toolbars ("playback", "section", "representation"); the shell mode
toolbar draws them before the mode's own toolbar, so a shell needs no code.
The components (PlaybackToolbar, SectionToolbar, RepresentationToolbar,
CoreModeToolbars, CommandButton) are exported on the layout entry.

New core commands with icons, reachable from the palette, menus, tool rail and
marking menu: results play/pause/stop/step, section planes per axis (toggle,
flip, clear), and the result view switches (undeformed outline, element
edges, result colours). The transport actions move to
utils/scene/fea/playbackActions, shared with the Simulation panel. The Desktop
UI's modes use the toolbars and its View menu lists the commands.

Core has no scene-wide wireframe, transparency or annotation tools, so there
is no toolbar group for them. VIEWER_CORE_API_VERSION and PLUGIN_API_VERSION
1.15.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
Number labels: core:labels-nodes and core:labels-elements draw the node and
element ids of a loaded FEA result as HTML over the view (NumberLabels, drawn
by the overlay layer when chrome.overlays.labels is set). Bounded: the
selection's elements, else a sample of at most 4000, thinned on a screen grid
to at most 400, redone only when the camera, selection or deformation change.
Node ids are the solver's when the bake has them.

Colour by: a colorBy mode toolbar (picker and reset) and commands colour the
scene by an FEA result's model property (selected as a result field, so the
existing painter and legend are used) or by model (range colours, with
ColorByLegend). registerColorBySource lets a plugin add sources. The
representation toolbar gains the label switches, and the Desktop UI uses all
of it. VIEWER_CORE_API_VERSION and PLUGIN_API_VERSION 1.16.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
Core gains the pieces a docked shell needs for the procedural builder, and the
Desktop UI uses them as a Build mode next to Model and Results.

- Commands: core:builder-undo / -redo / -compile / -recompile /
  -compile-browser / -commit / -close over the cellbuilder store, each greyed
  with its reason (no model, read off the scene, a connection that cannot edit
  or compile on a server, a job running, nothing to undo or commit).
- A "build" core mode toolbar (BuilderToolbar): model name and revision, an
  unsaved marker, undo / redo, compile, compile in the browser, commit, close.
- UiShellMode.requires: "builder" offers a mode only while a procedural model
  is open; it is left out of the switcher, Modes menu and palette otherwise, and
  the shell falls back to another mode when the model goes away.
- chrome.overlays.builder mounts the builder's canvas menus and gizmo HUD for a
  shell that docks the panel (shared CellBuilderOverlays, also used by classic).
- Desktop Build mode: the builder on the left (tree and storage behind it), the
  selection and scene on the right with the catalogs; the panel leaves out its
  footer and undo / redo there because the toolbar carries them; a Build menu.

Viewer-core and plugin API 1.17.0 (additive). Documented in UI_SHELLS.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
The Simulation panel, the result data panel and the Scene panel (its Model
tab) are mirrored, so they can be moved to a window of their own, and the
scene tree there gains the Systems tab and the row menu's selection box,
unload, saved-group and related entries.

- core:fea-controls publishes the result session as plain data (manifest sent
  when it changes, field / component / step, transport, toggles, colour scale,
  legend range, edge fade; the playing fields throttled to 100 ms). The panel's
  controls go through one seam, feaControlActions(): the main window runs the
  playbackActions / loader / resultSelection code, a pop-out sends one checked
  command per action (FEA_CONTROL_COMMANDS).
- core:fea-table: the pop-out sends its filter and sort, the main window reads
  the step, applies the same tableRowIndices the table uses and publishes the
  first 2000 rows with the count matched.
- core:scene-info: loaded models and whether each is shown, groups without
  member lists (capped at 5000, sent when they change), take-off and selection
  boxes; the panel acts through new SceneActions (setModelVisible,
  unloadModels, selectGroup, box actions, runRelated).
- The Systems tab's select / load by name and the related actions run in the
  main window from a pop-out.

Not in a pop-out: the Sources tab, the Scene panel's other tabs, the FE model
and plugin tabs of the Simulation panel, the animation export.

VIEWER_CORE_API_VERSION and PLUGIN_API_VERSION 1.18.0. Tests round-trip the
topics and commands through a fake bus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
…ult data and scene info

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

PR Review

👋 I checked your PR and found no issues. Thanks!

  • ✅ PR title is ok
  • ✅ Exactly one release label
  • ✅ SOURCE_KEY secret is set
  • ✅ Calculated next version: "0.137.0"

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

🚀 Profiling Results (Top 20 most expensive calls)

Function Calls Duration (s)
<built-in method builtins.exec> (~:0) 1414 20.7137
<module> (<string>:1) 1 20.7137
test_bench_batch_tessellate (tests/profiling/test_cad_backend_bench.py:63) 1 6.4304
run (tests/profiling/test_cad_backend_bench.py:73) 6 6.2380
batch_tessellate (src/ada/visit/tessellate.py:1124) 1446 6.2369
_batch_tessellate_local (src/ada/visit/tessellate.py:1136) 2880 6.1087
__truediv__ (src/ada/api/spatial/part.py:2070) 8 6.0332
tessellate_geom (src/ada/visit/tessellate.py:834) 1440 5.5775
test_build_big_ifc_pipe (tests/profiling/test_ifc_creation.py:48) 1 5.2131
tessellate_occ_geom (src/ada/visit/tessellate.py:688) 1440 5.0245
tessellate_shape (src/ada/visit/tessellate.py:558) 1440 5.0114
add_object (src/ada/api/spatial/part.py:309) 1201 4.1350
add_pipe (src/ada/api/spatial/part.py:164) 200 4.1169
tessellate (src/ada/cad/__init__.py:1414) 1440 4.0573
add_section (src/ada/api/spatial/part.py:294) 801 3.5085
add (src/ada/api/containers/sections.py:139) 805 3.5072
to_ifc (src/ada/api/spatial/assembly.py:432) 5 3.2362
equal_props (src/ada/sections/concept.py:116) 241399 3.2122
sync (src/ada/cadit/ifc/store.py:200) 5 3.1272
sync_added_physical_objects (src/ada/cadit/ifc/write/write_ifc.py:92) 5 3.0848

Krande and others added 5 commits November 6, 2026 20:21
The mode toolbars, labels and colour by, the Build mode and the pop-out panels
each bumped the viewer-core and plugin API on the way (1.15 to 1.18), but none
of those versions was released. Fold them into one 1.15.0 with a single
changelog entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
The conda package test runs against the installed package, which has no
frontend sources, so run_dev_backend stopped at the source-checkout check
before reaching what the tests assert. Point checkout_src at a temporary
folder holding the dev Vite config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
… page loads

The macOS runner exceeded the 1 s allowance for loading the single-file bundle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013iYuG3wvgeMxW9CZvRrSRP
@Krande
Krande merged commit 841d262 into main Nov 6, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant