Release planning

CadCraft 1.0 impact map

Every fix and feature lined up for 1.0, and what each one touches: which apps, and which layers of the stack.

ProjectCadCraft
Sheet0.10 impact
Items110
Date2026-11-09
51Fix
22Feature
0Spike
28Platform
0Site ops
8Sanity check
1Decision
≈ 319days in the written 0.10 plans
  • Planned 101 on the plan for the release it is filed under
  • Built 0 built and working in /lab (the dev builds). Whether the public has it is its reach: "in the lab", "Live" (the last gate) or "switched off"; see docs/REACH-LIVE.md
  • Partly built 1 part of it is built in /lab; the rest waits (see "Waits on")
  • Promised 0 the live site already says it is coming
  • Moved 0 moved here from an earlier release or wishlist
  • Found 0 bug found after a release shipped; fixed in a point release or the next one
  • Candidate 3 recommended in a spike or session log; owner to choose
  • Community please test 0 built and in /use; a Discord post gives the steps and the expected result and asks people to try it on their own devices, files or know-how
  • Decision Time 5 a decision, check, file, key, flag or go only you can give; folds into the list once answered

Built means built and working in the lab. Live means the public can use it, and is the last gate: 0 Built · Live, 0 Built · in the lab.

Sheet 1 · impact areas

Where 0.10 lands

How many items touch each app and each layer, by kind. One item can touch several areas, so the rows add up to more than the item count. Pick a row to filter the schedule below.

Impact areaFixFeatureSpikePlatformSite opsSanity checkDecisionAll
Apps
CadCraft 20 17 – 10 – 3 1 51
BimCraft 18 20 – 9 – 4 1 52
ModelCraft 19 20 – 10 – 3 1 53
MarkupCraft 12 16 – 9 – 3 1 41
TakeoffCraft 14 16 – 9 – 3 1 43
CivilCraft 21 18 – 10 – 4 1 54
DetailCraft 15 17 – 9 – 4 1 46
PartCraft 15 17 – 9 – 3 1 45
Studio – 1 – – – – – 1
SuperCad Studio – 6 – 6 – 1 1 14
Layers
Site and services 13 3 – 8 – 1 – 25
Desktop host – 1 – 1 – – – 2
App shell 5 15 – 8 – 2 1 31
App code 23 4 – 3 – – – 30
Our engines 8 – – 1 – 1 – 10
Vendor engines – – – – – – – 0
Drawing surface 3 – – – – – – 3
Help and words 2 1 – – – 1 – 4
Tests and tooling 2 1 – 2 – 3 – 8

Sheet 2 · schedule

Every fix and feature

Grouped by track. App chips carry each app’s layer colour; Studio is in ink. "Waits on" names what has to happen first; the small lines under it say who asked and where the item is written up.

Add an item Fork map (Rust and C++ forks) The roadmap

Issues sync every 10 minutes; last sync Nov 9, 2026 7:00 pm.

ItemWhatAppsLayersStatusDaysWaits onIssues
Performance roadmap — wave 3 60
FixPERF.20 Link to PERF.20Comment on PERF.20 Scale: every text format reader holds the whole file as one JS string (DXF, LandXML, OBJ, DAE, ASCII STL, USDA, the native JSON documents)

Measured: a 1 GB DXF and a 692 MB LandXML die in TextDecoder.decode ("Cannot create a string longer than 0x1fffffe8"); a 358 MB LandXML needs 4.9 GB and 27 s; a 10 MB DXF needs 364 MB (38 bytes of heap per file byte, parsed twice through dxf-model.js:65). Sites: dxf-decode.js:35-49 and dxf.js:68-74, civilcraft.js:2485 and xml.js:27, modelcraft io/obj.js:84, and JSON.parse(await file.text()) for every .modelcraft/.detailcraft/.civilcraft document (modelcraft.js:3210). The caps that exist (CivilCraft 200 MB, ModelCraft 200 MB, OBJ 64 MB) are honest and stay until the readers stream. Change: byte-level tokenizers over Uint8Array fed from Blob.slice with lazily decoded values and Float64Array/Uint32Array output, the way lib/ifc scanStep already works. DXF first (the reader is 1,563 lines, L), then LandXML (M), OBJ and ASCII STL (S each). Target: 100 MB DXF under 1 GB of memory, 1 GB files open with a progress bar instead of an error.

