- Swift 88.2%
- Shell 11.8%
|
Truls Aagedal
0dcb76ddce
Refresh README for 1.0 — full-profile backup, sppreset, tooltips
Documents the current feature set (kys + sppreset + .zip backup with selective restore), the Premiere/Premiere Pro version threshold, the .DS_Store / AppleDouble / metadatacache filter, the file tooltips, and the TCC quirk for ad-hoc Debug builds. Manual test plan now covers the full backup and partial-restore flows. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| bin | Add Sparkle auto-update with release-build.sh, bump to 1.0 | |
| KeyLayoutManager | Exclude metadatacache.prmdc2* from backups | |
| KeyLayoutManagerTests | Exclude metadatacache.prmdc2* from backups | |
| .gitignore | Initial commit: Premiere Keyboarder v0.1 | |
| appcast.xml | Add Sparkle auto-update with release-build.sh, bump to 1.0 | |
| Logo.af | Add app icon | |
| Logo.png | Add app icon | |
| project.yml | Add Sparkle auto-update with release-build.sh, bump to 1.0 | |
| README.md | Refresh README for 1.0 — full-profile backup, sppreset, tooltips | |
| release-build.sh | Add Sparkle auto-update with release-build.sh, bump to 1.0 | |
| setup.sh | Rename: PremiereKeyboarder -> KeyLayoutManager | |
Key Layout Manager
Small native macOS utility for managing Adobe Premiere keyboard layouts, source assignment presets, and full-profile backups. SwiftUI, non-sandboxed, Developer ID signed for distribution.
Premiere stores per-user data at:
~/Documents/Adobe/Premiere Pro/<version>/Profile-<username>/
Mac/<name>.kys # keyboard shortcut layouts
Settings/Source Patcher Presets/<name>.sppreset # source assignment presets
...everything else (workspaces, panel layouts, prefs, ...)
Moving any of that between Macs in Finder means hunting through nested Adobe folders. This app collapses it to one window:
- Export — browse every
.kysand.sppresetPremiere has on the local machine, multi-select, drag straight into Slack / Mail / Finder or export to a folder, iCloud Drive, or Dropbox. Right-click a profile to back up the entireProfile-<user>folder as a standalone.zip. - Restore — drop loose
.kys/.sppresetfiles (or a backup.zip) onto the window, or pick via the file panel. Backup zips expand into a grouped, per-entry checklist so a "restore only the keyboard layout" workflow stays one click away. Pick a destination profile (can differ from the source's Premiere version) and restore. Standard collision prompt (Overwrite / Keep both / Skip, plus "Apply to all remaining") covers any conflicts. Hover any incoming row to see a tooltip describing what that file does.
The version label adapts: Premiere 26 and later show as "Premiere <version>", earlier versions as "Premiere Pro <version>" — Adobe dropped "Pro" from the product name in v26.
.DS_Store, AppleDouble metadata, and Premiere's regenerable
metadatacache.prmdc2* files are filtered out of every backup, both
when writing and when listing existing zips.
Requirements
- macOS 14 or later
- Xcode 15+ for development
- An Apple Developer ID for signed, notarized distribution
Setup
./setup.sh
Installs XcodeGen via Homebrew
if needed, then generates KeyLayoutManager.xcodeproj from
project.yml. The .xcodeproj is gitignored — never hand-edit it;
change project.yml and re-run xcodegen.
If xcode-select -p points at Command Line Tools, switch it:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
Then:
open KeyLayoutManager.xcodeproj
Set your Team in Signing & Capabilities (or add
DEVELOPMENT_TEAM to project.yml) and hit Run. Without a team, Debug
builds are ad-hoc-signed and macOS will re-prompt for Documents-folder
access on every launch — a stable signature is what makes the TCC
grant stick.
Project layout
KeyLayoutManager/
App/ # @main + RootView (Export / Restore tabs) + Sparkle
Models/ # PremiereItemKind, PremiereInstall, ProfileLocation,
# KeyboardLayout, IncomingItem, BackupManifest,
# PremiereProduct (version → name), PremiereFileInfo (tooltips)
Services/ # PremiereScanner, CopyService, CloudTargets, TempStage,
# ZipService (wraps /usr/bin/zip and /usr/bin/unzip)
Features/
Export/ # source list, drag source, four export targets,
# "Back Up Profile..." + "Delete Profile..." context menu
Restore/ # drop zone, destination picker, grouped checklist,
# manifest banner, collision alert
Resources/ # Info.plist, entitlements
Assets.xcassets/
KeyLayoutManagerTests/
PremiereScannerTests, CopyServiceTests,
ZipServiceTests, BackupManifestTests,
PremiereProductTests, PremiereFileInfoTests
project.yml # XcodeGen config
setup.sh # bootstrap
release-build.sh # archive → notarize → staple → sign → upload → appcast
appcast.xml # Sparkle feed
Run the unit tests
xcodebuild test -scheme KeyLayoutManager -destination 'platform=macOS'
Currently 27 tests across six suites: scanner edges (empty Mac/,
missing Mac/, multi-digit version sort, non-version sibling dirs),
CopyService policies (overwrite, keepBoth name-bumping, skip, prompt
routing), zip round-trip (create → list → extract a subset), backup
manifest encode/decode, product-name version threshold, and
file-description coverage.
Manual test plan
- First launch. "Documents folder" TCC prompt appears once. Click Allow. Subsequent launches stay silent (assuming a stable signing identity).
- Export tab. Newest Premiere version → profile →
Keyboard LayoutsandSource Assignment Presetssubsections render under the profile. Sidebar header reads "Premiere 26.0" for v26+ and "Premiere Pro 25.x" for older. - Drag. Drag a row out into Finder, Slack, or Mail.
- Export to... Pick a folder via Save panel.
- iCloud / Dropbox backup. Buttons appear when the corresponding
cloud root exists; files land under
KeyLayoutManager/<version>/. - Per-item restore. Drop a loose
.kysor.sppreseton the Restore tab. Destination dropdown defaults to newest profile. Click Restore. - Collision prompt. Restore the same file again. Overwrite / Keep
both / Skip alert with "Apply to all remaining" toggle.
Keep bothproducesName (2).kys. - Full profile backup. Right-click a profile in the Export tab →
"Back Up Profile..." → choose a save location. The resulting
.zipcontains the entireProfile-<user>tree plus aKeyLayoutManager-manifest.jsonat the root..DS_Store, AppleDouble (._*), andmetadatacache.prmdc2*files are absent. - Full restore. Drop the new
.zipon the Restore tab. The banner shows "Backup of Premiere <version> — <profile>, <date>". Entries appear grouped by top-level folder with checkboxes; pick a destination profile, click "Restore N items". - Partial restore. Load the same
.zip, untick everything exceptMac/<your>.kys, click Restore. Verify only that one file is copied. - Cross-version restore. Pick a destination profile whose Premiere version differs from the backup's. Restore still proceeds (you accept any version mismatch consequences).
- Right-click delete. Right-click a profile → "Delete Profile..." → confirm. Profile folder moves to Trash; sidebar refreshes.
- Tooltips. Hover an incoming row on the Restore tab — known
file types (kys, sppreset,
Adobe Premiere Pro Prefs,.guides, workspaces, ...) show a one-sentence description.
Distribution
Non-sandboxed, hardened runtime, empty entitlements file. Sparkle 2 is
wired up — appcast.xml lives at the repo root, signed .zip releases
are hosted on
Codeberg Releases,
and existing installs see "Check for Updates..." under the app menu.
Releasing
One-time setup:
# notarytool credentials (re-uses the "Notary" profile referenced below)
xcrun notarytool store-credentials Notary \
--apple-id <appleid> --team-id <teamid> --password <app-specific-pw>
# Codeberg API token for auto-uploading the .zip to a release
export CODEBERG_TOKEN=<token>
Then for each release, bump MARKETING_VERSION / CURRENT_PROJECT_VERSION
in project.yml, regenerate the project, and run:
./release-build.sh # version read from project.yml
./release-build.sh 1.1.0 2 # or override version + build
The script archives, exports, notarizes, staples, zips (with AppleDouble
metadata stripped so Gatekeeper doesn't reject the bundle), signs the
zip with Sparkle's EdDSA key, creates a Codeberg release, uploads the
zip, and appends a new <item> to appcast.xml. Commit and push
appcast.xml to publish the update to existing installs.
The Sparkle EdDSA private key is shared with Aagedal Media Converter
(single keychain entry); bin/sign_update is Sparkle's signing helper.
If you need to notarize a one-off build by hand instead:
xcrun notarytool submit KeyLayoutManager.zip \
--keychain-profile "Notary" --wait
xcrun stapler staple KeyLayoutManager.app