@floless/app 0.23.1 → 0.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,13 +48,15 @@ in 3D (`steel-from-drawings`) → bake it out (an IFC file and/or native Tekla p
48
48
  to `demos/steel-from-drawings/` if you keep the editable copy in sync.
49
49
  6. **Bake the SAME scene into `steel-to-ifc` (the IFC bake-out), if it's installed.** Check
50
50
  `~/.aware/apps/steel-to-ifc/`. If present, replace the `scene:` mapping under that app's `bake-ifc`
51
- node `config.args` with the IDENTICAL scene (the installed copy and `demos/steel-to-ifc/` if
52
- present), then `aware app compile ~/.aware/apps/steel-to-ifc`. This keeps the exported IFC matching
51
+ node `config` (the `ifc` agent's `scene` input — NOT `config.args`; the app now calls the host-free
52
+ `ifc` AWARE agent, not an exec) with the IDENTICAL scene (the installed copy and `demos/steel-to-ifc/`
53
+ if present), then `aware app compile ~/.aware/apps/steel-to-ifc`. This keeps the exported IFC matching
53
54
  the 3D the user confirmed. (`steel-to-ifc` writes a real IFC file — IfcColumn/IfcBeam on the grid —
54
55
  openable in Tekla, SDS2, Revit or Navisworks; it never touches a Tekla model, so no Tekla needed.)
55
56
  7. **Bake the SAME scene into `steel-to-tekla` (native Tekla parts), if it's installed.** Check
56
57
  `~/.aware/apps/steel-to-tekla/`. If present, replace the `scene:` under that app's `bake-tekla` node
57
- `config.args` with the IDENTICAL scene (installed + `demos/steel-to-tekla/`), set `config.version`
58
+ `config` (the `tekla` `bake-scene` verb's `scene` input — NOT `config.args`; the app now calls the
59
+ first-class `bake-scene` verb, not an exec) with the IDENTICAL scene (installed + `demos/steel-to-tekla/`), set `config.version`
58
60
  to the user's RUNNING Tekla version (e.g. "2026.0" — the Open API connects to a version-specific
59
61
  channel, so a wrong version silently finds no model), then `aware app compile
60
62
  ~/.aware/apps/steel-to-tekla`. It creates a real Tekla member per element via the Open API (mode:
package/dist/web/aware.js CHANGED
@@ -2170,12 +2170,33 @@
2170
2170
  const $canvasMain = document.getElementById('canvas-main');
2171
2171
  const $dropTarget = document.getElementById('canvas-drop-target');
2172
2172
  const isFileDrag = (e) => !!e.dataTransfer && Array.from(e.dataTransfer.types || []).includes('Files');
2173
+ // An in-app node-card drag carries the card id as text/plain (set in the card's dragstart)
2174
+ // and no "Files" type. The canvas must accept its dragover, otherwise the browser paints the
2175
+ // default "no-drop" cursor over the topology while the card is in transit to the Templates
2176
+ // bar — the CSS `.agent-card.dragging { cursor: grabbing }` can't override it because the
2177
+ // browser owns the cursor during a native drag (#96). We mirror the card's
2178
+ // effectAllowed='copy' (and the bar's dropEffect) so it stays a steady copy affordance for
2179
+ // the whole drag instead of flickering between no-drop and copy.
2180
+ // text/plain-without-Files is a deliberate heuristic: a browser text-selection drag matches it
2181
+ // too, but over the canvas that is a harmless no-op (copy cursor in transit, swallowed drop) —
2182
+ // not worth coupling this to the card-only #fav-bar arming state to exclude.
2183
+ const isCardDrag = (e) => !!e.dataTransfer && !isFileDrag(e) && Array.from(e.dataTransfer.types || []).includes('text/plain');
2173
2184
  if ($canvasMain && $dropTarget) {
2185
+ // dragenter stays file-only on purpose: it shows the ".flo import" overlay ($dropTarget),
2186
+ // which must NOT appear for a node-card drag. dragover alone suppresses the no-drop cursor.
2174
2187
  $canvasMain.addEventListener('dragenter', (e) => { if (isFileDrag(e)) { e.preventDefault(); $dropTarget.classList.add('active'); } });
2175
- $canvasMain.addEventListener('dragover', (e) => { if (isFileDrag(e)) e.preventDefault(); }); // required to allow the drop
2188
+ $canvasMain.addEventListener('dragover', (e) => {
2189
+ if (isFileDrag(e)) { e.preventDefault(); return; } // required to allow the file drop
2190
+ if (isCardDrag(e)) { e.preventDefault(); e.dataTransfer.dropEffect = 'copy'; } // suppress the no-drop cursor (#96)
2191
+ });
2176
2192
  $canvasMain.addEventListener('dragleave', (e) => { if (!$canvasMain.contains(e.relatedTarget)) $dropTarget.classList.remove('active'); });
2177
2193
  $canvasMain.addEventListener('drop', (e) => {
2178
- if (!isFileDrag(e)) return; // let node-card drops fall through to the Templates bar
2194
+ // A card dropped on the bare canvas is a no-op: saving as a Template only happens on the
2195
+ // Templates bar (its own drop handler, which runs first as the drop bubbles up). Now that
2196
+ // the canvas accepts the dragover we must swallow that drop so the browser performs no
2197
+ // default action; a drop landing on the bar is already handled before it reaches here.
2198
+ if (isCardDrag(e)) { e.preventDefault(); return; }
2199
+ if (!isFileDrag(e)) return; // anything else: let it fall through untouched
2179
2200
  e.preventDefault();
2180
2201
  $dropTarget.classList.remove('active');
2181
2202
  importFlo(e.dataTransfer.files && e.dataTransfer.files[0]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floless/app",
3
- "version": "0.23.1",
3
+ "version": "0.23.3",
4
4
  "type": "module",
5
5
  "description": "Thin localhost host for floless.app — serves web/ and shells the aware CLI. No engine, no LLM.",
6
6
  "bin": {