CadCraftModelCraftCivilCraft App codeOur engines Planned 12 – docs/0.9-sessions/perf-wave3/
FixPERF.24 Link to PERF.24Comment on PERF.24 Scale: autosave rewrites the whole document every couple of seconds of editing, in every app (extends PERF.5)

Measured and read: CadCraft autosave writes a full DWG (dwg-autosave.js:39 saveDwg; 4.8 s today, 66 s at 10x), BimCraft the full IFC bytes (bimcraft.js:585 to model.js save), MarkupCraft the whole PDF Blob (markupcraft.js:4715; TakeoffCraft stops at 64 MB, takeoffcraft.js:4313), ModelCraft the JSON (modelcraft.js:3883). On a big file autosave is the longest task the person sees while working. Change: journal autosave, keeping the opened file's bytes or handle plus the edits map (IfcFile already holds exactly that in memory), snapshots taken in a worker from transferred buffers, and a clear cap with a message above a size. Shared piece in the shell's app-autosave.js, one snapshot function per app.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App shellApp code Planned 4 – docs/0.9-sessions/perf-wave3/
PlatformPERF.26 Link to PERF.26Comment on PERF.26 Scale: text writers return one string, so exports stop at 512 MB and hold twice the output

DXF (dxf.js:1324, dxf2000.js:437), LandXML (landxml.js:227), OBJ, DAE, USDA (usda-write.js:33), GeoJSON and gcode writers each build one string and return it; a 1,000,000-entity DXF export is near the V8 string limit and the string plus its Blob is twice the output in memory. Change: writers that yield chunks into a WritableStream (createWritable on a file handle when the host offers one, else a Blob built from parts), with the same report object. Pairs with the streaming readers row.

CadCraftModelCraftCivilCraft App codeOur engines Planned 4 – docs/0.9-sessions/perf-wave3/
FixPERF.30 Link to PERF.30Comment on PERF.30 CadCraft: the Problems audit stringifies every entity after every change; DXF parses on the main thread; save ceilings at 1M entities

problems-cadcraft.js:45/52 shapeKey and auditIds cost 450 ms per edit at 100k entities (a JSON key per entity after each change): make the audit incremental over the touched ids. readDxf runs on the main thread (1.9 s at 100k; the DWG reader already has a worker, dwg/read-async.js): move the DXF reader into the same worker or stream it (the scale readers row). Save ceilings: writeDxf2000 dies at 1M entities with "Invalid string length", saveDwg takes 58 s and 4.2 GB of heap at 1M (over Chromium's default) and 6.1 s / 1.4 GB at 100k: chunked Blob output (the writers row) and the DWG writer in a worker (the autosave row, which measured the autosave write at 0.5 s for 10k and 5.8 s for 100k on the main thread).

CadCraft App code Planned 3 – docs/0.9-sessions/perf-wave3/
FixPERF.51 Link to PERF.51Comment on PERF.51 Apps: 56 to 69 % of the JavaScript fetched at start never runs; dynamic import boundaries per command, workspace and file format (extends PERF.4)

Measured with V8 precise coverage on the current releases (tools/perf/addons-coverage.mjs): 6.4 MB (CadCraft) to 10.2 MB (BimCraft) of decoded JS per start, 363 to 492 modules, and after 10 s of idle plus a first command only 31 to 44 % of those bytes have executed (CadCraft 33 %, PartCraft 35 %, DetailCraft 44 %); interaction adds 1 to 2 %. Every file of the entry's static import closure is fetched (284/284 in CadCraft, 432/432 BimCraft). Per app 23 to 33 modules ran under 15 %: 0.3 to 1.1 MB each app, for example the whole DWG/DXF save path in CadCraft (dxf.js 95 KB at 8 %, dwg/write.js 58 KB at 8 %, dxf2000.js, lisp/*), ModelCraft io.js 106 KB at 11 %, PartCraft ws-illustrate 96 KB, sketchview 79 KB, ws-script 66 KB, BimCraft res-ui 107 KB, CivilCraft eg-ui 47 KB and the river/rail/water UIs. modulepreload (PERF.4) hides latency but does not cut bytes. Change: import() boundaries at the command, workspace and file-format level (the command registry already knows each command's module, input-<slug>.js); start with the entry, the view, the model and the toolbar; keep modulepreload for what stays static. Target: 1.5 to 3 MB less to download, parse and compile before the first drawing.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App code Planned 10 – docs/0.9-sessions/perf-wave3/
FixPERF.71 Link to PERF.71Comment on PERF.71 Code: eight app mains are one closure of 2,500 to 5,800 lines each; split by topic

The AST pass over 5,500 modules (204,968 functions) found each app's main a single init closure: bimcraft init 5,759 lines with 1,557 nested functions, markupcraft 4,755, takeoffcraft 4,509, modelcraft 3,858, partcraft 3,770, cadcraft 2,898, civilcraft 2,848, detailcraft start 2,478. Everything inside shares one scope, so nothing can be dynamically imported (the start-up row), tested alone or reasoned about; this is the single biggest piece of sloppy structure the owner asked about. The report (docs/0.9-sessions/perf-wave3/code-quality.md Q1) outlines each by its inner functions and proposes modules per topic (BimCraft: IFC open/save, fd, QTO, find, clash, props, nine context modules; the same per app). L per app, M for CadCraft; one app per lab pass, behind the existing browser tests (tools/<app>-test, bin/test-<app>*.mjs).

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App code Planned 20 – docs/0.9-sessions/perf-wave3/
FixPERF.72 Link to PERF.72Comment on PERF.72 Code: 4,300 one-line functions that only pass arguments on (forwarder adapters rebuilt per sub-UI, help: () => t() closures)

tools/perf/quality-forwarders.mjs: 2,299 forwarders plus 2,007 thin wrappers, 278 getters, 401 constant-return functions, 2,683 one-use helpers. Worst: civilcraft.js 182 forwarders (units: () => units(), say: (m) => say(m), row: (...x) => row(...x) rebuilt for four sub-UIs, lines 157-165), bimcraft.js 143, partcraft.js 117, landscape-ui.js 52 (the same {edit, LS, U} trio six times), commands.js 147 help: () => t('…') closures plus seven ask wrappers. This is read and parse cost and noise, not runtime (inlined). Change: pass the declarations by name, one adapter object per app shared by its sub-UIs, help: 'key' resolved at display time. S per file.

CadCraftBimCraftCivilCraftDetailCraftPartCraft App code Planned 3 – docs/0.9-sessions/perf-wave3/
FixPERF.73 Link to PERF.73Comment on PERF.73 Code: copies that drifted and hand copies with no sync tool (six inflate implementations, xlsx.js in four variants, input-mouse.js in eight apps)

The byte-copy system works where a tool owns the copy (1,011 of 1,043 copy groups). Outside it: inflateRaw plus deflateZlib byte-identical in lib/3dm and lib/chip, six inflate implementations in lib and crc32 in 316 files (one lib/zip); xlsx.js six times in four hand-edited variants (one lib/xlsx); pdf-snap.js and takeoffcraft snap.js diverged; lib/walls ahead of bimcraft wall-square.js (two solvers for one wall); 31 drifted file pairs in all; whole-file hand copies with no tool: input-mouse.js in eight apps, wheel-pad.js in five, panes.js in three, params.js, framing.js, bcf.js, render-tools.js, carbon-factors.js, keynotes.js; CadCraft's m3d copy stale because its tool refuses to run (FX.143). Change: one owner per copy (lib/ or the shell) with a sync tool, and bin/test-sync-copies.mjs that runs every sync tool with --check (130 tools; some write without the flag: give them one first). Also the STEP string helpers S/E/L/B typed into five IFC writers (civilcraft three, detailcraft, partcraft) belong in lib/ifc/step.js.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App codeTests and tooling Planned 4 – docs/0.9-sessions/perf-wave3/
FixPERF.74 Link to PERF.74Comment on PERF.74 Code: shared utilities written hundreds of times: vector math 2,088 implementations, csv cell 431, point-in-polygon 243, esc 198, uid 188, download 163

