Commit graph

507 commits

Author SHA1 Message Date
3b1610a167 feat(ui): Dragonflight redesign — foundation JSX files: data.jsx 2026-05-22 08:13:00 -04:00
d5fd705d66 feat(web-ui): Z-AMPP core JSX files (data, icons, visuals, tweaks, shell, app): icons.jsx 2026-05-22 08:09:04 -04:00
a700124f50 feat(web-ui): Z-AMPP core JSX files (data, icons, visuals, tweaks, shell, app): data.jsx 2026-05-22 08:09:03 -04:00
10952df591 feat(web-ui): add styles-asset and styles-rest CSS: styles-rest.css 2026-05-22 08:07:16 -04:00
352d21496f feat(web-ui): asset detail + rest CSS: styles-rest.css 2026-05-22 08:06:40 -04:00
016adff949 feat(web-ui): asset detail + rest CSS: styles-asset.css 2026-05-22 08:06:39 -04:00
6befb0f46a feat(web-ui): Z-AMPP screen + component CSS: styles-modal.css 2026-05-22 08:03:57 -04:00
e655ccdf64 feat(web-ui): Z-AMPP screen + component CSS: styles-screens.css 2026-05-22 08:03:55 -04:00
2c88fb0a03 feat(web-ui): Z-AMPP design system CSS: styles-fixes.css 2026-05-22 08:02:36 -04:00
7b13d8bd0f feat(web-ui): Z-AMPP design system CSS: styles.css 2026-05-22 08:02:35 -04:00
68df3797f1 feat(web-ui): new design system CSS from Claude Design: styles.css 2026-05-22 08:02:07 -04:00
dccca554e0 Add Dragonflight React SPA design - index.html and CSS: styles-fixes.css 2026-05-21 23:53:21 -04:00
1b63429def Add Dragonflight React SPA design - index.html and CSS: index.html 2026-05-21 23:53:19 -04:00
87da3c0b58 feat: migrate cluster.html to wd-* design system 2026-05-21 23:17:48 -04:00
06551c66a6 feat: migrate editor.html to wd-* design system 2026-05-21 23:16:46 -04:00
136820c8f9 feat: migrate capture.html to wd-* design system 2026-05-21 23:16:29 -04:00
7c88692c1c feat: migrate recorders.html to wd-* design system 2026-05-22 03:16:27 +00:00
1e0015322c feat: migrate projects.html to wd-* design system 2026-05-21 23:15:57 -04:00
6176791174 feat: migrate player.html to wd-* design system 2026-05-21 23:15:18 -04:00
9ff80f8cc1 feat: migrate upload.html to wd-* design system 2026-05-21 23:14:51 -04:00
738d6298d2 feat: migrate edit.html to wd-* design system 2026-05-21 23:14:19 -04:00
a84bc3ecfe feat: migrate api-tokens.html to wd-* design system 2026-05-21 23:14:09 -04:00
daa203a43e feat: migrate index.html to wd-* design system 2026-05-21 23:13:13 -04:00
33d2a4004d feat: migrate jobs.html to wd-* design system 2026-05-21 23:12:58 -04:00
6e43ab30c2 rebrand: Recorders — Dragonflight, ember orange hue-32 2026-05-22 02:54:10 +00:00
cc45cc6347 rebrand: _primitives-smoke — Dragonflight brand 2026-05-21 22:52:12 -04:00
c31933a53c rebrand: Projects — Dragonflight, ember orange hue-32 2026-05-21 22:51:20 -04:00
efe005378a rebrand: Editor (in development) — Dragonflight, ember orange hue-32 2026-05-21 22:49:43 -04:00
5874c93956 rebrand: Editor — Dragonflight, ember orange hue-32 2026-05-21 22:49:00 -04:00
cd5fc3a05c rebrand: upload.html — Dragonflight title + sidebar 2026-05-21 22:44:25 -04:00
e0a2d0c95c rebrand: jobs.html — Dragonflight title + sidebar 2026-05-21 22:42:56 -04:00
4572c88f58 rebrand: capture.html — Dragonflight title + sidebar + hue-32 2026-05-21 22:40:48 -04:00
c752227e20 rebrand: api-tokens.html — Dragonflight title + sidebar 2026-05-21 22:39:20 -04:00
d4e5af459e rebrand: settings.html — Z-AMPP → Dragonflight 2026-05-21 22:35:33 -04:00
29360e38e8 rebrand: users.html — Z-AMPP → Dragonflight 2026-05-21 22:33:21 -04:00
e5f4c00729 rebrand: containers.html — Z-AMPP → Dragonflight 2026-05-21 22:31:41 -04:00
c6aeedb5fc rebrand: Dragonflight — cluster.html brand names 2026-05-21 22:27:36 -04:00
32cf6bf63e rebrand: Dragonflight — tokens.html brand names and footer text 2026-05-21 22:26:24 -04:00
024833cc95 rebrand: Dragonflight — login.html brand names, description text 2026-05-21 22:22:58 -04:00
b4642b3c78 rebrand: Dragonflight — index.html brand names, splash screen, accent colors 2026-05-21 22:22:12 -04:00
b82cc73cf1 rebrand: Dragonflight — home.html wordmark, accent gradients, brand names 2026-05-21 22:19:00 -04:00
873920d27f rebrand: Dragonflight — ember orange accent (hue 266→32) 2026-05-21 22:16:32 -04:00
37767f9939 fix(cluster): pickIp() only treats 172.17.x as docker bridge, not all of RFC1918 172.16/12 2026-05-21 21:27:15 -04:00
30b4deffc6 fix(capture): proper SDK 16 patch via upstream FFmpeg master diff
The previous patch_decklink.py mixed v14_2_1 versioned types (Fix 1 renamed the allocator class) with no-ops for SetVideoInputFrameMemoryAllocator + QueryInterface-around-GetBytes (Fixes 2 & 3). That inconsistency compiled but silently dropped every video frame: VideoInputFrameArrived saw _v14_2_1 allocator output but tried to read it via the SDK 16 unversioned IDeckLinkVideoBuffer path, and the SDK released the buffer before FFmpeg could consume it.

