Commit Graph
332 Commits
Author SHA1 Message Date
stroblme e85b18092f Flow inputs carry an origin hint, run or panel
The Inputs editor and the canvas label show it, and the run forms leave
panel inputs out.
2026-10-15 10:08:46 +02:00
stroblme 43498037be PUT /panels/ carries a version and refuses a stale one with 409
The Panels dialog re-reads the list on 409. A panels.json without a
version reads as 0.
2026-10-15 10:07:50 +02:00
stroblme 290b9fa705 Superuser route to flush the metrics collector now
POST /observability/flush handles what the collector has queued and writes
it, so the soak harness no longer sleeps FLUSH_INTERVAL_S before clearing
its own rows.
2026-10-15 09:53:19 +02:00
stroblme 1f213460ad Audit shared-library source writes
A shared source goes live in every flow using it the moment it is saved, so
the write is recorded in the audit trail like a publish. Private source saves
stay drafts and are not audited.
2026-10-15 09:50:04 +02:00
stroblme 0004e4b9bd Retire a shared node in use with ?detach=true
DELETE /flows/library/{name} still answers 409 while nodes use the source.
With detach=true each of them keeps a copy of the code, in the published
flow and the draft, the source is deleted and the running users rebuild.
2026-10-15 09:48:47 +02:00
stroblme 96f4fa5a38 Warn when a node that runs no code names a device
A device on a node without source was accepted and silently ignored. The
build now reports it as ignored_device, an advisory issue.
2026-10-15 09:45:24 +02:00
stroblme 565d492f19 Give a rate-limit flush its own run, linked to the run that held the value
A flush ran its cascade under no id, so its executions and failures belonged
to no run. It now records a run with source "flush", and the holding run's id
travels on the queue item into a new `flow_run.parent` column, also on the
`/observability/runs` rows.
2026-10-15 09:37:30 +02:00
stroblme cfb9e53d68 Rename the trigger node type to debounce, migrating stored flows
The store rewrites `"type": "trigger"` to `debounce` in every published and
draft flow when it opens, bumps the version and commits once. No alias stays
behind, so `trigger` is now an unknown type.
2026-10-15 09:34:40 +02:00
stroblme afe4362bb2 Verify shoots the flow canvas and media tile from the Demo, not the media example
The canvas shot opens the Demo's music flow; the media shot reads the Demo's
Media screen, so neither needs the `camera` dashboard.
2026-10-15 08:36:38 +02:00
stroblme 8cfb0faca0 Merge remote-tracking branch 'origin/main' 2026-10-15 08:20:11 +02:00
Melvin Strobl 300d9017fd Merge remote-tracking branch 'origin/main' 2026-10-15 07:47:21 +02:00
stroblme bff20a9fb2 Endpoint labels sweep instead of pulse: left to right on a label publishing into the flow, right to left on one reading out of it, one pulse long, off under reduced motion; snapshot values are marked prior so catching up sweeps nothing 2026-10-15 00:23:01 +02:00
stroblme 9fb0e3ab90 Dashboard editor undo: ⌘Z / ⇧⌘Z over a 50-entry history of commits, folding keystrokes and the grid's own correction as the flow editor does 2026-10-15 00:07:58 +02:00
stroblme c9e38ede58 Stored state lists its keys, each with a two-press delete beside Clear 2026-10-15 00:04:03 +02:00
stroblme ddc281c81c Colour tile tests: the disc on the shared widgets panel for every look's screenshot, and a key's release sending rgb and hex 2026-10-14 23:59:24 +02:00
stroblme 6ca2a484ed Phone header: assistant button in the corner, gated on an available provider as the sidebar entry is; header triggers on the right at 44px 2026-10-14 23:41:30 +02:00
stroblme e35eb67a21 Locked slider dims its rail: :has() on the slider, since the rail comes before the input and no sibling selector reaches it 2026-10-14 23:41:29 +02:00
stroblme 4e08a97354 Stat unit sized against the hero numerals: dui-hero on the readout's outer span, so the unit's 0.4em is of the hero rather than the 14px body text 2026-10-14 23:41:28 +02:00
stroblme 2ac997ce37 ValueSource kind includes panel; Panels dialog no longer suggests the screen port openpanel does not serve 2026-10-14 23:32:32 +02:00
stroblme d423c47ca6 Socket snapshot carries the nodes waiting for a machine, so a reconnecting browser restores their queued dots 2026-10-14 23:31:54 +02:00
Melvin Strobl d33c18af55 Dashboard name pill opaque: the look's card colour with a hairline border, no blur 2026-10-14 22:19:34 +02:00
Melvin Strobl 09ce4798c3 Dashboard name pill on a round panel: 56 high, icon and title at 24, at most 280 wide 2026-10-14 22:16:00 +02:00
stroblme 8c50c22444 Add websocket node: client or served socket, listener or sender
ws:// and wss:// URLs dial out and hold a supervised connection; a path is
served under /hooks/<flow>/ with an optional secret. Outputs only listen,
inputs send. Frames are JSON keyed by port, with json_key and on_connect.
2026-10-14 18:42:19 +02:00
Melvin Strobl 210023b7e2 Round panel: the dashboards either side drawn in advance and live, on the face they open on, and dragged in up and down as faces are sideways; the name pill only on landing 2026-10-14 17:20:22 +02:00
Melvin Strobl d8e9fbda26 Round paging follows the finger: faces and dashboards on a track, swiped one to one with the next beside it, turned or sent back on release, rubber-banded at the ends; keys and dots slide the same track; the reading dot a smaller companion of the handle 2026-10-14 17:08:51 +02:00
Melvin Strobl c294789d85 Round faces: a bar as concentric arcs with a legend in the middle; larger title, gap line and face text; Read-only in the ring's gap; a round dashboard unpadded on a phone; reduced-motion ring assertion 2026-10-14 16:52:46 +02:00
Melvin Strobl bae4b15505 Marks as dots inside the track: ticks, a selector's options and a slider's reading on the track's midline and the ring's centre line, coloured by the fill or the handle over them; the selector ring fills to its option 2026-10-14 16:42:56 +02:00
Melvin Strobl 42c752c94e Dashboard motion: round dashboards page up and down, the ring eases to a notch or a reading, the slider tile to a value set elsewhere; reduced motion honoured by every tween; motion spec in the docs 2026-10-14 16:34:10 +02:00
Melvin Strobl 66e6c4b6ec Slider: the set value to its step's decimals; the reading marked on the track and on the ring; mark geometry in the docs 2026-10-14 16:00:53 +02:00
Melvin Strobl d05d3c4665 Slider reading in a tile: a line under the value in every look, row and fader; Beside it on every dashboard; tile geometry in the docs 2026-10-14 15:51:04 +02:00
Melvin Strobl 2008150692 Round dashboards: one face at a time, a face per widget type, paged by swipe, dots and keys; slider reading; face row in the editor 2026-10-14 15:24:25 +02:00
Melvin Strobl be3446cb16 Round dashboards: shape and ring, the ring drawn and turned in every look, Knob preset and face guide in the editor 2026-10-14 14:23:55 +02:00
Melvin Strobl 9bed078c41 Gauge: no value arc at the minimum
At 0 the value arc is a zero-length dash (pathLength 0), and its round
caps still painted a primary dot on the dial in every look. The arc is
now transparent while its fraction is not above 0. The widget spec puts
a gauge at 0 on its panel and checks it in each look; its tile count,
stale since the buttons widget, is 11.
2026-10-14 12:29:07 +02:00
Melvin Strobl 13a0c69edc Colour widget: commit the value being released
The brightness column changes and commits in one handler, so the commit
read the render's draft (still null) and sent nothing; the queued draft then
stuck and rode along with the next release. The pending colour lives in a ref
now. color-drag.spec gains a column drag.
2026-10-14 08:44:38 +02:00
Melvin Strobl 659799d1e5 Panel I/O: PanelDef.io ports, scoped publish and upload, I/O section in the Panels dialog 2026-10-13 21:10:54 +02:00
stroblme a93f865e91 Open in dashboard: searchable Command list 2026-10-12 22:07:17 +02:00
stroblme 530a4b602e Dashboard message picker: searchable combobox instead of a plain select 2026-10-12 22:06:31 +02:00
stroblme 4463007736 Dashboard palette: switch dashboard, publish, settings; ⌘S publishes 2026-10-12 22:05:39 +02:00
stroblme 88c80bdb60 Shared Dock, PublishButton, DiscardButton, DiscardDraftDialog for the flow and dashboard editors 2026-10-12 22:04:34 +02:00
stroblme 237b9d96c6 Button icon-touch/sm-touch sizes replace the repeated touch-target classes 2026-10-12 22:02:35 +02:00
stroblme 59272299f5 Dashboard add widget: searchable command palette with ⌘P, as on flows 2026-10-12 21:59:16 +02:00
stroblme d7c6e27a2a Embed widget: Image option scales a camera stream to the tile 2026-10-11 20:23:37 +02:00
stroblme 79e3908a76 Dashboard icons: add cctv 2026-10-11 20:20:54 +02:00
stroblme c1a6a89e13 Make alert dialog footer buttons 44px below md
The same treatment `ui/dialog.tsx` got: every footer button is a 44px
target on a phone; desktop keeps its sizes.
2026-10-07 09:32:07 +02:00
stroblme 7d6cc5b0bf Serve index.html no-cache on every route; check the theme script's CSP hash
`try_files` served the SPA fallback inside `location /`, so `/` and every
client route went out without `Cache-Control: no-cache`. The fallback is now
the last argument, an internal redirect to the exact no-cache location.

