diff --git a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/components/TaskRunnerModal.tsx b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/components/TaskRunnerModal.tsx
index 83510613..5268b8f4 100644
--- a/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/components/TaskRunnerModal.tsx
+++ b/src/workspaces/officerdev/src/apps/FileBrowser/FileBrowserApp/components/TaskRunnerModal.tsx
@@ -485,10 +485,10 @@ const FolderSummary = ({ folder, keepAll = false, onKeepAllChange }: FolderSumma
- {majorityCount} of {fileCount} videos share this layout and will be converted.
+ {majorityCount} of {fileCount} videos share this layout and will be processed.
-
Different layout — convert these separately:
+
Different layout — run these separately:
{skipped.map((f) => (
-
@@ -567,11 +567,14 @@ const ScriptRunner = ({ taskDirName, autoInputs, context, cwd, entryType, filePa
const [includeFiles, setIncludeFiles] = useState('');
// Mixed-layout escape hatch: convert every video keeping all tracks (no picking, nothing skipped).
const [keepAll, setKeepAll] = useState(false);
+ // Task opts into the folder "keep every track, run over all" escape hatch via config.folderKeepAll.
+ const [folderKeepAll, setFolderKeepAll] = useState(false);
// Fetch task detail to get input definitions
useEffect(() => {
- client.get<{ inputs?: Record }>(`/tasks/${taskDirName}`).then((task) => {
+ client.get<{ inputs?: Record; config?: { folderKeepAll?: boolean } }>(`/tasks/${taskDirName}`).then((task) => {
const defs: Record = task.inputs ?? {};
+ setFolderKeepAll(task.config?.folderKeepAll === true);
setInputDefs(defs);
// Initialize from autofill context, then defaults
const initial: Record = {};
@@ -717,7 +720,7 @@ const ScriptRunner = ({ taskDirName, autoInputs, context, cwd, entryType, filePa
0 ? setKeepAll : undefined}
+ onKeepAllChange={folderKeepAll && hasSelectablePickers && folder.skipped.length > 0 ? setKeepAll : undefined}
/>
)}
{inputDefs && (