Bisected with the BMD-provided Capture sample at SDK 16 mode 5 (Hp29) which got frames cleanly, confirming the signal was fine and the bug was in FFmpegs decklink demuxer.

Fix: pull libavdevice/decklink_{enc,dec,common}{.cpp,.h} from upstream FFmpeg master (commits past 7.1 that fully rename every decklink interface to its _v14_2_1 versioned form) and apply that diff in reverse during build. Now build is internally consistent and frames flow.

Verified: SDI1 recorder on zampp2 hits 423 frames in 14s @ 29 fps, ProRes HQ at 91 Mbps.
2026-05-22 00:53:03 +00:00
96f0f58e68 capture: yadif deint=1 so progressive SDI passes through unchanged
Bug: yadif=mode=1 unconditionally doubled output framerate for SDI input. On 1080p29.97 progressive sources the encoder produced zero frames (time advanced, size stayed at 1KiB MOV header).

Fix: deint=1 makes yadif only process frames flagged as interlaced; progressive frames pass through at the source rate.
2026-05-22 00:14:02 +00:00
a8656fc1a8 capture: custom FFmpeg 7.1 build with DeckLink + D-Bus mounts + SDI deinterlace
Dockerfile is now a two-stage build that compiles FFmpeg from source with --enable-decklink against the Blackmagic SDK 16.x headers in services/capture/sdk/ (operator-supplied, gitignored). build-with-decklink.sh + patch_decklink.py drive the build.

docker-compose.yml mounts /dev/shm, /run/dbus, /run/systemd into mam-api, capture, web-ui so the BMD runtime can talk to the host.

capture-manager.js wraps SDI sources with -vf yadif=mode=1 (deinterlace).

recorders.html defaults to SDI source type now that we have a working DeckLink path.
2026-05-22 00:01:43 +00:00
1074104d34 fix(capture): FFmpeg 7.x DeckLink compatibility 2026-05-22 00:00:02 +00:00
bbed2a7059 fix(decklink): mount /dev/blackmagic in sidecar + remote node routing via node-agent
Two bugs fixed:
1. SDI capture sidecar never had /dev/blackmagic bound — ffmpeg opened the
   decklink input inside a container with no device nodes, so frame=0.
   Fix: local spawns now push '/dev/blackmagic:/dev/blackmagic' onto Binds
   when source_type='sdi'.

