Skip to content
doom1337hvhPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

AppShell

The shared shell, scripts and template for doom1337hvh's small Mac apps, such as MusicNotch and Foldaway. Each app keeps its own repository and releases, and pulls AppShell in with Swift Package Manager, so they all look, build and ship the same way, and a fix here reaches every app.

What's in it

  • Sources/AppShell, a Swift package the apps import:
    • SettingsWindow and SettingsTab: the Settings window, with a row of tabs at the top, slightly raised but for the selected one, which is pressed in. It reopens on the tab used last. .general(menuBar:) (Launch at login, Show menu bar icon, then the app's own) comes first and .about() (icon, version, GitHub, licences) last.
    • MenuBar: the menu bar icon and its menu: the app's items, then Settings… and Quit. Hiding it is a setting in General.
    • LoginItem, AppShell.quitIfTranslocated() (the "Move to Applications" check), AppShell.demoScene (the -demo <scene> argument for README clips), and NSMenuItem("Title") { … } for menu items that run a closure.
  • scripts/: build.sh, release.sh and create-signing-cert.sh, which every app runs through its own tiny scripts/build.sh and so on; and new-app.sh, which starts a new app.
  • template/: what new-app.sh copies: a working menu bar app with General, a tab of its own and About, a README in the house format with TODOs to fill in, the release notes, a placeholder icon script, and a CLAUDE.md that tells Claude Code to build on AppShell and keep the house format.

Start a new app

scripts/new-app.sh Clipboardy --symbol doc.on.clipboard --in ~/Documents

This makes ~/Documents/Clipboardy, a menu bar app that already builds and runs, with the bundle ID io.github.doom1337hvh.Clipboardy and a placeholder icon drawn from the symbol. Then:

cd ~/Documents/Clipboardy && scripts/create-signing-cert.sh && scripts/build.sh --install

Fill in the TODOs (grep -rn TODO .), draw the real icon in scripts/make-icon.swift, and publish the folder on GitHub (GitHub Desktop: Add Local Repository, then Publish Repository).

Or ask Claude Code for a new app: with the new-mac-app skill in ~/.claude/skills, it runs this and fills in the rest the same way.

The house format

Every app follows it; the template already does.

Repository

Package.swift            depends on AppShell (branch main; Package.resolved pins the commit)
Package.resolved         committed
Resources/Info.plist     name, bundle ID io.github.<owner>.<Name>, version, GitHubRepository
Resources/AppIcon.icns   drawn by scripts/make-icon.swift
Sources/<Name>/          main.swift, AppDelegate.swift, Preferences.swift, settings tabs, the rest
scripts/                 build.sh, release.sh, create-signing-cert.sh and appshell.sh (which run
                         AppShell's), hooks/ for the app's own build steps, make-icon.swift,
                         make-video.swift for the README's clips
docs/                    icon.png, demo.gif, clips/*.gif, RELEASING.md
README.md, LICENSE       MIT
CLAUDE.md                the house rules for Claude Code in this app

README, in this order: centred icon, name, one-line tagline plus "Free, open source, and light on battery.", the main demo GIF, the Download · Install · In action · Settings links, a short intro, then Features, In action (one collapsed <details> clip each), Requirements, Install, Updating, Permissions, Settings, Battery, Troubleshooting, Unofficial APIs (if any), Uninstall, Build from source (with How it works), License.

The app

  • A menu bar app with no Dock icon (LSUIElement), Apple silicon, macOS 14 or later.
  • The menu: the app's own items, then Settings… (⌘,) and Quit (⌘Q).
  • Settings: General first, a tab per topic, About last. Each tab is a grouped form 500 points wide; every setting has a label and, if it needs one, a line underneath saying what it does.
  • Opening the app again while it runs shows Settings, so it's reachable with the icon hidden.
  • Opened from Downloads, it asks to be moved to Applications and quits.
  • It never connects to the internet: no analytics, accounts or update checks.
  • README clips are recorded from the real app with -demo <scene>; nothing is saved meanwhile.

Releases: signed with the app's own " Local Signing" certificate every time, so people's permissions carry over; scripts/release.sh writes the zip, the DMG and SHA256SUMS.txt; tags are v<version>. See the app's docs/RELEASING.md.

Using it in an app

The template's AppDelegate.swift shows all of it:

private lazy var menuBar: MenuBar = MenuBar(symbol: "sparkles", items: { [weak self] menu in
    guard let self else { return }
    menu.addItem(NSMenuItem("Turn On Clipboardy", isOn: prefs.isEnabled) { [weak self] in
        self?.prefs.isEnabled.toggle()
    })
}, showSettings: { [weak self] in
    self?.settings.show()
})
private lazy var settings: SettingsWindow = SettingsWindow { [weak self] in
    guard let self else { return [] }
    return [
        .general(menuBar: menuBar),
        SettingsTab("Clipboardy", symbol: "sparkles") { MainSettings(prefs: self.prefs) },
        .about(),
    ]
}

A tab's content is just its Sections; AppShell lays them out. .general and .about take extra content too, such as MusicNotch's "Where it appears" section or its media adapter status, and .about(thirdParty:) lists the licences of what the app ships from others.

An app's own build steps go in scripts/hooks/prepare.sh (before swift build) and scripts/hooks/bundle.sh (once the app is put together in $STAGED, before signing); see scripts/build.sh. MusicNotch builds and adds its media adapter framework there.

Changing AppShell

Apps get a change to AppShell once it's pushed and they run swift package update AppShell (then commit their Package.resolved). To try a change in an app before pushing it:

swift package edit AppShell --path ~/Documents/AppShell

The app then builds with your copy until swift package unedit AppShell.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages