···55The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7788+## [Unreleased](https://github.com/patrik-csak/mac-terminal/compare/v4.0.0...HEAD)
99+1010+### Changed
1111+1212+- **BREAKING**: `setTerminalProfile()` only tries to update Terminal windows if Terminal is running
1313+1414+### Fixed
1515+1616+- `getTerminalProfiles()` and `setTerminalDefaultProfile()` now work without opening Terminal
1717+818## [4.0.0](https://github.com/patrik-csak/mac-terminal/compare/v3.0.0...v4.0.0) – 2025-09-19
9191020### Added
+23-44
index.js
···11+import os from 'node:os';
12import alphaSort from 'alpha-sort';
33+import bplist from 'bplist-parser';
44+import {$} from 'execa';
25import ow from 'ow';
36import psList from 'ps-list';
47import {runAppleScript} from 'run-applescript';
···710 * @returns {Promise<string[]>} - List of installed Terminal.app profiles
811 */
912export async function getTerminalProfiles() {
1010- const result = await runAppleScript(`set text item delimiters to linefeed
1111-tell application "Terminal"
1212- return (name of every settings set) as string
1313-end tell`);
1313+ const terminalPlistPath = `${os.homedir()}/Library/Preferences/com.apple.Terminal.plist`;
1414+ const terminalPreferences = await bplist.parseFile(terminalPlistPath);
14151515- return result
1616- .split('\n')
1717- .sort(alphaSort({caseInsensitive: true, natural: true}));
1616+ return Object.keys(terminalPreferences[0]['Window Settings']).sort(
1717+ alphaSort({caseInsensitive: true, natural: true}),
1818+ );
1819}
19202021/**
···3738 * @return {Promise<void>}
3839 */
3940export async function setTerminalProfile({profile, setDefault}) {
4040- const terminalProfiles = await getTerminalProfiles();
4141-4242- ow(profile, ow.string.oneOf(terminalProfiles));
4343- ow(setDefault, ow.optional.boolean);
4141+ ow(profile, ow.string.oneOf(await getTerminalProfiles()));
44424545- let appleScript = getSetTerminalWindowsProfileAppleScript(profile);
4343+ if (await isTerminalRunning()) {
4444+ await runAppleScript(`tell application "Terminal"
4545+ set current settings of tabs of windows to settings set "${profile}"
4646+end tell`);
4747+ }
46484749 if (setDefault) {
4848- appleScript += '\n' + getSetTerminalDefaultProfileAppleScript(profile);
5050+ await setTerminalDefaultProfile(profile);
4951 }
5050-5151- await runAppleScript(appleScript);
5252}
53535454/**
···5858 * @return {Promise<void>}
5959 */
6060export async function setTerminalDefaultProfile(profile) {
6161- const terminalProfiles = await getTerminalProfiles();
6161+ ow(profile, ow.string.oneOf(await getTerminalProfiles()));
62626363- ow(profile, ow.string.oneOf(terminalProfiles));
6464-6565- const appleScript = getSetTerminalDefaultProfileAppleScript(profile);
6666-6767- await runAppleScript(appleScript);
6868-}
6969-7070-/**
7171- * Get the AppleScript to set the profile for all open Terminal.app windows
7272- *
7373- * @param {string} profile
7474- * @returns {string}
7575- */
7676-function getSetTerminalWindowsProfileAppleScript(profile) {
7777- return `tell application "Terminal"
7878- set current settings of tabs of windows to settings set "${profile}"
7979-end tell`;
8080-}
8181-8282-/**
8383- * Get the AppleScript to set the default profile for new Terminal.app windows
8484- *
8585- * @param {string} profile
8686- * @returns {string}
8787- */
8888-function getSetTerminalDefaultProfileAppleScript(profile) {
8989- return `tell application "Terminal"
6363+ if (await isTerminalRunning()) {
6464+ await runAppleScript(`tell application "Terminal"
9065 set default settings to settings set "${profile}"
9191-end tell`;
6666+end tell`);
6767+ } else {
6868+ await $`defaults write com.apple.Terminal Default\ Window\ Settings -string ${profile}`;
6969+ await $`defaults write com.apple.Terminal Startup\ Window\ Settings -string ${profile}`;
7070+ }
9271}