2. recorders.js always spawned sidecars against the local Docker socket
   (zampp1), even when a recorder's node_id pointed at zampp2 (where the
   card is). Fix: resolveNodeTarget() looks up the recorder's cluster node;
   if it's a different hostname the sidecar is spawned via a new
   POST /sidecar/start endpoint on the remote node-agent.

node-agent gains three new routes (all talk to the local Docker socket):
  POST   /sidecar/start         — create + start container (host network,
                                   privileged, /dev/blackmagic bind for sdi)
  DELETE /sidecar/:id           — stop + remove
  GET    /sidecar/:id/status    — inspect + poll capture service

docker-compose.worker.yml: add /var/run/docker.sock and LIVE_DIR to
node-agent so it can spawn sidecars, and document build-capture prerequisite.: recorders.js
2026-05-21 18:51:10 -04:00
8186b181cc fix(decklink): mount /dev/blackmagic in sidecar + remote node routing via node-agent
Two bugs fixed:
1. SDI capture sidecar never had /dev/blackmagic bound — ffmpeg opened the
   decklink input inside a container with no device nodes, so frame=0.
   Fix: local spawns now push '/dev/blackmagic:/dev/blackmagic' onto Binds
   when source_type='sdi'.

2. recorders.js always spawned sidecars against the local Docker socket
   (zampp1), even when a recorder's node_id pointed at zampp2 (where the
   card is). Fix: resolveNodeTarget() looks up the recorder's cluster node;
   if it's a different hostname the sidecar is spawned via a new
   POST /sidecar/start endpoint on the remote node-agent.

node-agent gains three new routes (all talk to the local Docker socket):
  POST   /sidecar/start         — create + start container (host network,
                                   privileged, /dev/blackmagic bind for sdi)
  DELETE /sidecar/:id           — stop + remove
  GET    /sidecar/:id/status    — inspect + poll capture service

docker-compose.worker.yml: add /var/run/docker.sock and LIVE_DIR to
node-agent so it can spawn sidecars, and document build-capture prerequisite.: index.js
2026-05-21 18:51:09 -04:00
539429c058 tokens.html: remove orphan sidebar-footer + duplicate /nav; use main flex wrapper 2026-05-21 16:40:28 -04:00
01a9d6c3db settings.html: remove orphan sidebar-footer + duplicate /nav; use main flex wrapper 2026-05-21 16:40:28 -04:00
Zac
ddd3b3eca1 Revert shell.css primitive rework (5 commits eea1ed6..a8f5bce) 2026-05-21 20:34:08 +00:00
a8f5bce9ee home.html: drop per-page body+shell rules (now in shell primitive) 2026-05-21 16:22:49 -04:00
683f0ff101 containers.html: drop inline shell hack (now in shell primitive) 2026-05-21 16:22:49 -04:00
47c0e1f933 users.html: drop inline shell hack (now in shell primitive) 2026-05-21 16:22:48 -04:00
6cad11f687 app.css: import new shell primitive; drop redundant html base rule (now in shell.css) 2026-05-21 16:22:47 -04:00
eea1ed6bcb shell.css: codify body + .wd-shell + .wd-main as a primitive (fix dead-space layout bug) 2026-05-21 16:22:46 -04:00
c6bcbbd214 web-ui(wave 2): migrate settings.html to new primitives
Surgical migration: stylesheet swap to /dist/app.css + sidebar markup
updated to wd-sidebar primitives. Page-specific content + JS unchanged.
2026-05-21 13:35:04 -04:00
e7495dfe29 web-ui(wave 2): migrate tokens.html to new primitives
Surgical migration: stylesheet swap to /dist/app.css + sidebar markup
updated to wd-sidebar primitives. Page-specific content + JS unchanged.
2026-05-21 13:35:03 -04:00
5650b279c3 web-ui(wave 2): migrate users.html to new primitives 2026-05-21 13:33:22 -04:00
596fe228ed web-ui(wave 2): migrate containers.html to new primitives 2026-05-21 13:33:22 -04:00
e0cfe80a9e web-ui(wave 2): migrate home.html to new primitives
Swap stylesheet to /dist/app.css. Sidebar markup ported to wd-sidebar /
wd-nav-item / wd-sidebar-* primitives (active state = leading accent dot).
Logout button promoted to wd-btn--ghost--sm--icon.