tools/perf/quality-utils.mjs counted 6,943 implementations of 24 utility names (21,260 lines): vector math 2,088 (516 distinct bodies in 1,094 files), area 299, point-in-polygon 243 (identical clusters of 17, 12, 9, 8 and 6), bbox 190, lerp 69, clamp 68; text and bytes: esc 198, uid 188, download/saveBlob 163, csv cell 431, base64 59. The shell exports none of these; lib/units is the one shared table that is used everywhere. Change: lib/geom2d (vec, bbox, area, point-in-polygon, lerp, clamp) and a shell util.js (esc, uid, download, csv, base64) synced into the builds like host.js; mechanical replacement guided by the cluster list, with the quality scripts kept as the check so the count only goes down. Also shell-mount.js (a 48-line block identical in seven apps) and ui-util.js (eight variants of one 45 to 76 line file) become synced shell files, and the Studio Live stateCore plus diff and invert hand-copied in three apps and joinFromPage in six become a shell live-state.js.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App codeApp shell Planned 6 – docs/0.9-sessions/perf-wave3/
FixPERF.75 Link to PERF.75Comment on PERF.75 Code: deep clones by JSON round trip (205 sites, some inside merge loops) and 24 timers polling faster than once a second

Perf-relevant sloppiness confirmed by reading the top sites. Clones: 205 JSON.parse(JSON.stringify()) plus 112 clone helpers; takeoffcraft/a Discord member/learn.js clones inside merge loops (11 sites), clipboard.js and dwg-keep.js clone document-sized objects: structuredClone or a cloneDoc that copies only what changes. Timers: cadcraft live.js:763 and markupcraft live-ui.js:71 setInterval(push, 33) build presence and JSON.stringify it 30 times a second while idle; hazard-ui and people-ui animate with setInterval 33; countall-ui waits on a worker with a 20 ms poll; plc-ui 50 ms; 250 to 500 ms pollers elsewhere. Change: event-driven pushes with a dirty flag, requestAnimationFrame for animation, promise-based worker replies; a check that lists any setInterval under 1 s. Also: a console.log in bimcraft fem/frame-push.js:155 inside the solver loop, 12 new RegExp inside loops (takeoffcraft xlsx-read.js:74 on file open).

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App code Planned 2 – docs/0.9-sessions/perf-wave3/
FixPERF.76 Link to PERF.76Comment on PERF.76 Code: O(n squared) searches in kernel code (ModelCraft mesh ops, the shared m3d model, CivilCraft LandXML) and render functions that rebuild whole panels

