Commit graph

453 commits

Author SHA1 Message Date
7486539b32 feat: worker compose adds capture profile (BMD DeckLink) and GPU env vars 2026-05-20 14:19:21 -04:00
a55c182be9 feat: docker-compose.gpu.yml overlay — NVIDIA GPU pass-through + NVENC worker 2026-05-20 14:19:02 -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
28a97e2ba3 fix(deploy): test-api.sh — skip capture 404 (sidecar/idle mode is normal) 2026-05-20 13:56:26 -04:00
5161644205 fix(capture): handle non-JSON responses from capture service gracefully 2026-05-20 13:55:06 -04:00
96ef569720 fix(deploy): test-api.sh — fix login POST, sequences 400, settings/ampp path 2026-05-20 13:54:30 -04:00
115c7340ee fix(deploy): test-api.sh — fix curl -f flag swallowing 4xx, fgrep for literal [, correct /auth/me path 2026-05-20 13:52:59 -04:00
4dd377e28d feat(cluster): add GET /:id/ping to probe node agent reachability and latency 2026-05-20 13:49:56 -04:00
3128ab43b3 feat(deploy): test-api.sh — API smoke test covering all major endpoints 2026-05-20 13:49:35 -04:00
0b49f28a80 feat(deploy): onboard-node.sh — one-command cluster node provisioning 2026-05-20 13:49:05 -04:00
0b255e063f feat(deploy): docker-compose.worker.yml for cluster worker nodes 2026-05-20 13:48:27 -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
e3cdf70883 feat(ui): Docker container management page — restart, stop, start 2026-05-19 23:57:23 -04:00
1e9710ce0c feat(editor): thumbnail images in media panel; Del=ripple, Shift+Del=lift 2026-05-19 23:56:23 -04:00
090452969c feat(api): register system + cluster routes; add self-heartbeat on startup 2026-05-19 23:50:19 -04:00
66844b93d3 feat(cluster): node registry API — heartbeat, list, deregister 2026-05-19 23:46:16 -04:00
bd8b492ff6 feat(db): cluster_nodes table for multi-server registry 2026-05-19 23:46:06 -04:00
910a906600 feat(system): Docker container management via Unix socket 2026-05-19 23:46:03 -04:00
89771a2380 feat(timeline): ripple delete on Del, extract/lift on Shift+Del 2026-05-19 23:45:41 -04:00
a5823effe9 feat(assets): add ?redirect=1 to thumbnail endpoint for img src use 2026-05-19 23:44:17 -04:00
36e668455f feat(editor): media-panel search, sequence duration badge, parseFloat guard
- Media panel gains a search input that filters the clip list in real time
  (case-insensitive match on display_name / filename)
- Timeline toolbar shows total sequence duration (e.g. 00:05:23;14) and
  frame rate, updated whenever clips change or a sequence is opened
- parseFloat() guard on state.seq.frame_rate so a NUMERIC string from
  Postgres never leaks into Timeline.render() / applyHistory()
2026-05-19 23:27:25 -04:00
4d0e715982 fix(sequences): coerce NUMERIC frame_rate to float in all API responses
node-postgres returns NUMERIC columns as strings by default.  Add a
mapSeq() helper that parses frame_rate to a JS float before any response
is sent.  Affected routes: GET /, POST /, PUT /:id, GET /:id.
2026-05-19 23:24:16 -04:00
bfc2649909 feat(editor): fps-aware render, FPS selector in new-seq dialog, keyboard help overlay
- openSequence() and applyHistory() now pass state.seq.frame_rate to
  Timeline.render() instead of hardcoded 59.94 — clips render on the
  correct frame grid for every sequence
- New-sequence panel gains a frame-rate selector (23.976 / 24 / 25 /
  29.97 / 30 / 50 / 59.94 / 60); createNewSequence() posts frame_rate
  to the API
- Press ? to open a keyboard shortcut help overlay; Escape to close
2026-05-19 23:20:10 -04:00
81c771a7be feat(jobs): replace polling with SSE EventSource for live job updates
- Drop setTimeout/scheduleRefresh loop in favour of EventSource on
  /api/v1/jobs/events (pushes every 2 s from the server)
- Refresh dot turns green on open, goes grey + "Reconnecting…" on error
  (EventSource auto-reconnects natively)
- Type-filter is now applied client-side against the full SSE payload so
  the dropdown change no longer triggers an HTTP round-trip
- killJob / retryJob / clearCompleted no longer call loadJobs(); the next
  SSE push (≤2 s) reflects the change automatically
2026-05-19 23:17:18 -04:00
16b8530d43 fix: include filename in search; add POST /cleanup-live to recover stuck live assets 2026-05-19 23:10:51 -04:00
8a2ef38326 fix: bulk-fetch jobs by state (no N+1 getState()); add GET /events SSE stream 2026-05-19 23:09:47 -04:00
d382c6b559 fix: EDL export uses sequence frame_rate for timecode (29.97/59.94 DF, others non-drop) 2026-05-19 23:09:17 -04:00
d21c61a8b2 fix: addClip uses s.fps instead of hardcoded TC.secondsToFrames (59.94) 2026-05-19 23:08:13 -04:00
b175eaf54c fix: clean up temp segment directory after conform job finishes 2026-05-19 23:06:54 -04:00
90bb0769e5 fix: correct editor service port typo (47435 → 7435) 2026-05-19 23:06:35 -04:00
07ded22f8e feat: video proxy streaming endpoint + editor drag-and-drop to timeline
- mam-api: add GET /api/v1/assets/:id/video streaming proxy that fetches
  from RustFS/S3 and pipes to browser with range-request support, bypassing
  direct S3 access from Chrome
- mam-api: fix /stream route to return /video proxy URL for both proxy and
  original-mp4 assets; return null cleanly for non-playable sources
- s3/client: set requestChecksumCalculation/responseChecksumValidation to
  WHEN_REQUIRED to suppress x-amz-checksum-mode header on signed URLs
- editor: fix loadSourceAsset to set state.sourceAsset even when no proxy
  exists (info toast instead of bail-out) so Insert/Overwrite still work
- editor: add drag-and-drop from media panel to timeline — items are now
  draggable, timeline container accepts drops and calls Timeline.addClip
  with the asset at playhead position
- editor: add tl-drag-over CSS highlight on timeline during drag
2026-05-19 22:47:33 -04:00
5019563c38 fix: override user-select:none on draggable media items to fix drag initiation
EditorInterface root div has select-none (user-select:none) applied globally
to prevent text selection during editing. Chrome/Safari refuse to start HTML5
drag-and-drop on elements that inherit user-select:none, which is why no
ghost image appeared, cursor never changed, and no dragstart events fired.

Fix: add select-text (user-select:text) to both draggable divs in
MediaThumbnail (list view and grid view). This overrides the inherited none
specifically on the elements that need to be dragged, without changing the
global UX behavior of the editor.
2026-05-19 14:45:47 -04:00