Hero (portrait, wordmark, tagline) and the 10 illustrated cards keep
their bespoke design — they're a brand moment. Hardcoded oklch values
in the inline style replaced with var(--accent-bright), var(--signal-bad),
var(--bg-base), var(--accent-border), var(--overlay), etc. wherever the
brand palette already provides them.

All JS ids preserved (assetCount, projectCount, recorderCount,
containerCount, nodeCount, jobCount, ingestCount, captureStatus,
tokenBurn, userAvatar, userName, userRole, logoutBtn, systemBuild).
loadStats() poll cycle unchanged.
2026-05-21 13:19:16 -04:00
16a34a2fad web-ui(wave 2): migrate login.html to new primitives
Keeps the hero + AMPP Safe stamp + brand panel. Right column now uses
wd-form-group / wd-input / wd-label / wd-btn primitives loaded from
/dist/app.css. All JS ids and handlers preserved verbatim (login-form,
setup-form, flash, show-setup, show-login).

Visual changes: tighter form spacing, focus rings use accent-subtle
ring, flash messages use the top-strip toast pattern.
2026-05-21 13:09:39 -04:00
75b94a5025 web-ui(wave 2): token cleanups from wave-1 code review
Promoted 14 new tokens (--accent-hover, --signal-{good,bad,warn}-hover,
--accent-bright, --thumb-black, --overlay, --shadow, --ease-out-{quart,expo},
--dur-{fast,normal,slide}, --z-topbar) and substituted every raw oklch /
cubic-bezier / hardcoded z-index occurrence in the 12 primitive files.

cubic-bezier appearances dropped from 8 files to 0 (only in tokens.css).
Bundle byte count: 138 KB -> 139 KB. Visual regression: zero (smoke page
still renders identically).
2026-05-21 17:08:02 +00:00
447b2b2b81 web-ui: add _primitives-smoke.html for wave-1 visual QA
Delete at end of wave 4 once every shell page has migrated to the new primitives.
2026-05-21 12:43:00 -04:00
3b89cf2d5f web-ui: fix wave-1 build pipeline (primitives missing from bundle)
Three bugs found during task 20 verify, all fixed:

1. Tailwind CLI does NOT read postcss.config.js. Switched Dockerfile to
   npx postcss + postcss-cli so the postcss plugin chain actually runs.

2. postcss-import was not installed but app.css uses @import for the
   primitive component files. Added postcss-import + cssnano (for prod
   minification under --env production).

3. @import statements must come BEFORE any other rules per CSS spec.
   app.css had @tailwind base/components ABOVE @import, so postcss-import
   silently skipped every component @import. Moved all @imports to the
   top, @tailwind directives below. Bundle went from 121KB with 0 wd-*
   classes to 138KB with 116 wd-* classes.

Also added tailwind safelist for wd-/is-/nav-dev-badge so the wave-2
migration of HTML files cannot accidentally tree-shake primitives.
2026-05-21 16:41:55 +00:00
f9236101b9 web-ui: wave-1 finish — self-host fonts + multi-stage Dockerfile
Fonts: Inter 400/500/600 + JetBrains Mono 400/600 (woff2 from rsms/inter and JetBrains/JetBrainsMono github).

Dockerfile: two-stage build. Stage 1 (node:20-alpine) runs tailwindcss --minify to emit public/dist/app.css. Stage 2 (nginx:alpine) ships the static result.

