@floless/app 0.22.0 → 0.23.0
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.
package/dist/floless-server.cjs
CHANGED
|
@@ -52729,7 +52729,7 @@ function appVersion() {
|
|
|
52729
52729
|
return resolveVersion({
|
|
52730
52730
|
isSea: isSea2(),
|
|
52731
52731
|
sqVersionXml: readSqVersionXml(),
|
|
52732
|
-
define: true ? "0.
|
|
52732
|
+
define: true ? "0.23.0" : void 0,
|
|
52733
52733
|
pkgVersion: readPkgVersion()
|
|
52734
52734
|
});
|
|
52735
52735
|
}
|
|
@@ -52739,7 +52739,7 @@ function resolveChannel(s) {
|
|
|
52739
52739
|
return "dev";
|
|
52740
52740
|
}
|
|
52741
52741
|
function appChannel() {
|
|
52742
|
-
return resolveChannel({ isSea: isSea2(), define: true ? "0.
|
|
52742
|
+
return resolveChannel({ isSea: isSea2(), define: true ? "0.23.0" : void 0 });
|
|
52743
52743
|
}
|
|
52744
52744
|
|
|
52745
52745
|
// oauth-presets.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: floless-app-steel-from-drawings
|
|
3
|
-
description: This skill should be used to turn a structural steel drawing into an interactive 3D model in floless.app — the "Steel from Drawings" reader. Triggers on a pending floless `rebake` request for the `steel-from-drawings` app (queued from its "Re-read & re-bake ▸" button), or asks like "read this framing plan into 3D", "turn this steel drawing into a model", "bake my drawing into steel-from-drawings". It teaches the host AI to READ a steel drawing (PDF/image) with its own vision, extract a schematic 3D scene (grids, members, sizes, takeoff) in the viewer-3d scene schema, bake it INLINE into the app's `view` node, recompile, and ask the user to approve — all at COMPOSE time (no model in the run path, no API key). Also bakes the same scene into the `steel-to-ifc` companion
|
|
3
|
+
description: This skill should be used to turn a structural steel drawing into an interactive 3D model in floless.app — the "Steel from Drawings" reader. Triggers on a pending floless `rebake` request for the `steel-from-drawings` app (queued from its "Re-read & re-bake ▸" button), or asks like "read this framing plan into 3D", "turn this steel drawing into a model", "bake my drawing into steel-from-drawings". It teaches the host AI to READ a steel drawing (PDF/image) with its own vision, extract a schematic 3D scene (grids, members, sizes, takeoff) in the viewer-3d scene schema, bake it INLINE into the app's `view` node, recompile, and ask the user to approve — all at COMPOSE time (no model in the run path, no API key). Also bakes the same scene into the `steel-to-ifc` companion (universal IFC file) and the `steel-to-tekla` companion (native Tekla parts via the Open API, needs Tekla open). Triggers also on "export this to IFC", "bake to Tekla/SDS2/Revit", "bake into Tekla".
|
|
4
4
|
metadata:
|
|
5
5
|
version: 0.1.0
|
|
6
6
|
---
|
|
@@ -17,11 +17,12 @@ and no AI API key**: the brain is you, in the terminal (the FloLess thin-UI cont
|
|
|
17
17
|
and **for `steel-from-drawings` it supersedes the generic re-bake** — you bake the scene INLINE into
|
|
18
18
|
the `.flo`'s `view` node, not into `config.yaml`).
|
|
19
19
|
|
|
20
|
-
**Bake-out
|
|
21
|
-
file (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
**Bake-out companions.** Two sibling apps consume the SAME scene: **`steel-to-ifc`** writes a
|
|
21
|
+
universal **IFC** file (open in Tekla, SDS2, Revit, Navisworks; no Tekla needed), and
|
|
22
|
+
**`steel-to-tekla`** creates **native Tekla members** directly via the Open API (needs Tekla open).
|
|
23
|
+
When you bake a scene, bake the *identical* scene into whichever of these are installed (loop steps
|
|
24
|
+
6–7) so every output matches the 3D the user confirmed. The whole loop: **read the drawing → see it
|
|
25
|
+
in 3D (`steel-from-drawings`) → bake it out (an IFC file and/or native Tekla parts) → finish in your tool.**
|
|
25
26
|
|
|
26
27
|
> **Pasted a request?** If the user pastes a message beginning with a `[floless-request type=rebake
|
|
27
28
|
> id=…]` marker, that's a request copied from the FloLess Dashboard — resolve it via
|
|
@@ -51,11 +52,19 @@ step 6) so the IFC matches the 3D the user confirmed. The whole loop: **read the
|
|
|
51
52
|
present), then `aware app compile ~/.aware/apps/steel-to-ifc`. This keeps the exported IFC matching
|
|
52
53
|
the 3D the user confirmed. (`steel-to-ifc` writes a real IFC file — IfcColumn/IfcBeam on the grid —
|
|
53
54
|
openable in Tekla, SDS2, Revit or Navisworks; it never touches a Tekla model, so no Tekla needed.)
|
|
54
|
-
7. **
|
|
55
|
+
7. **Bake the SAME scene into `steel-to-tekla` (native Tekla parts), if it's installed.** Check
|
|
56
|
+
`~/.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
|
+
to the user's RUNNING Tekla version (e.g. "2026.0" — the Open API connects to a version-specific
|
|
59
|
+
channel, so a wrong version silently finds no model), then `aware app compile
|
|
60
|
+
~/.aware/apps/steel-to-tekla`. It creates a real Tekla member per element via the Open API (mode:
|
|
61
|
+
write, snapshot — Undo reverts the whole bake); needs Tekla OPEN with a model. Profiles fall back
|
|
62
|
+
to a sized rectangular section when the environment lacks the drawing's catalogue profile.
|
|
63
|
+
8. **Hand the approval to the user.** Tell them what you read (e.g. "read 6 columns + 8 beams on grids
|
|
55
64
|
A–C / 1–2, heights assumed 4.5 m — review in Inspect → Code, then Compile/Approve, then ▶ Run to
|
|
56
|
-
see the 3D; run **steel-to-ifc**
|
|
57
|
-
safety gate**. Never auto-run.
|
|
58
|
-
|
|
65
|
+
see the 3D; run **steel-to-ifc** for an IFC file or **steel-to-tekla** for native Tekla parts").
|
|
66
|
+
The human eyeballing the read in 3D **is the safety gate**. Never auto-run.
|
|
67
|
+
9. **Clear the request.** `DELETE http://localhost:<port>/api/requests/<id>` once done (if from one).
|
|
59
68
|
|
|
60
69
|
## Scene schema (the bake target — exactly what `viewer-3d` renders)
|
|
61
70
|
|
package/dist/web/app.css
CHANGED
|
@@ -1125,9 +1125,17 @@
|
|
|
1125
1125
|
overflow-y: auto;
|
|
1126
1126
|
display: grid;
|
|
1127
1127
|
grid-template-columns: 1fr 1fr;
|
|
1128
|
+
/* align-items:start so a collapsed card isn't stretched to match an
|
|
1129
|
+
expanded sibling in the same row (the accordion-in-grid pattern). */
|
|
1130
|
+
align-items: start;
|
|
1128
1131
|
gap: 6px;
|
|
1129
1132
|
padding-right: 4px;
|
|
1130
1133
|
}
|
|
1134
|
+
/* One grid cell per agent: holds the card header + its command list, so the
|
|
1135
|
+
commands nest directly under the picked card (see renderLibrary). */
|
|
1136
|
+
.lib-card { min-width: 0; }
|
|
1137
|
+
.lib-card.expanded .lib-item { border-color: var(--accent-dim); }
|
|
1138
|
+
.lib-card.expanded .lib-fav { transform: rotate(180deg); }
|
|
1131
1139
|
.lib-item {
|
|
1132
1140
|
background: var(--surface-2);
|
|
1133
1141
|
border: 1px solid var(--border-strong);
|
|
@@ -1162,6 +1170,7 @@
|
|
|
1162
1170
|
border-radius: 3px;
|
|
1163
1171
|
flex-shrink: 0;
|
|
1164
1172
|
line-height: 1;
|
|
1173
|
+
transition: transform 0.15s ease, color 0.15s, border-color 0.15s;
|
|
1165
1174
|
}
|
|
1166
1175
|
.lib-item .lib-fav.faved { color: var(--star); border-color: var(--star); }
|
|
1167
1176
|
|
package/dist/web/aware.js
CHANGED
|
@@ -3681,15 +3681,20 @@
|
|
|
3681
3681
|
renderLibrary = function renderLibraryReal() {
|
|
3682
3682
|
const q = ($libSearch.value || '').toLowerCase().trim();
|
|
3683
3683
|
const items = agentCatalog.filter((a) => !q || a.id.toLowerCase().includes(q) || (a.kind || '').toLowerCase().includes(q));
|
|
3684
|
+
// Each agent is ONE grid cell: the card header + its (lazy) command list live
|
|
3685
|
+
// in the same `.lib-card`, so expanding nests the commands directly under the
|
|
3686
|
+
// picked card instead of scattering them into a neighbouring grid slot.
|
|
3684
3687
|
$libList.innerHTML = items.map((a) => `
|
|
3685
|
-
<div class="lib-
|
|
3686
|
-
<div class="
|
|
3687
|
-
<div class="
|
|
3688
|
-
|
|
3688
|
+
<div class="lib-card" data-agent="${escapeAttr(a.id)}">
|
|
3689
|
+
<div class="lib-item">
|
|
3690
|
+
<div class="info">
|
|
3691
|
+
<div class="name">${escapeHtml(a.id)} <span style="color:var(--text-dim);font-weight:400">v${escapeHtml(String(a.version))}</span></div>
|
|
3692
|
+
<div class="meta">${escapeHtml(a.kind || 'agent')} · ${a.commands} command${a.commands === 1 ? '' : 's'} · ${a.skills} skill${a.skills === 1 ? '' : 's'}</div>
|
|
3693
|
+
</div>
|
|
3694
|
+
<button class="lib-fav" data-expand="${escapeAttr(a.id)}" data-tip="Show commands">⌄</button>
|
|
3689
3695
|
</div>
|
|
3690
|
-
<
|
|
3696
|
+
<div class="lib-commands" id="cmds-${escapeAttr(a.id)}" hidden></div>
|
|
3691
3697
|
</div>
|
|
3692
|
-
<div class="lib-commands" id="cmds-${escapeAttr(a.id)}" hidden></div>
|
|
3693
3698
|
`).join('') || '<div class="empty-state">No agents match.</div>';
|
|
3694
3699
|
$libList.querySelectorAll('[data-expand]').forEach((btn) => {
|
|
3695
3700
|
btn.onclick = () => expandAgent(btn.dataset.expand);
|
|
@@ -3699,8 +3704,10 @@
|
|
|
3699
3704
|
async function expandAgent(id) {
|
|
3700
3705
|
const box = document.getElementById(`cmds-${id}`);
|
|
3701
3706
|
if (!box) return;
|
|
3702
|
-
|
|
3707
|
+
const card = box.closest('.lib-card');
|
|
3708
|
+
if (!box.hidden) { box.hidden = true; if (card) card.classList.remove('expanded'); return; }
|
|
3703
3709
|
box.hidden = false;
|
|
3710
|
+
if (card) card.classList.add('expanded');
|
|
3704
3711
|
box.innerHTML = '<div class="cmd-desc">loading…</div>';
|
|
3705
3712
|
try {
|
|
3706
3713
|
const { agent } = await api(`/api/agent/${encodeURIComponent(id)}`);
|