* security(proxies): reserve outputs atomically
* proxies: ReservedOutput::file returns an Option instead of expect()
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Brandon Thomas <brandon@storyteller.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Raise a loaded project's next_id past the ids already in it (fixes#2809)
* Demo project: start new ids past its fixed transition and marker ids (#2809)
* Count transcript, source graphic and narration keys as ids in use on load (#2809)
* Format tests: a transcript's key raises next_id on load (#2809)
* Count ids that are only referenced (clip items, subclip parents, transition ends, sends, outputs, cameras, merged clips) on load (#2809)
* Scroll the timeline clip menu when it is taller than the screen (#2852)
The clip menu has about 35 items and ran off the bottom of short
screens with no way to reach the rest. It now scrolls inside the window,
as the panel menu already does.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Let the clip menu move up before it scrolls
The scroll area only took the height left below the pointer, so the menu
stayed where it was opened and scrolled even when the whole menu fit on
the screen, and the clip menu tests in clip_dialogs_ui could no longer
click the items past that height. Asking for the full height lets the
popup move up as before; it only scrolls when the screen is too short.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* #703: test that timeline track lines are visible and the playhead head is short
The lines between timeline tracks were drawn in the timeline background colour, so they could not be seen, nothing marked the top of the highest video track, and the playhead head covered the whole ruler. The tests check that separator-coloured lines run under every track and above the top video track, and that the head stays within the bottom 14 points of the ruler. Without the fix no such lines are drawn and the head is 38 points tall.
* #130: test that timecodes and menus use the Premiere-style type
The big timecodes were 15 pt semibold and the menu bar's menus used egui's default text size. The tests check that the timeline, program and reference timecodes are painted in 16 pt regular in the timecode colour, and that File menu items are drawn at 13 pt. Without the fix the timecodes are 15 pt semibold and the menu items are 12 pt.
* #1084: test that the Import captions file button label is legible in light mode
The label was always white, so it disappeared against the light grey button in light mode. The test shows the empty Captions tab in the dark and light themes and requires at least 3:1 contrast between the label and the button fill. Without the fix the light theme fails at 1.04:1.
* #1309: test that the sort arrow does not cover a sorted column's name
In a narrow List-view column the sort arrow was painted over the end of the clipped column name. The test narrows the sorted Name column and requires the name's visible clip rect to end left of the arrow. Without the fix the name stays visible up to x=67 while the arrow starts at x=60.
* #1084: hold the Import captions label to 4.5:1 contrast
The label is normal-size text (12 pt semibold), so WCAG AA asks for 4.5:1, not the 3:1 the test allowed. Both themes clear 4.5:1 today; with the fix reverted the label is at 1.04:1.
* #130: menu bar titles use the 13 pt menu text, like their menus
#130 styled the menus' items with theme::menu_style through MenuConfig, which egui applies to submenus only. The bar's own titles kept egui's default 12 pt, dimmer button text. MenuBar::style takes the same style, so the titles and their menus now share one size and colour, as in a native menu bar. The #130 test now checks the File title too; without this change it fails at 12 pt.
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
- Read and write CLI inputs/outputs on a blocking pool instead of stalling
the async runtime (rust:S7493).
- Document the FLAC STREAMINFO MD5 as the RFC 9639 integrity signature it
is, and validate the AV1 generator's spec path before reading it.
- Normalize the DCT basis literals that read as numeric suffixes.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Found while testing crates/tts-text/src/normalize.rs:416 (parse_time am/pm suffix) and :947 (parse_wordish a.m. branch); consumed by crates/tts-text/src/phonemize.rs:398 (is_single_letter)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/interchange/src/common.rs:68
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/tts-text/src/normalize.rs:78-97 (normalize, '-' / currency arms)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/captions/src/ttml.rs:358 (parse_time, offset-time branch) and :310 (decimal_ticks)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* security: validate CLI paths/args in dev tools (SonarCloud S2083/S8707/S8705/S7044)
Resolve and validate command-line path arguments before use, enforce HTTPS at
download sinks, and confirm path containment. Hardens local codegen/fetch tools
against path-traversal and command-argument-injection findings.
* ci: exclude dev tool scripts from SonarCloud coverage gate
The extract_tables.py codegen tools aren't part of the unit-tested surface;
exclude tools/, docs/, examples/ from coverage so the new-code coverage gate
doesn't block hardening-only changes.
The async screenshot() handler read and deleted the screenshot with blocking
std::fs calls, stalling the Tokio executor. Switch to tokio::fs::read /
tokio::fs::remove_file (await) and enable the tokio "fs" feature.