NOTE on task 19 (nginx caching for /dist /fonts): SKIPPED. The existing nginx.conf already caches *.css and *.woff2 for 1y immutable via the generic location ~* \\.(css|...|woff2|...)$ regex. Adding explicit /dist/ and /fonts/ blocks would be redundant.
2026-05-21 16:32:55 +00:00
6561cecf33 web-ui: fix corrupted .gitignore from earlier patch 2026-05-21 12:31:18 -04:00
a4bb6e7b0c web-ui: add node_modules + public/dist to .gitignore for wave-1 build 2026-05-21 12:30:56 -04:00
1f995c9029 web-ui: wave-1 foundation — services/web-ui/tailwind.config.js 2026-05-21 12:30:41 -04:00
891a8f82b7 web-ui: wave-1 foundation — services/web-ui/src/css/components/topbar.css 2026-05-21 12:30:40 -04:00
23ae848f5b web-ui: wave-1 foundation — services/web-ui/src/css/components/tokens.css 2026-05-21 12:30:40 -04:00
a16c235f71 web-ui: wave-1 foundation — services/web-ui/src/css/components/toast.css 2026-05-21 12:30:39 -04:00
e56704b69f web-ui: wave-1 foundation — services/web-ui/src/css/components/slide-panel.css 2026-05-21 12:30:39 -04:00
1c0ed05ac9 web-ui: wave-1 foundation — services/web-ui/src/css/components/sidebar.css 2026-05-21 12:30:38 -04:00
a6c9f88068 web-ui: wave-1 foundation — services/web-ui/src/css/components/motion.css 2026-05-21 12:30:38 -04:00
310eca0810 web-ui: wave-1 foundation — services/web-ui/src/css/components/list-row.css 2026-05-21 12:30:38 -04:00
a76e6b9a81 web-ui: wave-1 foundation — services/web-ui/src/css/components/form-controls.css 2026-05-21 12:30:37 -04:00
836a163cc8 web-ui: wave-1 foundation — services/web-ui/src/css/components/field-group.css 2026-05-21 12:30:37 -04:00
052a880b0f web-ui: wave-1 foundation — services/web-ui/src/css/components/empty-state.css 2026-05-21 12:30:36 -04:00
2f3e04cfc3 web-ui: wave-1 foundation — services/web-ui/src/css/components/card-operational.css 2026-05-21 12:30:36 -04:00
080f82e198 web-ui: wave-1 foundation — services/web-ui/src/css/components/card-asset.css 2026-05-21 12:30:36 -04:00
c08025eeb2 web-ui: wave-1 foundation — services/web-ui/src/css/components/button.css 2026-05-21 12:30:35 -04:00
30cb6663dd web-ui: wave-1 foundation — services/web-ui/src/css/components/badge.css 2026-05-21 12:30:35 -04:00
e256a771d5 web-ui: wave-1 foundation — services/web-ui/src/css/app.css 2026-05-21 12:30:34 -04:00
3df6a4434e web-ui: wave-1 foundation — services/web-ui/postcss.config.js 2026-05-21 12:30:34 -04:00
9d99811272 web-ui: wave-1 foundation — services/web-ui/package.json 2026-05-21 12:30:33 -04:00
fd955076dd web-ui: fix codec/settings panel clipping in recorders.html
Flex-child overflow footgun: .slide-panel-body had flex:1 and overflow-y:auto
but without min-height:0 it never shrank below content height, so the new
Master/Proxy codec blocks overflowed past the panel bottom and the footer
(Cancel / Probe / Save buttons) was unreachable. Lock the panel to 100vh,
add min-height:0 to the body. Also drop redundant margin-bottom on
.codec-block since the body already has gap spacing.
2026-05-21 14:10:24 +00:00
89ceef444e web-ui: include auth-guard.js on home.html and projects.html so the IN DEV badge renders on those pages too 2026-05-21 14:01:52 +00:00
00bf112b5a web-ui: replace editor.html with under-construction screen
The timeline editor isn't ready yet. Replace the 49 KB prototype page
with a clean construction screen (still rendering the standard sidebar
so users can navigate away). The 'IN DEV' badge on the sidebar nav item
is injected by auth-guard.js across all pages.
2026-05-21 09:59:29 -04:00
16a1fe604f web-ui: tag IN DEV pages in sidebar from auth-guard
Adds a tiny CSS rule + DOM patch that walks .nav-item links on every
page and appends an 'IN DEV' badge to those matching a known in-dev
page (currently just editor.html). Avoids touching all 13 HTML files
for the same single-line nav change.
2026-05-21 09:59:29 -04:00
f6c0594088 web-ui: rewrite recorders.html with tabbed codec settings + BMD card picker
- Replace flat codec dropdowns with Master/Proxy blocks, each with
  Video/Audio/Container tabs.