`src/csp.check.ts` recomputes the inline theme script's sha256 and fails
`bun run check` with the new value when the CSP no longer names it.
2026-10-07 09:32:06 +02:00
stroblme 8f3e229c8f Sandbox website tiles by default; opt into same-origin per widget
A website tile now runs in an opaque origin (allow-scripts, popups, forms).
Its new "Trusted site" setting adds allow-same-origin for sites that need
their own cookies and storage, and a trusted tile pointing at the origin the
app runs on (its own, or the hub's) shows a notice instead of the frame.
2026-10-07 09:31:49 +02:00
stroblme ed8aee2387 Authenticate sockets by header or one-time ticket instead of ?token= 2026-10-07 08:58:22 +02:00
stroblme 953a983919 Bind a worker's name and labels into its token; list and revoke tokens by jti 2026-10-07 08:42:14 +02:00
stroblme 9ef7f90dd8 Keep query-string tokens out of the uvicorn, nginx and Traefik access logs 2026-10-06 17:32:51 +02:00
stroblme 243d39b591 Give connectors a store that survives restarts, and a way to clear it
`ConnectorNode.store` keeps short strings per connector package in the
engine's database (`connector_state`, migration f8c3e5a91d27), so the nodes of
one package share them and `fluksio serve` needs nothing new: get, set and
delete, at most 64 kB a value and 256 keys a package. A superuser lists the
keys (never the values) and clears them through `/connectors/{node_type}/state`,
or under Stored state in a connector node's panel. Documented in the connector
contract.
2026-10-06 17:19:48 +02:00