Machine Configuration held one lead-in and lead-out per thickness and
applied it to every contour. Each thickness now has Outside Cuts and
Inside Cuts tabs; inside cuts follow the outside leads until "Same as
outside cuts" is cleared, and configurations without inside leads keep
applying one pair to both.
The lead type lists, per-type fields and preview from Cutting Settings
are now a reusable LeadsEditor control that both dialogs use. The
machine tabs hide what the configuration cannot hold: the arc sweep,
the clean-hole kerf (taken from the thickness) and Line + Line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Help menu's F1 shortcut took the key before the plate view, so F1
in Clone/Add Part opened help rather than setting the part in place as
it always has. Actions can now claim F1; Clone does, and MainForm lets
the key through to the plate view while it is active.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Operators could only drag or delete a cut-off, so changing which line runs
through a junction (e.g. letting a vertical split the sheet to keep a whole
remnant beyond it) meant deleting and re-adding lines. Trim/Extend edits the
existing start/end limits instead, so no file-format or planner change is
needed: trims stop on the crossing line's centre, extends run to the next
crossing or the sheet edge, and Swap Through-Cut (right-click a junction)
does both at once, trimming the through line's far side because only the
origin-side edge is certain. Edits undo as one step and re-place the changed
segments with PlateSequencing.PlaceCutOffs so a new separator is cut last.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Undo regenerates each restored plate's cut-offs, which removes the
cut-off parts first. A plate holding nothing but cut-offs became empty
for a moment, so the new-plate sentinel dropped a trailing plate while
the restore was still enumerating the plates, throwing "Collection was
modified". Regenerate inside a PlateManager batch so the sentinel only
settles once every plate is done.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Issue #13 asked whether a Sheet Cut-Off can be rotated; Space already
toggles vertical/horizontal, but nothing said so. The tool now shows a
"Space: turn horizontal" tag by the pointer, spells out its keys in the
status bar, and F1 opens a new sheet-cutoff help topic while it is
active (actions can now supply a status hint and a help topic).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plan Cutting saved its settings only on a successful Apply, so a plate
that would not plan lost them. Each open then laid the machine's leads
back over the last parameters, and the cutting panel rebuilt parameters
from scratch, dropping kerf and the machine/material/thickness stamp.
Save the settings when the dialog is accepted, keep the panel's
unexposed fields, and only apply the machine's leads when the last
parameters were not already taken from that machine, material, grade
and thickness.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PlateFillService throws for a plate with a sheet outline, but the desktop
swallowed it: Fill (Ctrl+F) caught every exception and showed nothing, and
Fill Area's async void either completed silently or let it escape.
PlateFillService.Refusal(plate) names the reason, and every caller checks
it first: Fill and Fill Area put it in the status bar and add nothing,
Pattern Tile offers a new plate only, the MCP fill/pack tools return it as
an Error result, and the console exits 2 with it unless --autonest is given.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The plate view fills the outline, hatches obstacles and draws the usable
area; Edit Plate imports an outline from a CAD file or clears it, with
the size read-only while the sheet has one.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Browsing nests in Database mode crashed with ObjectDisposedException on
DataGridView: selecting another nest drops the embedded version history,
and WinForms leaves its grid's keyboard-tooltip auto-pop timer running.
When the timer fired it hid the tooltip through the disposed grid.
GridStyle now hides that tooltip when a styled grid's window is destroyed,
which stops the timer for every grid in the app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8dded7f1 draws cut-off ids white on a disc of the cut-off line's orange,
so the old assertion that no orange touches the id failed on the Windows
CI job. The test now checks what the disc is for: the disc is there, and
the id's white strokes survive on the cut's own pixels. Drawing the lines
after the labels fails it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every installed copy checked GitHub Releases on its own, so a shop's
workstations shared GitHub's 60-requests-per-hour unauthenticated limit
per public address and each downloaded the ~90 MB package over the
internet. Shops large enough to hit that already run the nest server.
The server now mirrors the Velopack feed at /updates/{stable|dev}: one
GitHub API request per 30-minute refresh, each package downloaded once
and checked against the feed's size and SHA-256 before it is served. A
channel is mirrored only while clients ask for it, so stable-only shops
never download development builds. Database-mode clients read the
server first and fall back to GitHub when it has no feed (old server,
mirror off, not mirrored yet), downloading each package from whichever
source listed it. A hand-set feed URL still takes precedence.
OPENNEST_UPDATES=off turns the mirror off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The plate-colored disc behind a cut-off id read as a notch in any part edge
the cut runs along. An orange-red disc with a white id reads as a tag on the
cut-off line instead, and still keeps the dashed line from striking it through.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Highlighting an earlier version on the Versions tab left the plates,
drawings and plate preview on the current version, so there was no way
to see what a historical version looked like without opening it. The
embedded history now reports its selection and the browser downloads
that version (debounced, cached per history view) and shows it, labelled
as historical; selecting the current version returns to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The panel gains a Current plate only / All plates selector, shown when the
two scopes differ. Changing it takes the unapplied scrap cut-offs off,
cancels any running plan and replans. The toolbar button opens with the
scope last chosen there (default all plates); the Plate and Nest menu items
keep their fixed scopes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auto Nest leaves out ledger item codes already on other open server nests,
and save and post re-check a nest's codes before going on.
- Server: GET /api/nests/stock-item-codes?exclude= lists the codes on
non-deleted Draft, Quote and To Be Cut nests. Codes are stored in
nest_stock_codes (schema v14) at every archive write; the upgrade reads
each current archive once.
- Data: INestRepository.GetStockCodesInUseAsync, LedgerCodesInUse (5 s,
failures become an unknown answer), the pure LedgerCodeFilter for ledger
rows (reusable by release-time nesting) and LedgerCodeCheck for the
re-check.
- Desktop: the Auto Nest ledger summary counts "(N on other nests)" or says
other nests were not checked. Save, Save As and post open Ledger Stock
Changed when codes are taken: proceed after a per-attempt
acknowledgement, remove the codes (undoable), or cancel. A ledger that
cannot be read skips the check with a status note.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WinForms user settings lived in user.config under %LOCALAPPDATA%\OpenNest,
the Velopack install folder that setup clears on a reinstall, and the
default provider starts empty at each assembly version. Store them in
%APPDATA%\OpenNest\user-settings.json instead, carrying over any values
the old user.config still holds on first run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a Support Bed tab beside Clamps that edits the grid or slats new
nests assigned the machine receive. A machine without a bed shows the
legacy support-grid.json values; the first edit stores them on the
machine in its units.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The status bar shows the running version, and the Help menu gains
Check for Updates (an immediate check sharing the background check's
lock) and About OpenNest. A copy that is not a Velopack installation
offers to open the GitHub Releases page instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drawing.Bends stay in the DXF's source frame while CadImporter moves the
program so its first pierce sits at the origin (Source.Offset). The plate
renderer added part.Location to raw bend points, so every bend and etch
mark was shifted by its drawing's pierce offset, visible on the drawing
library set preview and on plates alike. Remove Source.Offset before
rotating and placing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- archived library drawings: say they can't be edited or released; no
front end can restore a library drawing yet
- library filter hint names the Show all materials checkbox
- undo labels Support Bed and Automatic Scrap Cutoffs match their menus
- display-outline posting hints name both Plate > Plan Cutting... and
--plan-cutting, since the console prints them too
- MaterialLedger options are saved per Windows user, not per machine
Clamps are physical fixtures that differ between machines, but one global
clamps.json served every machine, so a plasma table and a fiber laser could
not have different rails.
- MachineConfig.Clamps holds each machine's rail in the machine's units,
edited on a new Clamps tab in Tools > Machine Configuration.
- New and BOM import give a nest the rail of the machine they assign;
Nest > Clamps loads and saves the nest's machine's clamps. Each nest keeps
its own copy, so machine edits never move existing nests' clamps.
- At startup, while no machine has clamps, the legacy clamps.json (or the
server's shared copy) is copied once into the default or only machine;
with several machines and no default the user picks one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Shape Library, drawing library and drawing set preview each drew
parts their own way (hardcoded green fill, steel-blue fallback, black
outlines with gray etch). They now share a library style on ColorScheme
(background, fill, outline, etch and bend colors) that ignores drawing
colors, follows the active scheme (Dark gets a dark variant) and
round-trips through saved schemes, defaulting when absent. Nest part
colors are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the name list with a ListView of 96px thumbnails drawn by
Program.GetImage at each shape's preview defaults (or its first
configuration), labelled with the name and configuration count. The
left pane opens three tiles wide instead of half the window.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nest drawings can require no parts, but the CAD Converter's quantity
spinner had a minimum of 1, so Edit Drawings in Converter threw
ArgumentOutOfRangeException as soon as such a drawing was selected.
Lowering the minimum to 0 lets the converter load it and hand the
drawing back with its quantity still 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nest's machine and its Nest Info fields were the last edits only the
fingerprint safety net could catch (and it misses most of them). Machine
is now one step, together with the support grid and cut-off settings the
machine brings. Nest Info is one step for what Undo can put back (units,
material, thickness, customer, notes and plate defaults); the name,
status, author and creation date stay as they are through Undo, so an
edit of only those records nothing.
The sheet strip only shows Auto Nest proposals; what it shows is
committed through Auto Nest, which is already recorded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drawing changes were unrecorded, so Undo skipped them or lumped them
into an anonymous "Change". Each is now one labelled step: Import
Drawings, Shape Library (menu and panel button), Drawing Library (what
the dialog added or re-quantified), Save to Drawing Library (the nest
keeps the drawing's new library link), Edit Drawings in the converter,
Drawing Properties, Delete Drawing and Clean Unused Drawings. Dropping a
drawing on a plate was already recorded as Add Part and is now tested.
The converter can change live programs while it loads, even when it is
cancelled; a cancel that did so now rolls the nest back to before the
converter opened instead of leaving those edits unrecorded.
Deleting a drawing threw when removing its parts emptied the trailing
plates, because the plate manager drops trailing empty plates while the
loop walked the live plate list; it walks a copy now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cutting edits were unrecorded, so Undo skipped them or folded them into
an anonymous "Change". Each is now one labelled step: Add Cut-Off, Move
Cut-Off (one step per drag), Automatic Cut-Offs, Auto Sequence (current
plate or all plates, only when the order changed), Set Sequence (per
click), Sequence by Path (the whole tool session; Backspace and Ctrl+Z
inside it still take back one line), Place Lead-In, Remove Lead-Ins (the
tool's menu, the plate and the nest commands), Cutting Parameters (an
edited lead-in panel when the tool closes), Plan Cutting and Clear
Lead-ins and Cut-offs.
Plan Cutting stages scrap cut-offs on the live plates before it plans,
so its scope opens with the staging and records only when the plan is
applied; closing without applying records nothing. Clearing applied work
is its own step and no longer warns that it cannot be undone.
Opening the lead-in tool used to give a plate without parameters the
defaults straight away; the plate now takes the tool's parameters with
its first lead-in, so opening and closing the tool changes nothing.
Undo no longer waits while the tool has a part picked: it ends the tool.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plate and clamp changes went unrecorded, so Undo skipped them or lumped
them into an anonymous "Change". Each is now one labelled step: Edit
Plate (only on OK), Rotate Plate, Resize Plate, Set Nest Default Plate,
Clamps and Support Grid (applying to the nest; saving machine defaults
stays outside the history), Remove Clamp / Put Clamp Back from the
plate's clamp menu, and Add/Move/Delete Clamp in Edit Clamps.
Edit Plate used to copy an empty plate's settings into the nest defaults
even when the dialog was cancelled; that now happens only on OK, so a
cancelled dialog changes nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Placement edits were only caught by the fingerprint safety net, so they
undid as an anonymous "Change" or folded into the next edit. Each now
records one labelled step: Fill (at the commit, so a stopped fill that
keeps nothing records nothing), Fill Area, Pattern Tile, Auto Nest (from
the kept proposal only; Make Nests tabs too), Clear Nest, Remove Empty
Plates and Center Parts. Clear Nest no longer warns that it cannot be
undone.
Pattern Tile onto a new plate created a plate beside the empty sentinel,
which the plate manager dropped at once, so the pattern landed on a
detached plate; it now fills the sentinel.
The undo tests share one harness that compares a text description of the
nest before an edit and after Undo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Whole-nest snapshots make undo safe without a hand-written inverse per
operation: each recorded edit stores one NestSnapshot in the document's
history, and Undo/Redo read one back and swap it into the open window.
- Document.History is reset with the opened nest; Save and database
saves mark the save point instead of clearing it.
- EditNestForm.BeginChange opens a scope: nested scopes merge into the
outermost, Complete commits one entry, and leaving it incomplete rolls
a changed nest back. No-ops are detected by the scope's changed flag,
not by comparing bytes (copies are not byte-stable).
- RestoreNest shares the per-nest binding with the constructor and keeps
the Document, the nest's identity, the plate index, the viewport and
the selection. It ends the action, closes Cutting Inspection, side
panels and the remnant viewer, rebuilds the PlateManager, reapplies
the view's cut-off settings and recolours the drawings, because each
of those holds or derives from the old nest's objects.
- An edit no scope recorded (Phase 3 sites) is detected by a cheap
fingerprint and committed as its own "Change" entry before a scope,
Undo or Redo, so it is never silently discarded; DEBUG builds also
warn about it on idle.
- Edit > Undo/Redo name the next entry. Ctrl+Z/Ctrl+Y/Ctrl+Shift+Z go
to focused text editors first, then to an action's own step-back
(Sequence by Path), then to the nest. They wait for jobs, fills,
background saves and busy actions, but not for a plain selection.
- Recorded: delete, drag, arrow nudges (coalesced), rotate, align,
push, expand spacing, add part (drop and clone), cut, add and remove
plate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The members group resumed layout only after the outer table had already
sized it, so its docked grid kept the default 240x150 until the form was
resized. Inner containers now resume before the table lays them out.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zoomed out, small parts and short cut-off segments piled their ids on each
other. As the CAD converter numbers entities, an id now shows only once its
part is big enough on screen to hold it: a part must be as wide and tall as
the id's text, a cut-off segment as long as the id's disc.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Typing customer, material, grade and thickness by hand let near-duplicate
spellings into the library, which then split drawings that should match.
The fields are now drop-downs of the values the library and the machine
material catalog already use, while still accepting new values; thicknesses
already used for the material are listed ahead of the standard gauges.
A library color could be set but never cleared back to the color scheme's,
so Automatic and Reset are added. The rotation start/end/step boxes gave no
sense of the range, so a dial shades it, ticks the angles the engines try
(via RotationPolicy) and lets either end be dragged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cut-off lines are painted after the parts, so the dashed line ran straight
through each segment's id, which sits on the cut. Cut-off segment ids are now
held back from the parts pass and drawn after the lines, over a disc of the
plate's fill color.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Grids opened at their designer widths and jumped a moment later, because
GridStyle waited for the first paint with rows before measuring them.
Columns now measure their header and first 50 rows directly: at handle
creation when the rows are already there, otherwise in a call posted when
rows arrive, which runs after the filling code and before the repaint.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The flat ten-row list squeezed the quadrant picker to 120x28 and gave no
hint of units or where the defaults are saved. Group the fields (General,
Plate Size, Quadrant, Spacing), lay the edge spacings out around a plate,
show in/mm suffixes, and convert the values when the units switch so a
48 in plate does not silently become 48 mm.
The footer says whether Save writes to this PC or the shared nest server,
and Save is disabled while the shared copy is read-only instead of
failing after the click.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every segment of a cut-off is its own part of the one cut-off drawing, but
its sequence label was placed from the drawing's whole program, so all of a
cut-off's segments stacked their numbers on one point. The view culls parts
outside the visible area, so zooming changed which segment drew last and the
shown number appeared to change. Each segment is now labelled at the middle
of its own cutting moves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Rot Start, Rot End and Step columns showed the drawing's radian
constraints as-is, so users had to type 1.5708 for 90 degrees. The grid now
shows and accepts degrees; rows keep the radian values, so an unedited row
passes the drawing's limits to the engine without a conversion round trip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Strip lines now stop at a full-length horizontal cut-off that clears the
parts instead of slicing the band beyond it. The desktop dialog and Plan
Cutting also propose their own horizontal separator when that band beats
the X tail (opt-in for API callers via KeepHorizontalRemnant); a kept X
tail beside the band becomes a corner piece whose separator stops there.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FillStrategyRegistry now holds a fixed, ordered list of the seven
built-in strategies (Pairs, Row, Column, RectBestFit, Extents, Linear,
TiltedRemnant, in their Order sequence) instead of reflecting over the
Engine assembly. LoadFrom and LoadPlugins are gone; nothing outside
tests called them, so outside IFillStrategy plug-ins were never loaded
by a shipped host and none are loaded now. IFillStrategy stays public.
The disabled set stays process-wide and keeps its Disable, Enable,
SetEnabled, Strategies, AllStrategies and DisabledNames behavior for the
Options form. DefaultPlateFiller still reads Strategies, so interactive
Fill, the fixed-strategy engines, Irregular's block catalog and private
plate fill, the cutout lattice fill and the brute-force runner all keep
honoring it.
PlateViewFillLifetimeTests drives fills through PlateView, which builds
its own filler, so a filler-level seam can't reach it. The registry gets
an internal UseForTesting hook that swaps the list until disposed, and
the WinForms test project can see Engine internals for it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When every drawing in a set starts with the same words, as in
"4980 A111 PT01", the set preview's labels were all cut short to the
same "4980 A111 P…". The preview now drops the leading words all names
share, cutting only at a space, '-', '_' or '.' and never emptying a
name, and notes the dropped prefix above the drawings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The set preview guessed row widths and settled the scale in four rounds,
which could stick at rows of minimum-width label cells and leave much of
a narrow pane empty. At a given scale, filling each tallest-first row as
far as the pane allows is the best row split, and the packed height only
grows with scale, so the layout now bisects for the largest scale that
fits. A 21-drawing set in a 400x590 pane goes from scale 1.14 with 345 px
used to 2.23 filling the height.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CL-707 config now declares sections, sentence-case labels and ranges,
so its dialog matches the CI Fiber one instead of the generic PropertyGrid.
The sectioned editor gains what the CL-707 config needs: optional (nullable)
numbers behind an enable box, editable tables for lists of simple records,
and a text field that suggests values from a table column (Selected library).
"Lead-in arc line 2 feedrate" is relabeled "Lead-in arc feedrate", which is
what #127 drives.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaterialLedger's Release lets a hold go, so a Released hold no longer keeps
a sheet for the nest; only Proposed, Approved and AwaitingCloseout holds,
the statuses ML counts against free stock, are open. The Has Been Cut
note's link pointed at /Nests/{id}, which ML does not serve; its nest page
is /Nests/Details/{id}.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each zoom step rebuilt every part's display paths from its CNC program,
and each drag step rebuilt the moved parts, which dominates for parts
with hundreds of holes. LayoutPart now keeps its paths in the drawing's
program frame and only maps them to the view on a zoom or move,
rebuilding when IsDirty is set or the program, rotation or manual
lead-ins change. Also caches the label StringFormat.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaterialLedger's /api/stock/opennest now resolves an OpenNest material
and grade through ranked acceptance rules. The client reads the new
spec rank, family, grade and finish and the item rank; an older ledger
that sends none of them deserializes as rank 1 with no label.
LedgerStockMapper groups drops only by identical size and spec, keeps
the ledger's order in rows and in each row's ItemCodes, and orders rows
by rank. Auto Nest's Source column shows the row's grade and finish
("A1011 P&O"); substitutes (rank above 1) read "A1011 P&O for HR" in
amber, name the substitution in their tooltip and still load ticked.
The engine still sees no rank.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Server nests in Database mode get a read-only status bar label comparing their
open MaterialLedger holds with the sheets they cut, e.g. "Ledger: 2 of 4 held,
2 short". Nothing writes to the ledger and nothing waits on it.
- MaterialLedgerClient.GetHoldsAsync reads GET /api/stock/holds?openNestNestId=
with the closed LedgerHoldsResult set; unknown status strings are kept. The
request plumbing is shared with GetStockAsync.
- LedgerHoldSummary (OpenNest.Data) counts Proposed/Approved/Released/
AwaitingCloseout holds against the plate quantities, skipping the trailing
empty plate as /sheets does.
- NestHoldStatus refreshes on server open, after save, after storage or
Options changes and on label click; it never polls. The tooltip lists holds
in nest units. File-mode, unsaved and ledger-less nests show nothing.
- Setting Has Been Cut in Nest Info with holds still open shows a non-modal
note linking to {ledgerUrl}/Nests/{id}. Posting is not gated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auto Nest on MaterialLedger stock now records which inventory item each
physical sheet uses, so ML can hold exactly those items instead of matching
by size.
- Core: Plate.StockItemCodes (entry i = sheet i of Quantity; empty = uncoded).
Core invalidates it: a resize clears it (turning the sheet keeps it), a lower
Quantity truncates it, a nest material/grade/thickness change clears every
plate's, ClearAll clears it and new plates never copy it.
- Desktop Auto Nest: after a kept proposal is committed, LedgerStockAssignment
deals each ledger row's codes to its plates in Nest.Plates order (bundles
repeat their code; clamp-removal variants use their base row). Rejected,
discarded or cancelled proposals never reach it. NestPipelineCommit.PairWithStock
pairs committed plates with their solved stock; the engine stays ledger-free.
- Plate list tooltip: "Stock: CODE (location)"; locations are display-only.
- nest.json: optional plate stockItemCodes, omitted when empty, read leniently.
- /api/nests/{id}/sheets: new plates[] { index, width, length, quantity,
stockItemCodes }; sheets[] unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auto Nest's Stock Options gets a Load from ledger button that reads the nest
material's free sheets and drops from MaterialLedger's API-key-protected
GET /api/stock/opennest. Ledger rows are request-local: the engine sees them as
ordinary NestPlateStock rows with ledger:{n} ids and finite quantities, and they
are never written to Nest.PlateOptions.
- OpenNest.Data/MaterialLedger: settings file, read-only client (X-Api-Key,
5 s timeout, closed LedgerStockResult set) and LedgerStockMapper (bundles and
sheets one row each, same-size drops grouped with ordered item codes, unknown
shapes and too-small items skipped, inch/mm conversion).
- Options: MaterialLedger URL and API key (DPAPI, CurrentUser) with Test.
- Auto Nest grid: Use, Qty and Source columns for every row; PlateOption gains
request-local Quantity and Id, which NestStockBuilder passes to the engine.
Ledger rows score by area; hand-typed costs stay saved.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>