Nested-loop searches with includes/some inside N by N loops: modelcraft mesh/ops.js:421 subdivide (also :471, :820, :915), m3d model.js:693, :778, :1637, :1957 (in both ModelCraft and CadCraft's copy), civilcraft landxml.js:298-322. These are the places a 10x model turns into a 100x wait; the 3D track's numbers (ModelCraft push/pull and undo at 500k faces) land here. Change: Sets and Maps keyed by vertex or id, measured before and after with tools/perf/scale-bench.mjs and the apps3d scripts. Render functions that rebuild and re-query the DOM on every call (196 querySelectorAll and 315 addEventListener inside render functions; takeoffcraft.js sheet list on every sheet switch, shell app-workspace.js, supercadcraft.js, cadcraft renderLayers and renderSelTotals): keyed children and incremental updates, measured on the 2D track's 2,000-sheet set.

CadCraftModelCraftTakeoffCraftCivilCraft App codeOur engines Planned 4 – docs/0.9-sessions/perf-wave3/
FixPERF.78 Link to PERF.78Comment on PERF.78 Code: dead modules and exports, god functions and cyclomatic hotspots beyond the mains

Confirmed dead: cadcraft addons/windows/lib/cutlist/cutlist.js (190 lines, a stale copy nothing imports), addons/trusscraft/lib/layout.js in four apps (tests only), modelcraft anim/skin-gpu.js, compute/parity.js twice, partcraft eng-data and eng-units stubs; 32 dead exports (about 54 KB: partcraft worker solvers, the openfoam runner) plus 26 orphan modules (about 141 KB). Name-level dead code across the 5,020 namespace and dynamic imports needs a bundler dry run (one tree-shake pass per app as a report, nothing shipped bundled). Hotspots: 120 functions over 300 lines and 618 with cyclomatic complexity 40 or more: readFamily 234, writeDwg 769 lines at 214 (plus convert 195, buildModelParts 182), vla-host get 207, validateItem 194, buildSite3D 190, dxf entityFrom0 187 and writeDxf 159, pdf-write writeMarkedUp 182, writeCivilIfc 702 lines, model-ui mountModel 1,804 lines, res-ui 1,407, shell app-panels 1,742 and app-settings 1,521. Change: table-driven dispatch for the entity switches, one module per panel section, delete the dead files; each behind the existing tests.

CadCraftBimCraftModelCraftCivilCraftDetailCraftPartCraft App code Planned 4 – docs/0.9-sessions/perf-wave3/
Interface roadmap — wave 1 26
FeatureUI.9 Link to UI.9Comment on UI.9 Command line anywhere: docked in the status strip, floating over the drawing, in its own window, or hidden

Duncan docks a command line in the status strip (statusbar.command, 0.9 DU.1), and it only hands its text to the command finder; the reference screenshot floats one over the drawing with history above it and a ▾ to open the log. CadCraft has a real command line of its own (cad-cmdline-09.md) in the classic layout only. Change: a commandline block of its own (places: stage-bottom, bottom, float, window; options history, log, width), filled by the app when it has one (CadCraft's, with its LISP and keyword prompts) and by the finder elsewhere; dragged by its grip to float anywhere over the drawing or to a window (UI.2/UI.3), remembered; Ctrl+9 shows/hides it as people expect; typed input goes to it from anywhere in the drawing when the layout says so (the classic rule). Works in every layout the person adds it to (UI.5), default in Drafting (UI.12) and Duncan.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App shellApp code Planned 3 – docs/0.9-sessions/interface-wave1/SUMMARY.md
FeatureUI.10 Link to UI.10Comment on UI.10 View overlays: view cube and compass, navigation bar, viewport label, axes icon, in the corners of the drawing

The drafting reference shows four things over the drawing itself: a view cube with a compass (N/E/S/W, "TOP", a WCS drop-down) top right, a navigation bar (a Discord member, zoom, zoom window, orbit) at the right edge, a viewport label "[-][Top][2D Wireframe]" top left, and an axes (UCS) icon bottom left. The engine has no corner places: view-top and view-bottom are full-width strips, and each app draws its own view cube (BimCraft's display modes beside the view cube, GH.3-B) or none. Change: four view-corner places (view-tl, view-tr, view-bl, view-br) in the format, each a small stack of overlays that never take pointer events outside their boxes; shared overlay blocks: viewcube (the app's 3D view orientation through the adapter's views API, with the compass and the named views), navbar (a Discord member, zoom extents, zoom window, orbit, walk from the registry), viewlabel (view name, display mode, scale, the [-] menu with the app's view commands), axes (the app's UCS/axes drawing, or the shared one). Each is a block a layout turns on, so Drafting (UI.12) and Sketch have them and Toolbox does not. Apps keep their own where they have more (BimCraft's display modes feed viewlabel). Test: each overlay present and placed in every app that has 3D, with the drawing's pointer events untouched between them.

CadCraftBimCraftModelCraftCivilCraftDetailCraftPartCraft App shellApp code Planned 4 – docs/0.9-sessions/interface-wave1/SUMMARY.md
FeatureUI.12 Link to UI.12Comment on UI.12 Drafting layout: menu bar, quick-access strip, ribbon, file tabs, view cube and navigation bar, command line, Model / Layout tabs, status toggles

The owner's reference screenshot is a 2D drafting workspace of the kind people who come from the long-established drafting program know: a menu bar (File Edit View Insert Format Tools Draw Dimension Modify Window Help), the quick-access strip with the workspace drop-down and search, a ribbon (Home Insert Annotate Parametric View Manage Output Add-ins Collaborate) with Draw / Modify / Annotation / Layers / Block / Properties / Groups / Utilities / Clipboard / View groups, file tabs (Start, Drawing1*, +), the drawing with a viewport label, a view cube with compass, a navigation bar and an axes icon, a floating command line, Model / Layout1 / Layout2 tabs and a status bar of toggles with the scale and a customize gear, in a dark chrome. None of our six built-ins is this one (docked and autorev are BIM ribbons, Vector and Sketch are palette layouts). This row: a seventh built-in, "Drafting" (assets/workspaces/drafting.ccworkspace.json; the name is ours, never the program's: the vendor-names rule), made only of the engine's blocks (menubar set "drafting", titlebar with quick + switcher + search, ribbon with more/slots/contextual, viewtabs open at view-top, the four view overlays, commandline float, viewtabs all at view-bottom, statusbar toggles + scale + customize, look.tone dark), listed in all eight apps and SuperCad Studio; CadCraft's adapter fills every slot, the other apps fill what they have (resolveLayout drops the rest with a note, as today). Every pixel from our tokens and icons: the layout copies where things are, never another program's artwork. Conformance test, help topic common/layout-drafting, es-MX and id words, a screenshot for /download and the release note.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App shellApp code Planned 4 UI.8 to UI.11 (the blocks it is made of); the owner's look at the mockup (UI.1). docs/0.9-sessions/interface-wave1/SUMMARY.md
FeatureUI.14 Link to UI.14Comment on UI.14 One icon family everywhere: the CadCraft set in every layout's ribbon, toolbar, toolbox, menu and palette, and the missing tools drawn

Today the set shows only in Duncan's tool rows and the Vector/Sketch palettes; the ribbon, the classic toolbars, the menu styles, the toolbox, the File menu, the pet palette and the status bar still show Bootstrap Icons or the app's own drawings, and about 270 specialist tools (the 2026-11-05 count: BimCraft MEP and families, CivilCraft alignments and water, DetailCraft connections, PartCraft features, MarkupCraft and TakeoffCraft marks) have no drawing in the set at all. Change: (1) the engine's tool() and the input registry's icon lookup ask the set first for EVERY block and the classic toolbars (iconKey → iconNode; Bootstrap only as the last fallback, logged in the lab so the missing list is real); (2) draw the missing tools in sets per app, each set reviewed on the UI.13 sheet, one agent per app with the rules, about 30 icons a day; (3) the eight apps' own toolbar drawings (CadCraft's 1.6 px line icons, BimCraft's, …) retire where the set covers them, kept under Settings › Icons "Each app's own drawings" for people who prefer them; (4) add-ons name icons from the set by key (api.icons) so an add-on's tools match. Measured at the end: zero Bootstrap fallbacks in the eight apps' default toolbars and ribbons in the lab; the number of set icons in the release note. Owner addition the same day (UI.22): the drawings themselves, the inventory and the icon repo are UI.22, the library; this row is wiring that library into every block, layout and app so one family shows everywhere.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraft App shellApp code Planned 8 UI.13 (the rules) first. docs/0.9-sessions/interface-wave1/SUMMARY.md
PlatformUI.22 Link to UI.22Comment on UI.22 The icon library: one drawing for every command, option and shell function in the eight apps, kept as data, the same in every layout and app

Owner 2026-11-09: "we need to create an entire library of icons (a task) that covers all of the application options, so that our icons are consistent regardless of the layout/app." What exists: app-workspace-icons.js holds 114 drawings on a 32-unit grid; about 270 specialist tools had no drawing by the 2026-11-05 count; the shell bar, More menu, panel tabs, status bar, menus and dialogs still use Bootstrap Icons (bi-*) and each app draws some of its own, so one command looks different from layout to layout and app to app. This row makes the library its own thing: (1) an inventory tool (tools/icons/inventory.mjs) reads every app's command registry, its toolbar, menu and toolbox definitions, the shell's bar buttons and panel tabs, Settings and the layout blocks, and writes docs/icons/INVENTORY.md: every command or option id, its apps, its drawing key or "missing"; nothing is drawn before the list exists; (2) the library in its own public repo (getcadcraft/icons, Apache-2.0, like every shared library): one SVG source per icon on the 32 grid with the five fills and two strokes as classes, names.json (key, name, aliases, the commands that use it), and a build that packs the set into app-workspace-icons.js, a sprite for the site and the add-ons kit, and the gallery data for UI.23; a hand edit of the packed file is refused by a check; (3) the drawings, under the UI.13 rules, in batches by app with the owner's look at each batch on the review sheet; shared verbs (move, copy, rotate, trim, offset, measure, zoom, undo) drawn once for every app; the shell's own set (home, find, help, settings, sun and moon, full screen, offline, problems, team, lessons, the AI and the panel buttons); (4) a lint in the release freeze: a registered command without a drawing, a drawing without a name, or a bi-* class left in shell or app chrome fails it; (5) the count in the release note (UI.18) comes from the inventory, never typed. Each app's own drawings are migrated or retired by its session.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraftSuperCad Studio App shellApp codeTests and tooling Planned 10 UI.13 (the owner's drawing rules) first; UI.14 wires the result into every block. docs/0.9-sessions/interface-wave1/SUMMARY.md
PlatformUI.25 Link to UI.25Comment on UI.25 One state language: an action enables or disables menu items, shows and updates panels, and selects on the canvas; every unit follows the same state

