Skip to content

Apps list: the apps in a folder of their own (#76) - #136

Merged
Saffsanity merged 3 commits into
Saffsanity:mainfrom
Anubhav-Rai:apps-in-folders
Oct 19, 2026
Merged

Saffsanity merged 3 commits into
Saffsanity:mainfrom
Anubhav-Rai:apps-in-folders

Conversation

@Anubhav-Rai

Copy link
Copy Markdown
Contributor

Fixes #76.

What

The Apps list now finds apps installed in a folder of their own, the way Adobe's suite installs them (/Applications/Adobe Photoshop 2026/Adobe Photoshop 2026.app). It looks one level down into each applications folder, as Launchpad and Spotlight do. It still never looks inside a bundle, so an app's own helpers stay out.

Why it missed them

WindowCatalog.findInstalledApps() listed only the .app bundles sitting directly in /Applications, /Applications/Utilities, /System/Applications, /System/Applications/Utilities and ~/Applications. Anything in a subfolder was never seen.

How

  • New pure file: the scan moves to Sources/SillHost/InstalledApps.swift, a small enum on FileManager and Bundle only, so a check can compile it on its own. findInstalledApps() now just passes it the same five folders.
  • Folder rules:
    • In each folder: the .app bundles directly in it first, then the .app bundles in each plain subfolder, one level down.
    • Not followed: symbolic links to folders, other kinds of packages, folders more than one level down, and anything inside a bundle.
  • Unchanged from before: first bundle ID wins and the list is sorted by display name.
  • Safari edge case: names starting with a dot are skipped, but .skipsHiddenFiles is deliberately not used. /Applications/Safari.app is a symbolic link into its cryptex that macOS flags as hidden, and that option dropped Safari from the list (I caught it comparing old vs new on a real Mac).

How I tested it

  • New check: Tests/checks/installed-apps builds a fake applications folder in a temporary directory and checks 13 cases:
    • a suite's folder (App menu don’t look in folders #76)
    • a folder too deep
    • a helper inside a bundle
    • a dot-named folder
    • a symbolic link to a folder
    • a Safari-style hidden-flagged link to an app
    • two bundles with one ID
    • several folders, a missing one, the sort and the name
  • The check catches the bug: dropping the subfolder scan fails the App menu don’t look in folders #76 case, and putting .skipsHiddenFiles back fails the Safari case.
  • On a real Mac (macOS 27, MacBook Pro M5), with the same five folders: 90 apps before, 92 after. The two new ones are an app and its uninstaller in ~/Applications/IB Gateway 10.50/, and nothing that was listed before went missing.
  • swift build -c release is clean, and Tests/checks/run-all.sh passes.
  • CLAUDE.md lists the new file in Layout and the new check.

Not tried: an actual iPad's Apps list with the Adobe suite installed (I don't have it). The device gets the same [AppInfo] as before, just longer.

🤖 Generated with Claude Code

The scan looked only at the bundles directly in each applications
folder, so a suite installed one app per folder, like Adobe's, never
showed. It now also looks one level down, never inside a bundle, in
InstalledApps.swift with a check of its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Saffsanity

Copy link
Copy Markdown
Owner

From a pass over all the open pull requests (nothing is decided yet): #135 fixes #76 the same way (the same new InstalledApps.swift and installed-apps check) and is proposed to close as a duplicate of this one, since this one keeps Safari listed, and #135 searches to any depth where this one stops one level down (its own example, /Applications/Adobe/Creative Suite/Photo.app, would be missed), so that depth is worth taking here; #66 (and #72 and #73, built on it) appends Finder at the end of the findInstalledApps body this PR replaces, so whichever lands second moves that line after InstalledApps.find.

Saffsanity and others added 2 commits October 20, 2026 00:41
…e a framework

