No internet connection
  1. Home
  2. How to
  3. Logic Pro

Importing to Mix Template in Logic Pro - assistance required

By Mr Jake E Skinner @Mr_Jake_E_Skinner
    2025-03-25 16:31:43.435Z

    I'm looking for help with a Macro to speed up the process of importing tracks from my tracking project into my mix template in Logic Pro. This Loom video explains in more detail.

    https://www.loom.com/share/f77c944f9a8f47e3bd56681244fca2f1

    Thanks in advance!

    • 24 replies

    There are 24 replies. Estimated reading time: 46 minutes

    1. Matthew Brabender @Matthew_Brabender
        2025-03-25 19:43:34.178Z

        Unhelpful post from me, but interested in what you/others find. I've looked into macros for importing into a template several times but have not had any luck with streamlining the process. I think some of the problems is that there are no real keyboard shortcuts in Logic for this process so it relies on mouse position/clicks and Logic has no real function to get track names. And if you are anything like me, you'll have tracks in the recording project that you don't import into the mix template.
        I'm wondering if looking at the import in the opposite way might be easier .... as in import template tracks / busses etc into the recording project. I would still require manual shuffling though.

        My current process is I'll import tracks into the template all in one go, manually move each track to the right spot and then have a bunch of SF buttons that can change the output , colour etc

        1. Kitch Membery @Kitch2025-03-25 20:25:02.678Z

          Hi @Mr_Jake_E_Skinner & @Matthew_Brabender

          This is a really cool workflow idea that I should investigate. I'll take a look at this later in the week and see if it's possible. :-)

          And Jake, thanks for the video, it was really helpful.

          Bump this thread on Monday if you don't hear from me.

          1. Mr Jake E Skinner @Mr_Jake_E_Skinner
              2025-04-02 13:54:11.931Z

              Hi Kitch,

              Just bumping this post (as requested!)

              I look forward to your insight on this!

              1. Kitch Membery @Kitch2025-04-02 21:54:27.414Z

                Hi @Mr_Jake_E_Skinner

                Thanks for bumping the thread. I've started working on it, it's a tricky workflow to automate, so I shall keep you posted. :-)

            • Kitch Membery @Kitch2025-04-03 23:05:18.981Z

              Hi @Mr_Jake_E_Skinner, @Matthew_Brabender & @Alex_Oldroyd8

              I'm making progress... But still need to do a bit of work to make it robust... thought I'd share my progress in case you thought I'd forgotten about it.

              Here is a video of it in action... Select the matching track name in the Mixing project that matches a track name in the Tracking project. Then run the script.

              Will hopefully have more time to get this over the line next week.
              Woo!

              1. Matthew Brabender @Matthew_Brabender
                  2025-04-04 04:58:32.582Z

                  Wow! That must have taken some serious thinking! Nice work!

                  1. In reply toKitch:
                    AAlex Oldroyd @Alex_Oldroyd8
                      2025-04-04 10:09:35.586Z

                      god damn! i'm excited

                    • Mr Jake E Skinner @Mr_Jake_E_Skinner
                        2025-04-04 13:20:37.137Z

                        Awesome Kitch! I can't wait to try this out!

                        Would it work the other way round too? I.e selecting the tracks that you want to import and have them automatically go to the correct tracks in the template?

                        1. Kitch Membery @Kitch2025-04-04 16:51:35.110Z

                          Hi @Mr_Jake_E_Skinner

                          In my current implementation, it will not work the other way around, unfortunately. But if I find a way I'll let you know. :-)

                        2. Kitch Membery @Kitch2025-04-16 17:55:12.272Z

                          Hi @Mr_Jake_E_Skinner, @Matthew_Brabender & @Alex_Oldroyd8,

                          Select the tracks (in the tracks area) that you want to import matching tracks to, then run the script.

                          The script will ask for the location of the session you want to import from, and then it will proceed to import the tracks.

                          It will no doubt need some work, but here it is for now.

                          const logic = sf.ui.logic;
                          logic.appActivateMainWindow();
                          
                          const mainWindow = logic.mainWindow;
                          mainWindow.invalidate();
                          
                          const sessionName = mainWindow.getString("AXTitle");
                          const sessionPath = decodeURIComponent(mainWindow.getString("AXDocument")).slice(0, -1);
                          const sessionDirectory = sessionPath.split("/").slice(0, -1).join("/") + "/";
                          
                          const browsersGroup = mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first;
                          const browsersPanel = browsersGroup.groups.whoseDescription.is("All Files").first;
                          
                          function getSessionDirectoryPath() {
                              try {
                                  // Session Path
                                  const sessionDirectoryPath = decodeURIComponent(mainWindow.invalidate().getString("AXDocument")).slice(0, -1).replace("file://", "");
                                  return sessionDirectoryPath;
                          
                              } catch (err) {
                                  throw `There was an error fetching the Session Directory Path`;
                              }
                          }
                          
                          function getLogicRowElementByTrackName(trackName, column) {
                              const allFilesTable = browsersPanel.scrollAreas.first.tables.first;
                              const rows = allFilesTable.children.whoseRole.is("AXRow");
                          
                              const rowTitles = allFilesTable.groups.first.children;
                              const columnLookupTable = rowTitles.map(c => c.title.value);
                          
                              const targetRow = rows.find(c => c.textFields[columnLookupTable.indexOf("Name")].value.value === trackName);
                          
                              return targetRow.children[columnLookupTable.indexOf(column)];
                          }
                          
                          function getTrackName(track) {
                              try {
                                  const trackDescription = track.getString("AXDescription");
                                  const trackName = trackDescription.match(/“([^"]+)”/)[1];
                          
                                  return trackName;
                              } catch (err) {
                                  throw err
                              }
                          }
                          
                          function getSelectedTracks() {
                              const trackHeadersGroup = mainWindow.invalidate().trackHeadersGroup;
                              return trackHeadersGroup.getElements('AXSelectedChildren');
                          }
                          
                          function focusTrack(track) {
                              const hasFocusBtn = track.radioButtons.first;
                          
                              // Focus track
                              hasFocusBtn.elementSetAttributeValue({
                                  attributeName: "AXFocused",
                                  attributeValue: true
                              });
                          
                              hasFocusBtn.elementClick();
                          }
                          
                          function doForEachSelectedTrack({ action }) {
                              const selectedTracks = getSelectedTracks();
                              const firstSelectedTrack = selectedTracks[0];
                          
                              selectedTracks.forEach(track => {
                                  focusTrack(track);// Focus track
                          
                                  try {
                                      action(track);
                                  } catch (err) {
                                      throw err;
                                  } finally {
                                      focusTrack(track); // Refocus Track
                                  }
                              });
                          
                              focusTrack(firstSelectedTrack); // Focus first track
                          }
                          
                          function trackFunction(track) {
                              try {
                                  const trackName = getTrackName(track);
                                  const contentCheckbox = getLogicRowElementByTrackName(trackName, "Content");
                                  const replaceButton = browsersPanel.buttons.whoseTitle.is("Replace").first;
                          
                                  // Enable focus for checkbox
                                  contentCheckbox.elementSetAttributeValue({
                                      attributeName: "AXFocused",
                                      attributeValue: true
                                  });
                          
                                  // Enable Content Checkbox
                                  contentCheckbox.elementClick({ actionName: "AXPress", onError: "Continue" });
                                  sf.waitFor({
                                      callback: () => contentCheckbox.invalidate().value.intValue === 1, // Wait for checkbox to becom active
                                      timeout: 1000
                                  }, `Failed waiting for checkbox to be selected`);
                          
                          
                          
                                  replaceButton.elementClick({ actionName: "AXPress" });
                          
                              } catch (err) {
                                  throw err
                              }
                          }
                          
                          function refreshAllFilesPanel() {
                              const allFilesRadioButton = mainWindow.radioGroups.first.radioButtons.whoseDescription.is("All Files").first;
                          
                              const allFilesGroup = mainWindow.groups.find(g => {
                                  return g.children.first.getString("AXDescription") === "All Files"
                              }).getFirstWithDescription("All Files");
                          
                              const allFilesSubGroup = allFilesGroup && allFilesGroup.groups.whoseDescription.is("All Files").first;
                              const computerBtn = allFilesSubGroup.groups.find(g => g.buttons.first.getString("AXHelp") === "Computer").buttons.first
                          
                              if (computerBtn.exists) {
                                  computerBtn.elementClick();
                              }
                          }
                          
                          function navigateToTargetProjectPath({ targetProjectPath }) {
                              // try {
                              const logic = sf.ui.logic;
                              logic.appActivateMainWindow();
                          
                              logic.menuClick({ menuPath: ["File", "Import", "Logic Projects…"] });
                          
                              const importWindow = logic.windows.whoseTitle.is("Import").first;
                          
                              sf.waitFor({
                                  callback: () => importWindow.invalidate().exists,
                                  timeout: 1000
                              }, `Failed waiting for`);
                          
                              sf.wait({ intervalMs: 200 });
                          
                              const importButton = importWindow.buttons.whoseTitle.is("Import").first;
                          
                              sf.keyboard.press({ keys: "slash" });
                          
                              // Required wait for "Go To" Sheet.
                              sf.wait({ intervalMs: 100 });
                          
                              const sheet = importWindow.sheets.first;
                          
                              sheet.elementWaitFor();
                          
                              const goToTextField = sheet.textFields.first
                          
                              goToTextField.elementWaitFor({}, `There was an error opening the go to sheet`);
                          
                              // Set the Text Field 
                              goToTextField.elementSetTextFieldWithAreaValue({ value: targetProjectPath }, `Could not set the directory path in "Go To" text field. Path: ${targetProjectPath}`);
                          
                              sf.waitFor({
                                  callback: () => goToTextField.value.invalidate().value === targetProjectPath,
                                  timeout: 2000,
                              }, `Could not update the path text field`);
                          
                              // Accept/Close the sheet
                              sf.keyboard.press({ keys: "return" });
                          
                              sheet.elementWaitFor({ waitForNoElement: true }, `Failed waiting for Go To Sheet to disappear`);
                          
                              sf.wait({ intervalMs: 200 });
                          
                              importButton.elementWaitFor();
                          
                              importButton.elementClick();
                          
                              importButton.elementWaitFor({ waitForNoElement: true }, `Failed waiting import window to dissapear`);
                              /*     } catch (err) {
                                      throw `There was an error selecting the project path: "${targetProjectPath}" ${err}`;
                                  } */
                          }
                          
                          function checkForTrackNumbers(trackNames) {
                              const trackArea = mainWindow.getFirstWithDescription('Tracks').groups.whoseDescription.is('Tracks');
                              const trackHeaders = trackArea.allItems[1].splitGroups.first.splitGroups.allItems[1].scrollAreas.first.groups.whoseDescription.is('Tracks header').first;
                              const selectedTrackNames = trackHeaders.getElements('AXSelectedChildren').map(trackHeader => trackHeader.getString("AXDescription").match(/“(.*)”/)[1]);
                          
                              const seen = new Set();
                              for (const trackName of selectedTrackNames) {
                                  if (seen.has(trackName)) {
                                      // Duplicate found
                                      throw `Duplicate track name found: "${trackName}"`;
                                  }
                                  seen.add(trackName);
                              }
                              return false; // No duplicates found
                          }
                          
                          function importAudio() {
                              sf.interaction.displayDialog({
                                  buttons: ["Cancel", "Proceed"],
                                  cancelButton: "Cancel",
                                  defaultButton: "Proceed",
                                  prompt: `For this script to work correctly please make sure that...\n• Track control surface bars are hidden.\n• Track numbers are visible`
                              });
                          
                              refreshAllFilesPanel();
                          
                              // Check selected track names for duplicates
                              checkForTrackNumbers();
                          
                              // Get the session directory path
                              const sessionDirectoryPath = getSessionDirectoryPath();
                          
                              // Ask user to select the project they's like to import
                              const targetProjectPath = sf.interaction.selectFile({
                                  prompt: `Please select the Logic Project that you'd like to import tracks from.`,
                                  allowedFileTypes: ["logicx"],
                                  defaultLocation: sessionDirectoryPath,
                              }).path;
                          
                              navigateToTargetProjectPath({ targetProjectPath });
                          
                              doForEachSelectedTrack({ action: trackFunction, });
                          
                              sf.interaction.displayDialog({
                                  giveUpAfterSeconds: 2,
                                  prompt: "Track import complete"
                              });
                          }
                          
                          importAudio();
                          

                          It may take me some time to get this working in the reverse order where you select the tracks from the browser instead, but will keep you posted if/when I make any progress.

                          Rock on!

                          1. AAlex Oldroyd @Alex_Oldroyd8
                              2025-04-17 07:37:21.750Z

                              Hey @Kitch ! Thanks so much for working on this.

                              I'm going to try to reverse engineer what you've done so that i can automatically import specific tracks from a specific session. From the video you posted it looks like this is replacing rather than importing?

                              At the moment however i'm getting the following error and i'm not sure what the issue is:

                              17.04.2025 08:36:46.29 <info> [Backend]: !! Command Error: import tracks kitch [user:cm05g3cxg000tw110ukohsorg:cm9l1grx70000g310taet9hg8]:
                              TypeError: Cannot read property 'getFirstWithDescription' of undefined
                              (import tracks kitch line 115) 
                              
                              1. AAlex Oldroyd @Alex_Oldroyd8
                                  2025-04-17 07:45:02.819Z

                                  i bypassed the refreshAllFilesPanel() function. It now loads up the "Please select the Logic Project that you'd like to import tracks from." popup. I select the project, the Import Logic Projects menu pops up - but then i get the following error:

                                  17.04.2025 08:40:43.54 <info> [Backend]: !! Command Error: import tracks kitch [user:cm05g3cxg000tw110ukohsorg:cm9l1grx70000g310taet9hg8]:
                                  kAXErrorCannotComplete (import tracks kitch: Line 132)
                                      SoundFlow.Shortcuts.AXUIElementException: kAXErrorCannotComplete
                                     at SoundFlow.Shortcuts.AXUIElement.DoAction(String action) + 0x98
                                     at SoundFlow.Shortcuts.Automation.Actions.ClickMenuAction.<Execute>d__20.MoveNext() + 0x394
                                  --- End of stack trace from previous location ---
                                     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x24
                                     at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0x100
                                     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x68
                                     at SoundFlow.Shortcuts.Automation.AutoAction`1.<Run>d__25.MoveNext() + 0x368
                                  
                                  1. In reply toAlex_Oldroyd8:
                                    Matthew Brabender @Matthew_Brabender
                                      2025-04-17 12:02:09.386Z

                                      I'll be doing the same - that is importing tracks without replacing. My template is a whole bunch of routing but no tracks. This is great start :)

                                    • In reply toKitch:
                                      Kitch Membery @Kitch2025-04-17 20:20:54.189Z

                                      Thanks @Alex_Oldroyd8 & @Matthew_Brabender,

                                      I'll have to revisit this again next week, but thanks for the input.

                                      @Alex_Oldroyd8, if you're able to do a quick screen recording so I can see what's failing, that would be great.

                                      1. AAlex Oldroyd @Alex_Oldroyd8
                                          2025-04-29 10:16:58.187Z

                                          Hey Kitch

                                          Sorry for delay on this. Link to screen recording:
                                          https://www.dropbox.com/scl/fi/1yjuh9v5yhhgbqj02y1x3/error-in-templates-script.mov?rlkey=iqb5j4ouu2o9uv04ihdks1bq5&dl=0

                                          Running this script. Basically yours but bypassing the refreshAllFilesPanel() Function

                                          const logic = sf.ui.logic;
                                          logic.appActivateMainWindow();
                                          
                                          const mainWindow = logic.mainWindow;
                                          mainWindow.invalidate();
                                          
                                          const sessionName = mainWindow.getString("AXTitle");
                                          const sessionPath = decodeURIComponent(mainWindow.getString("AXDocument")).slice(0, -1);
                                          const sessionDirectory = sessionPath.split("/").slice(0, -1).join("/") + "/";
                                          
                                          const browsersGroup = mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first;
                                          const browsersPanel = browsersGroup.groups.whoseDescription.is("All Files").first;
                                          
                                          function getSessionDirectoryPath() {
                                              try {
                                                  // Session Path
                                                  const sessionDirectoryPath = decodeURIComponent(mainWindow.invalidate().getString("AXDocument")).slice(0, -1).replace("file://", "");
                                                  return sessionDirectoryPath;
                                          
                                              } catch (err) {
                                                  throw `There was an error fetching the Session Directory Path`;
                                              }
                                          }
                                          
                                          function getLogicRowElementByTrackName(trackName, column) {
                                              const allFilesTable = browsersPanel.scrollAreas.first.tables.first;
                                              const rows = allFilesTable.children.whoseRole.is("AXRow");
                                          
                                              const rowTitles = allFilesTable.groups.first.children;
                                              const columnLookupTable = rowTitles.map(c => c.title.value);
                                          
                                              const targetRow = rows.find(c => c.textFields[columnLookupTable.indexOf("Name")].value.value === trackName);
                                          
                                              return targetRow.children[columnLookupTable.indexOf(column)];
                                          }
                                          
                                          function getTrackName(track) {
                                              try {
                                                  const trackDescription = track.getString("AXDescription");
                                                  const trackName = trackDescription.match(/“([^"]+)”/)[1];
                                          
                                                  return trackName;
                                              } catch (err) {
                                                  throw err
                                              }
                                          }
                                          
                                          function getSelectedTracks() {
                                              const trackHeadersGroup = mainWindow.invalidate().trackHeadersGroup;
                                              return trackHeadersGroup.getElements('AXSelectedChildren');
                                          }
                                          
                                          function focusTrack(track) {
                                              const hasFocusBtn = track.radioButtons.first;
                                          
                                              // Focus track
                                              hasFocusBtn.elementSetAttributeValue({
                                                  attributeName: "AXFocused",
                                                  attributeValue: true
                                              });
                                          
                                              hasFocusBtn.elementClick();
                                          }
                                          
                                          function doForEachSelectedTrack({ action }) {
                                              const selectedTracks = getSelectedTracks();
                                              const firstSelectedTrack = selectedTracks[0];
                                          
                                              selectedTracks.forEach(track => {
                                                  focusTrack(track);// Focus track
                                          
                                                  try {
                                                      action(track);
                                                  } catch (err) {
                                                      throw err;
                                                  } finally {
                                                      focusTrack(track); // Refocus Track
                                                  }
                                              });
                                          
                                              focusTrack(firstSelectedTrack); // Focus first track
                                          }
                                          
                                          function trackFunction(track) {
                                              try {
                                                  const trackName = getTrackName(track);
                                                  const contentCheckbox = getLogicRowElementByTrackName(trackName, "Content");
                                                  const replaceButton = browsersPanel.buttons.whoseTitle.is("Replace").first;
                                          
                                                  // Enable focus for checkbox
                                                  contentCheckbox.elementSetAttributeValue({
                                                      attributeName: "AXFocused",
                                                      attributeValue: true
                                                  });
                                          
                                                  // Enable Content Checkbox
                                                  contentCheckbox.elementClick({ actionName: "AXPress", onError: "Continue" });
                                                  sf.waitFor({
                                                      callback: () => contentCheckbox.invalidate().value.intValue === 1, // Wait for checkbox to becom active
                                                      timeout: 1000
                                                  }, `Failed waiting for checkbox to be selected`);
                                          
                                          
                                          
                                                  replaceButton.elementClick({ actionName: "AXPress" });
                                          
                                              } catch (err) {
                                                  throw err
                                              }
                                          }
                                          
                                          function refreshAllFilesPanel() {
                                              const allFilesRadioButton = mainWindow.radioGroups.first.radioButtons.whoseDescription.is("All Files").first;
                                          
                                              const allFilesGroup = mainWindow.groups.find(g => {
                                                  return g.children.first.getString("AXDescription") === "All Files"
                                              }).getFirstWithDescription("All Files");
                                          
                                              const allFilesSubGroup = allFilesGroup && allFilesGroup.groups.whoseDescription.is("All Files").first;
                                              const computerBtn = allFilesSubGroup.groups.find(g => g.buttons.first.getString("AXHelp") === "Computer").buttons.first
                                          
                                              if (computerBtn.exists) {
                                                  computerBtn.elementClick();
                                              }
                                          }
                                          
                                          function navigateToTargetProjectPath({ targetProjectPath }) {
                                              // try {
                                              const logic = sf.ui.logic;
                                              logic.appActivateMainWindow();
                                          
                                              logic.menuClick({ menuPath: ["File", "Import", "Logic Projects…"] });
                                          
                                              const importWindow = logic.windows.whoseTitle.is("Import").first;
                                          
                                              sf.waitFor({
                                                  callback: () => importWindow.invalidate().exists,
                                                  timeout: 1000
                                              }, `Failed waiting for`);
                                          
                                              sf.wait({ intervalMs: 200 });
                                          
                                              const importButton = importWindow.buttons.whoseTitle.is("Import").first;
                                          
                                              sf.keyboard.press({ keys: "slash" });
                                          
                                              // Required wait for "Go To" Sheet.
                                              sf.wait({ intervalMs: 100 });
                                          
                                              const sheet = importWindow.sheets.first;
                                          
                                              sheet.elementWaitFor();
                                          
                                              const goToTextField = sheet.textFields.first
                                          
                                              goToTextField.elementWaitFor({}, `There was an error opening the go to sheet`);
                                          
                                              // Set the Text Field 
                                              goToTextField.elementSetTextFieldWithAreaValue({ value: targetProjectPath }, `Could not set the directory path in "Go To" text field. Path: ${targetProjectPath}`);
                                          
                                              sf.waitFor({
                                                  callback: () => goToTextField.value.invalidate().value === targetProjectPath,
                                                  timeout: 2000,
                                              }, `Could not update the path text field`);
                                          
                                              // Accept/Close the sheet
                                              sf.keyboard.press({ keys: "return" });
                                          
                                              sheet.elementWaitFor({ waitForNoElement: true }, `Failed waiting for Go To Sheet to disappear`);
                                          
                                              sf.wait({ intervalMs: 200 });
                                          
                                              importButton.elementWaitFor();
                                          
                                              importButton.elementClick();
                                          
                                              importButton.elementWaitFor({ waitForNoElement: true }, `Failed waiting import window to dissapear`);
                                              /*     } catch (err) {
                                                      throw `There was an error selecting the project path: "${targetProjectPath}" ${err}`;
                                                  } */
                                          }
                                          
                                          function checkForTrackNumbers(trackNames) {
                                              const trackArea = mainWindow.getFirstWithDescription('Tracks').groups.whoseDescription.is('Tracks');
                                              const trackHeaders = trackArea.allItems[1].splitGroups.first.splitGroups.allItems[1].scrollAreas.first.groups.whoseDescription.is('Tracks header').first;
                                              const selectedTrackNames = trackHeaders.getElements('AXSelectedChildren').map(trackHeader => trackHeader.getString("AXDescription").match(/“(.*)”/)[1]);
                                          
                                              const seen = new Set();
                                              for (const trackName of selectedTrackNames) {
                                                  if (seen.has(trackName)) {
                                                      // Duplicate found
                                                      throw `Duplicate track name found: "${trackName}"`;
                                                  }
                                                  seen.add(trackName);
                                              }
                                              return false; // No duplicates found
                                          }
                                          
                                          function importAudio() {
                                              sf.interaction.displayDialog({
                                                  buttons: ["Cancel", "Proceed"],
                                                  cancelButton: "Cancel",
                                                  defaultButton: "Proceed",
                                                  prompt: `For this script to work correctly please make sure that...\n• Track control surface bars are hidden.\n• Track numbers are visible`
                                              });
                                          
                                              //refreshAllFilesPanel();
                                          
                                              // Check selected track names for duplicates
                                              checkForTrackNumbers();
                                          
                                              // Get the session directory path
                                              const sessionDirectoryPath = getSessionDirectoryPath();
                                          
                                              // Ask user to select the project they's like to import
                                              const targetProjectPath = sf.interaction.selectFile({
                                                  prompt: `Please select the Logic Project that you'd like to import tracks from.`,
                                                  allowedFileTypes: ["logicx"],
                                                  defaultLocation: sessionDirectoryPath,
                                              }).path;
                                          
                                              navigateToTargetProjectPath({ targetProjectPath });
                                          
                                              doForEachSelectedTrack({ action: trackFunction, });
                                          
                                              sf.interaction.displayDialog({
                                                  giveUpAfterSeconds: 2,
                                                  prompt: "Track import complete"
                                              });
                                          }
                                          
                                          importAudio();
                                          
                                          1. AAlex Oldroyd @Alex_Oldroyd8
                                              2025-04-29 10:21:28.773Z

                                              If it helps, this is a script i'm using currently which is working. Screen recording of it in action and the script below.

                                              const logic = sf.ui.logic
                                              logic.appActivate();
                                              logic.invalidate();
                                                  
                                              const templateSessionName = event.props.templateSessionName
                                              const waitInterval = 1001
                                              
                                              importTrackFromTemplate();
                                              
                                              function importTrackFromTemplate() {
                                                  ensureBrowsersOpen();
                                                  invaldiateLogic();
                                                  searchForAndOpenSession();
                                                  setViewOptions(event.props.globalSet, event.props.ioSet, event.props.audioSet, event.props.instSet, event.props.auxSet, event.props.midiSet)
                                                  selectAllTracks();
                                                  selectImportItems();
                                                  selectImportItems();
                                                  importTracks();
                                              
                                              }
                                              
                                              function ensureBrowsersOpen() {
                                                  //Calling command "ensure browsers open" from package "! Helpful functions and scripts"
                                                  sf.soundflow.runCommand({
                                                      commandId: 'user:cl3c6los2000cd11016x299k9:cm05fyv07000sw1102gs71a7g#cleepu1pj0009z010dwkjqxtf',
                                                      props: {}
                                                  });
                                              
                                                  sf.wait({
                                                      intervalMs: waitInterval,
                                                  });
                                              }
                                              
                                              function invaldiateLogic() {
                                                  //Calling command "Invalidate() All Files" from package "! Helpful functions and scripts"
                                                  sf.soundflow.runCommand({
                                                      commandId: 'user:cl3c6los2000cd11016x299k9:cm0b89vjs0003r510xhcmrpte',
                                                      props: {}
                                                  });
                                              }
                                              
                                              function searchForAndOpenSession() {
                                                  const logic = sf.ui.logic
                                                  logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("All Files").first.mouseClickElement({
                                                      anchor: "MidCenter",
                                                  });
                                              
                                                  logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("All Files").first.elementClick();
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.groups.allItems[1].buttons.allItems[1].elementClick();
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.textFields.first.elementSetTextAreaValue({
                                                      value: templateSessionName,
                                                  });
                                              
                                                  sf.wait({
                                                      intervalMs: waitInterval,
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.textFields.whoseValue.is(templateSessionName).first.mouseClickElement({
                                                      anchor: "MidCenter",
                                                  });
                                              
                                                  sf.keyboard.press({
                                                      keys: "return",
                                                  });
                                              
                                                  sf.wait({
                                                      intervalMs: waitInterval,
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.groups.first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.textFields.first.mouseClickElement({
                                                      anchor: "MidCenter",
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.buttons.whoseTitle.is("Import…").first.elementClick();
                                              
                                                  sf.wait({
                                                      intervalMs: waitInterval,
                                                  });
                                              
                                              }
                                              
                                              function selectAllTracks() {
                                                  const logic = sf.ui.logic
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.textFields.first.mouseClickElement({
                                                      anchor: "MidCenter",
                                                  });
                                              
                                                  sf.keyboard.press({
                                                      keys: "cmd+a",
                                                  });
                                              }
                                              
                                              function selectImportItems() {
                                                  const logic = sf.ui.logic
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").allItems[1].checkBoxes.first.checkboxSet({
                                                      targetValue: "Enable",
                                                      onError: "Continue",
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.checkBoxes.allItems[1].checkboxSet({
                                                      targetValue: "Enable",
                                                      onError: "Continue",
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.checkBoxes.allItems[2].checkboxSet({
                                                      targetValue: "Enable",
                                                      onError: "Continue",
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.checkBoxes.whoseTitle.is("-").first.checkboxSet({
                                                      targetValue: "Enable",
                                                      onError: "Continue",
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.checkBoxes.allItems[3].checkboxSet({
                                                      targetValue: "Enable",
                                                      onError: "Continue",
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.checkBoxes.allItems[4].checkboxSet({
                                                      targetValue: "Enable",
                                                      onError: "Continue",
                                                  });
                                              
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.scrollAreas.first.tables.first.children.whoseRole.is("AXRow").first.checkBoxes.allItems[5].checkboxSet({
                                                      targetValue: "Enable",
                                                      onError: "Continue",
                                                  });
                                              }
                                              
                                              function importTracks() {
                                                  const logic = sf.ui.logic
                                                  logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.buttons.whoseTitle.is("Add").first.elementClick();
                                              }
                                              
                                              /**
                                               * @param {object} obj
                                               * @param {'Global'|'I/O'|'Audio'|'Inst'|'Aux'|'MIDI'} obj.viewName
                                               * @param {'Enable'|'Disable'|'Toggle'} [obj.targetValue]
                                               */
                                              function setViews({ viewName, targetValue }) {
                                                  const logic = sf.ui.app("com.apple.logic10");
                                                  const viewButton = logic.mainWindow.groups.allItems[3].groups.whoseDescription.is("All Files").first.groups.whoseDescription.is("All Files").first.groups.allItems[3].checkBoxes.whoseDescription.is(viewName).first;
                                              
                                                  viewButton.checkboxSet({ targetValue, });
                                              }
                                              
                                              function setViewOptions(globalSet, ioSet, audioSet, instSet, auxSet, midiSet) {
                                                  const logic = sf.ui.app("com.apple.logic10");
                                                  logic.appActivateMainWindow();
                                              
                                                  setViews({
                                                      viewName: "Global",
                                                      targetValue: globalSet,
                                                  });
                                              
                                                  setViews({
                                                      viewName: "I/O",
                                                      targetValue: ioSet,
                                                  });
                                              
                                                  setViews({
                                                      viewName: "Audio",
                                                      targetValue: audioSet,
                                                  });
                                              
                                                  setViews({
                                                      viewName: "Inst",
                                                      targetValue: instSet,
                                                  });
                                              
                                                  setViews({
                                                      viewName: "Aux",
                                                      targetValue: auxSet,
                                                  });
                                              
                                                  setViews({
                                                      viewName: "MIDI",
                                                      targetValue: midiSet,
                                                  });
                                              
                                              }
                                              
                                              
                                              1. AAlex Oldroyd @Alex_Oldroyd8
                                                  2025-05-01 07:49:54.473Z

                                                  @Kitch this is the script i'm using at the moment

                                                • In reply toAlex_Oldroyd8:
                                                  Kitch Membery @Kitch2025-04-29 23:27:24.204Z

                                                  The fix might be simple... It looks like the "Go to" sheet is not appearing, so the script is failing.

                                                  As a test (before I provide a better fix), can you try putting a 500ms wait on line 144 and see if that makes it work?

                                                  Let me know :-)

                                                  1. In reply toAlex_Oldroyd8:
                                                    Kitch Membery @Kitch2025-04-29 23:33:27.790Z

                                                    And if that works... Remove the wait, and change

                                                    sf.keyboard.press({ keys: "slash" });
                                                    

                                                    to

                                                    sf.keyboard.press({ keys: "cmd+shift+g" });
                                                    
                                                    1. AAlex Oldroyd @Alex_Oldroyd8
                                                        2025-04-30 08:17:28.655Z

                                                        Hey Kitch

                                                        Couldn't get it to work with the sf.wait but the

                                                        sf.keyboard.press({ keys: "cmd+shift+g" });
                                                        

                                                        worked.

                                                        I'm now getting the following error:

                                                        30.04.2025 09:13:58.40 <info> [Backend]: !! Command Error: import tracks kitch 2 [user:cm05g3cxg000tw110ukohsorg:cm9l1grx70000g310taet9hg8]:
                                                        ElementSetAttributeValueAction requires UIElement (import tracks kitch 2: Line 59)
                                                            Couldn't get item #0 as the array length was 0 - sf.ui.app('com.apple.logic10').<unknown>.<unknown>.<unknown>.first.radioButtons.first (AxElementArrayIndexedItem)
                                                        

                                                        In case my script has different lines, line 59 for me is:

                                                            // Focus track
                                                            hasFocusBtn.elementSetAttributeValue({
                                                                attributeName: "AXFocused",
                                                                attributeValue: true
                                                            });
                                                        

                                                        Video here:
                                                        https://www.dropbox.com/scl/fi/p3mtz00uxrap5c1fvbm2g/error-line-59-templates-script.mov?rlkey=hs6it35p32pvc66qsue71v8ov&dl=0

                                                        1. Kitch Membery @Kitch2025-04-30 17:16:32.929Z

                                                          Hi @Alex_Oldroyd8

                                                          Great to hear the fix worked. :-)

                                                          Regarding the next error issue... From the video you shared, you have a track selected named "cello synth lead" but I don't see a track named "cello synth lead" in the session you're trying to import.

                                                          No doubt you're after a slightly different workflow from the script I created, so let me know what you're after and I'll see if I can whip something up.

                                                          1. AAlex Oldroyd @Alex_Oldroyd8
                                                              2025-05-01 07:49:15.192Z

                                                              Ah I seeeee. Yep you're right - so i would be using a version of this script to import tracks from a specific project and add them to the current project rather than replace existing tracks.

                                                              I posted my script and a video of it working above, i'll tag you.

                                                              1. Kitch Membery @Kitch2025-05-01 17:17:44.044Z

                                                                Hi @Alex_Oldroyd8

                                                                I'll take a look at your workflow next week and see if it's something that could be implemented. :-)

                                                                Bump this thread if I forget. :-)

                                                                1. AAlex Oldroyd @Alex_Oldroyd8
                                                                    2025-05-02 07:49:16.387Z

                                                                    Amazing! Thanks mate