Owner 2026-11-09: "remember that actions can enable or disable menu items or make panels show/update as well as selecting objects on the canvas." What exists: every app wires this by hand in its own code: Properties refreshes on the app's selection event, the project tree selects through app code, the command registry (ccInput) knows commands but no enabled or visible condition, menus and toolbars are static until an app toggles classes, contextual ribbon tabs do not exist (UI.11), Problems and the add-ons read their own events. Change: (1) one state in the shell (ccState): selection (ids, kinds, count), mode (model / paper, 2D / 3D), the active view, the current layer and tool, document dirty; the apps publish into it through the host adapter; nothing else writes it; (2) declarations as data: a command, menu item, button, ribbon tab or panel says when it is enabled, visible or shown (enabled: selection.count > 0; visible: selection.kind == wall; show: problems.count > 0) in the registry and the layout file (format v2), never in per-app DOM code; the dock manager applies them: items dim, contextual tabs appear and go (UI.11), panels show or refresh, badges count; (3) the reverse channel: a unit acts on the canvas through the host (select, reveal, highlight), so a Browser row, a Problems line, a schedule row or a search hit selects and zooms to the objects with the same undoable selection the pointer makes; (4) one action path: every button, menu item and shortcut runs the registry command, so one command in a ribbon, a palette, a menu and the status bar has one enabled state and one label; (5) a check (bin/test-shell-state.mjs) opens every app, selects through the host and asserts Modify enabled, Properties updated, the Browser row lit, a declared contextual tab shown, then selects from the panel and asserts the canvas selection. The mockup's demo shows the behaviour (click a wall, or its Browser row). SuperCad Studio's host is the same contract.

CadCraftBimCraftModelCraftMarkupCraftTakeoffCraftCivilCraftDetailCraftPartCraftSuperCad Studio App shellApp code Planned 5 UI.21 (units) and UI.6 (format v2) carry the declarations; each app publishes its state in its own session. docs/0.9-sessions/interface-wave1/SUMMARY.md
Suggest an item

Anyone can send one; no account and no name needed. The team reads each idea, and the ones we take on appear on this page. Please leave out web addresses.