This pull request looked one level down into each applications folder,
so an app further down, like Saffsanity#135's /Applications/Adobe/Creative
Suite/Photo.app, was still missed. The depth comes from Saffsanity#135 by GreedyC,
which fixed Saffsanity#76 the same way: InstalledApps.bundles(in:) now walks the
folders a level at a time at any depth, by name within each folder, so
of two bundles with one ID the shallower one wins, and at one depth the
one in the folder first by name. It still never enters a bundle or
another package, and now not a framework either, a bundle that is no
package (Sparkle's keeps an Updater.app inside). It never follows a link
it finds in a folder, so a link back up cannot loop; a folder it is
given that is itself a link (~/Applications on another disk) is
resolved first and read, as main read it. Both Utilities folders are
now read twice, inside their parent and as given, which changes
nothing: the first bundle with an ID wins and both reads find the same
bundles. The doc comment no longer says Launchpad and Spotlight show
apps this way.

The check gains an app two folders down, a package's and a framework's
inner apps, a dot-named app below the top, a link back up, a folder
given as a link, and one app twice at one depth in sibling folders that
APFS lists out of order; it counts its failures instead of stopping at
the first, and removes its fake folder. It gets a mutants script (12
one-line mutants, among them the walk cut to one level, the next level
walked backwards and each folder left unsorted) and a place in CI's
mutants matrix. CLAUDE.md's Layout line and the checks' README describe
the scan as it now is.

Verified: the check 18 of 18 and its mutants 12 of 12; run-all.sh with
installed-apps and addresses; swift build -c release, only the
CaptureProbe warning; a loopback synthetic host on the software encoder
lists 122 apps on this Mac where main listed 119 (IDLE, Python Launcher
and an Edge web app added, none lost).

Co-authored-by: GreedyC <62262441+GreedyC@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Saffsanity

Copy link
Copy Markdown
Owner

Thank you for this. To get it ready to merge, two commits now sit on top of yours on this branch (your commit is unchanged): a merge of the current main (#142, #153; no conflict), and 8167830, which adds:

  • Any depth. The scan walks each applications folder a level at a time at any depth instead of stopping one level down. The depth comes from Apps drawer: find applications in nested folders #135 by @GreedyC (credited as co-author on the commit), so its example, /Applications/Adobe/Creative Suite/Photo.app, is found. Each folder is read by name, so of two bundles with one ID the shallower one wins, and at one depth the one in the folder first by name.
  • Never inside a framework. As before, nothing inside a bundle or another package is read. A framework is a bundle but not a package, so the walk would otherwise enter it (Sparkle's keeps an Updater.app inside).
  • Links. A link found inside a folder is never followed, so a link back up cannot loop. A folder in the list that is itself a link (~/Applications on another disk) is resolved first and read, as main read it.
  • Comments. The doc comment no longer says Launchpad and Spotlight show apps this way, and findInstalledApps notes that both Utilities folders are now read twice, harmlessly, since the first bundle ID wins.
  • The check. 18 cases (two folders down, a package's and a framework's inner apps, a dot-named app below the top, a link back up, a folder given as a link, one app twice at one depth). It counts failures instead of stopping at the first and removes its temporary folder. A mutants.py with 12 one-line mutants, each caught, joins CI's mutants matrix; CLAUDE.md's Layout line and Tests/checks/README.md describe it.

Checked: the check 18 of 18 and its mutants 12 of 12, Tests/checks/run-all.sh installed-apps addresses, swift build -c release (only the known CaptureProbe warning), and a loopback synthetic host listing 122 apps on a Mac where main lists 119 (IDLE, Python Launcher and an Edge web app added, none lost). It merges once CI passes on this head.

@Saffsanity
Saffsanity merged commit 9a8e30c into Saffsanity:main Oct 19, 2026
2 checks passed
Saffsanity added a commit that referenced this pull request Oct 19, 2026
Two conflicts, both sides kept: CI's mutants matrix has installed-apps and thumbnail-hold,
in order; Tests/checks/README.md says where each came from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to acalatrava/sill that referenced this pull request Oct 19, 2026
Main gained Saffsanity#136 (the Apps list's apps at any depth, its installed-apps check). Two conflicts, both
unions: CI's mutants matrix lists display-wake and installed-apps (every check but ledger, which has
no mutants), and Tests/checks/README.md's provenance note names both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to addhumal/sill that referenced this pull request Oct 19, 2026
Main gained Saffsanity#136 (the Apps list finds apps in folders, with the installed-apps
check). ci.yml's mutants matrix conflicted, both sides adding a check: both kept,
in the list's order (connection-list and installed-apps). The checks README
notes where connection-list came from, as it does for installed-apps.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Saffsanity added a commit to grub-basket/sill that referenced this pull request Oct 19, 2026
The checks README keeps main's installed-apps row and this branch's key-strokes row (353 checks, 83 mutants).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Saffsanity added a commit that referenced this pull request Oct 19, 2026
…y-stepping

ci.yml's mutants matrix takes both new checks (display-stepping,
installed-apps), sorted; CLAUDE.md's Layout keeps WindowCatalog's displays
and InstalledApps side by side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to kyleparisi/sill that referenced this pull request Oct 19, 2026
Main moved from d1fa97e to 9a8e30c with Saffsanity#136 (the Apps list's folders,
Saffsanity#76), which added the installed-apps check. It and this branch each added
a check to ci.yml's one-line mutants matrix, which conflicted: the line
now lists both, installed-apps and virtual-display-api, in sorted order
with the 43 it had. Tests/checks/README.md and CLAUDE.md merged by
themselves and keep both checks' rows and Layout entries. Saffsanity#136 did not
touch VirtualDisplay.swift.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HunterAhlquist pushed a commit to HunterAhlquist/sill that referenced this pull request Oct 19, 2026
…pencil-pressure-rebased

Only ci.yml's mutants matrix conflicted: it keeps both new checks,
`installed-apps` (Saffsanity#136) and `pen`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to scripsweave/sill that referenced this pull request Oct 19, 2026
Main gained Saffsanity#110 (Shift-Return and Shift-Tab), Saffsanity#136 (apps in folders,
the installed-apps check), Saffsanity#87 (the virtual display's BOOL encoding, the
virtual-display-api check) and Saffsanity#88 (a universal Sill.app on request).
Merged so this branch builds and checks against today's main. Only
ci.yml's one-line mutants matrix conflicted: both sides kept, sorted
(46 checks: main's installed-apps and virtual-display-api beside this
branch's pairing-sharing; ledger has no mutants).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to Code-Tomato/sill that referenced this pull request Oct 20, 2026
…de Send Audio

Main gained Saffsanity#136 (the Apps list finds apps in folders of their own, at any
depth: InstalledApps and its check). Two conflicts, both lists:
- ci.yml's mutants matrix: both sides' checks, installed-apps among them,
  with the sound's audio-codec, audio-packetizer, audio-playout and ledger.
- Tests/checks/README.md's history: main's installed-apps sentence, then
  the audio branch's, which now also says what the beta changed in
  phone-portrait, tour and away-quality.
CLAUDE.md merged by itself (InstalledApps in the Layout and the checks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saffsanity added a commit to addhumal/sill that referenced this pull request Oct 20, 2026
Main gained Saffsanity#136 (the Apps list finds apps in a folder of their own, and its installed-apps check);
it touches the window catalog and the checks' list, not the display path, the host's commands or
the keyframe check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	.github/workflows/ci.yml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

App menu don’t look in folders

2 participants