- Replace BM1/BM2 device dropdown with cluster-node picker plus
  inline BMDCards.render(...) SVG -- click a port to set device_index.
- Wire full codec field set (video bitrate, framerate, audio codec/
  bitrate/channels, container) end-to-end to /api/v1/recorders.
- Auto-hide bitrate input for profile-driven codecs (ProRes, DNxHR,
  PCM, FLAC); show for H.264/265/NVENC, AAC, AC-3, Opus, DNxHD.
- Resolve SDI source display in cards via /cluster/devices/blackmagic
  (hostname + model + port) instead of raw device index.

Finishes the pending item from
docs/superpowers/plans/2026-05-21-cluster-codec-revamp.md.
2026-05-21 09:47:32 -04:00
4a3a672cbe cluster: stable hostname for mam-api, jq-based smoke test
mam-api self-heartbeat now reads NODE_HOSTNAME so primary rows survive container restarts instead of resurrecting with the random container ID. test-cluster.sh rewritten to use jq (the python f-strings had a parse bug that silently passed the IP check) and limited the docker-bridge alarm to 172.17.x since the user LAN occupies 172.18.0.0/16.
2026-05-21 11:50:52 +00:00
d39f86d9c5 ui: add bmd-card.js — visual DeckLink port picker
Renders an inline SVG of the detected card (Duo 2 / Quad 2 / Mini
Recorder / Mini Monitor / UltraStudio 4K Mini, with a generic fallback)
showing each connector in its real physical position. Click to select.
Used by recorders.html for SDI source selection.
2026-05-21 00:19:51 -04:00
f4a83eedc4 capture-manager: dynamic ffmpeg args from per-recorder codec config
Adds a VIDEO_CODECS / AUDIO_CODECS / CONTAINER catalogue and a
buildEncodeArgs() that composes -c:v / -c:a / -b:v / -b:a / -r / -ac / -f
from the recorder's saved settings. Master and proxy each get their own
codec stack, both honour the container format chosen in the UI, and the
S3 keys now use the actual container extension instead of hardcoded mov/mp4.
2026-05-21 00:19:00 -04:00
4c65753358 recorders route: accept full codec field set + node/port pinning
POST/PATCH now persist all new codec columns via a whitelist. /start
forwards every codec setting to the capture container as an env var. The
live-asset created during /start now uses the recorder's container ext
(.mov vs .mp4 etc.) instead of always assuming .mov.
2026-05-21 00:17:45 -04:00
0efef0d81b cluster route: fallback IP from request + /devices/blackmagic endpoint
Heartbeat handler now overrides 172.x docker bridge IPs with the
request's source address when the request itself came from a real LAN.
Adds GET /devices/blackmagic that flattens every node's capabilities so
the recorder UI can show a card picker spanning the whole cluster.
2026-05-21 00:16:36 -04:00
485af25d4a capture bootstrap: forward every codec env var to captureManager.start 2026-05-21 00:16:03 -04:00
3b4af6ef11 node-agent: prefer NODE_IP and skip docker bridge interfaces
In bridge mode the agent was reporting the container's 172.x address
because the first non-internal interface in os.networkInterfaces() was
docker0. Now honours NODE_IP, skips lo/docker*/br-*/veth*/etc, and
down-ranks the 172.16-31 range so real LAN IPs win. Also exposes the
detected IP on /health for the onboarding script to print.
2026-05-21 00:15:03 -04:00
049beb8818 recorders: add granular codec / container / port columns
Expands recorders with video bitrate, framerate, audio codec / bitrate
/ channels, container format, and a node_id/device_index pair so the UI
can pin SDI recorders to a specific node + DeckLink port instead of
relying on a flat "BM1/BM2" index. capture-manager.js consumes these via
env vars and builds ffmpeg args from them.
2026-05-21 00:14:11 -04:00
a39c9831c5 cluster: dedupe rows + enforce unique hostname index
Migration 004 wrapped table creation in IF NOT EXISTS, so deploys with
a pre-existing cluster_nodes table never picked up the inline UNIQUE
constraint and accumulated duplicate hostnames on every container
restart. This migration purges older duplicates and adds the unique
index idempotently so the ON CONFLICT (hostname) upsert finally works.
2026-05-21 00:14:01 -04:00
066b9b17d3 feat: expand GPU transcoding settings (extension, framerate, rc mode, audio) 2026-05-20 23:41:42 -04:00
629022ab5f fix(worker): use npm install instead of npm ci — no package-lock.json present 2026-05-20 23:29:15 -04:00
cc8ee63639 fix(node-agent): replace express with built-in http — no external deps needed 2026-05-20 22:59:03 -04:00
21d31f1678 mam-api: switch base image to node:22-slim (glibc) so host nvidia-smi binary runs 2026-05-20 19:19:33 -04:00
74299629e6 feat: detect GPUs via nvidia-smi and populate cluster_nodes capabilities 2026-05-20 17:25:11 -04:00
a4b9b5be82 fix: prefer NODE_IP env var in getLocalIp() for Docker deployments 2026-05-20 16:16:09 -04:00
a926da1c30 feat: add settings key-value table migration 2026-05-20 15:57:23 -04:00
11e1de1cf8 feat: add S3 / Object Storage settings section 2026-05-20 15:55:34 -04:00
7032cee6b3 feat: call loadS3ConfigFromDb() on startup after migrations 2026-05-20 15:53:26 -04:00
02cfa68b92 fix(assets): replace static S3_BUCKET with getS3Bucket() for dynamic config 2026-05-20 15:49:40 -04:00
737e69d72f fix(upload): replace static S3_BUCKET with getS3Bucket() for dynamic config 2026-05-20 15:48:48 -04:00
ab504841c3 feat(settings): add S3 / object-storage settings routes (GET, PUT, test) 2026-05-20 15:48:14 -04:00
b1457f0aad feat(s3): dynamic DB-driven config with rebuildS3Client + Proxy export 2026-05-20 15:47:40 -04:00
beb58d3cd6 Add Settings nav link to sidebar 2026-05-20 15:07:36 -04:00
2f48d0243b Add Settings nav link to sidebar 2026-05-20 15:06:41 -04:00
cfdd0d1a55 Add Settings nav link to sidebar 2026-05-20 15:05:16 -04:00
0433fc8805 fix(home): prevent bottom cutoff — safe center + remove min-height: 100% 2026-05-20 15:01:50 -04:00
777fa7fc2b Add Settings nav link to sidebar 2026-05-20 14:56:04 -04:00
53392608e5 Add Settings nav link to sidebar 2026-05-20 14:51:37 -04:00
b7c7bb1662 Add Settings nav link to sidebar 2026-05-20 14:50:02 -04:00
dd1c40c9c8 Add Settings nav link to sidebar 2026-05-20 14:45:49 -04:00
7c37eababd Add Settings nav link to sidebar 2026-05-20 14:42:46 -04:00
53805f2c59 Add Settings nav link to sidebar 2026-05-20 14:37:38 -04:00
74e87359e2 Add Settings nav link to sidebar 2026-05-20 14:36:03 -04:00
5e2683aba7 Add Settings nav link to sidebar 2026-05-20 14:32:34 -04:00
fe921d0444 Add Settings nav link to sidebar 2026-05-20 14:29:41 -04:00
12a52c40c9 feat: settings.html — GPU transcoding, SDI capture routing, AMPP integration 2026-05-20 14:21:18 -04:00
76281b7564 feat: GPU worker Dockerfile using CUDA base with ffmpeg NVENC support 2026-05-20 14:18:55 -04:00
1725ec1de9 feat: settings routes for hardware inventory, GPU transcoding, capture service URL 2026-05-20 14:18:43 -04:00
dd3c2894f6 feat: cluster heartbeat stores capabilities (GPU/BMD hardware detection) 2026-05-20 14:18:22 -04:00
a941f609f0 feat: node-agent detects NVIDIA GPUs and Blackmagic DeckLink cards, reports in heartbeat 2026-05-20 14:18:07 -04:00
86d2960b60 feat: add capabilities column to cluster_nodes (migration 005) 2026-05-20 14:17:44 -04:00
5161644205 fix(capture): handle non-JSON responses from capture service gracefully 2026-05-20 13:55:06 -04:00
4dd377e28d feat(cluster): add GET /:id/ping to probe node agent reachability and latency 2026-05-20 13:49:56 -04:00
c5a358888b feat(node-agent): heartbeat agent — CPU/mem stats, health endpoint, bearer token auth 2026-05-20 13:48:18 -04:00
0bc1ac9161 feat(node-agent): add Dockerfile 2026-05-20 13:47:57 -04:00
feb78b8bcb feat(node-agent): add package.json for cluster heartbeat agent 2026-05-20 13:47:53 -04:00
86b80e043e fix: correct sidebar logo alt text in projects.html (Z-AMPP → Wild Dragon) 2026-05-20 09:17:05 -04:00
398ee8b932 fix: standardize sidebar icons in containers.html (containers/cluster/logout) 2026-05-20 09:15:14 -04:00
44277bced6 fix: standardize sidebar icons in cluster.html (containers/cluster/logout) 2026-05-20 09:14:11 -04:00
ea04b8f9e1 fix: standardize sidebar icons in editor.html (containers/cluster/logout) 2026-05-20 09:12:02 -04:00
ede55a8a5f feat(plugin): add seq info bar, export panel, and 2-row action bar styles 2026-05-20 00:38:59 -04:00
9ba3bf6f83 feat(plugin): add seq info bar, hi-res button, export panel to panel UI
- Active sequence info bar shows current Premiere sequence name
- Import Proxy / Hi-Res split buttons replace single Import button
- Export panel (hidden) slides in with seq name, project picker, clip count
- Export Timeline button in second action row triggers panel
2026-05-20 00:38:09 -04:00
16888d62e2 feat(plugin): proxy URL fix, hi-res import, import path tracking, timeline export
- Fix: /stream returns relative URL — prepend serverUrl before Node.js download
- Add: importAssetHires() calls /assets/:id/hires for original file
- Add: saveImportMapping() stores tempPath→assetId in localStorage so
  timeline export can match Premiere clips back to MAM assets
- Add: startExportTimeline() reads active sequence via exportTimelineData(),
  shows export panel with seq name + clip count
- Add: confirmExportTimeline() resolves paths→assetIds, upserts sequence,
  PUT /sequences/:id/clips
- Add: refreshCurrentSequenceInfo() shows active sequence name in info bar
2026-05-20 00:37:34 -04:00
5bb22c17c8 feat(plugin): add exportTimelineData() and getProjectItems() to ExtendScript
exportTimelineData() walks all video tracks in the active sequence and
returns clip source/timeline frame positions + file paths so the panel JS
can map them back to MAM asset IDs for timeline export.

getProjectItems() enumerates all ProjectItems with paths — useful for
rebuilding the import mapping after a Premiere restart.
2026-05-20 00:35:18 -04:00
a855ea7885 feat(api): add GET /assets/:id/hires endpoint for original file download
Returns presigned S3 URL + filename/ext/file_size for the original
hi-res source so the Premiere plugin can download and import it.
2026-05-20 00:34:18 -04:00
f7aedb1936 fix(ui): normalize sidebar — add Containers + Cluster to all 8 remaining pages 2026-05-20 00:22:57 -04:00
879c547e08 home: add Containers + Cluster cards, fix Editor link, extend loadStats 2026-05-20 00:02:48 -04:00
0c761d553c feat(ui): cluster node registry page — health, CPU, memory, deregister 2026-05-19 23:58:17 -04:00