2 Commits
Author SHA1 Message Date
Claude Opus 5andbdeshi cf7d9a4583 Draw the real icon, and give the menu bar its own glyph
Replaces the placeholder coat silhouette with the app's actual subject:
Claude's asterisk above a rack of overcoats, on Claude's own coral. The
wardrobe is the app in one picture — several coats to pick between, one
currently worn.

The menu bar stops scaling the app icon down and draws its own glyph
instead. At 18pt the icon's three coats, lapels and pockets collapse into
a smudge, and its colours ignore the menu bar entirely. The glyph is a
template image, so macOS tints it for light and dark and for the
open-menu inversion, and re-tints it itself when the theme changes. That
also drove its shape: six rays rather than eight, because at that size
eight have under a pixel between arms and merge into a blob.

The coloured dots beside it don't get that for free — ProfileColor picks
a brightness for the current appearance at the moment it's asked, and the
title is only rebuilt when profiles start or stop. Observing
effectiveAppearance rebuilds it, so a theme switch doesn't leave dots
mixed for the old appearance sitting in the menu bar.

Everything is still drawn from vector paths rather than exported from a
design tool, so each size can be tuned — small sizes need fatter strokes
than a straight downscale gives — and nothing binary but the derived
assets is committed. The README gains a hero banner, composed from the
generated icon so it can't drift out of step with it.

About gains the tagline under the icon, names itself in the description
rather than opening with a bare verb, and drops the author line.
2026-08-05 21:06:58 +06:00
Claude Opus 5andbdeshi 135db9b308 Rewrite shannoncoat as a native Swift menu-bar app
Replaces the original shannoncoat.sh entirely with in-process Swift. The
script stopped earning its keep once the rest went native, and being a
persistent process rather than a one-shot CLI is what later makes live
window tracking possible at all.

- ProfileStore: JSON config at ~/.shannoncoat/<name>.json (was hand-rolled
  YAML), with ~ expansion, paths relative to the config dir, and
  name/dir-collision validation in one place.
- ProcessInspector: sysctl(KERN_PROC_ALL/KERN_PROCARGS2) enumeration
  instead of shelling out to pgrep.
- ClaudeControl: launch via Process, focus via direct Accessibility calls
  (unhide, un-minimize, poll-for-window, AXRaise) instead of AppleScript,
  and a quit that respects Claude's own termination handling rather than
  unconditionally SIGKILLing after a flat 5s timeout.
- LiveState: NSWorkspace notification-driven state with no polling timer,
  so the menu bar reflects reality within about a second — including
  changes made outside the app entirely.
- ManageWindow: one non-modal window replacing what would otherwise be a
  string of separate popup alerts, with inline add/remove and directory
  pickers.
- LaunchAtLogin / UpdateChecker: SMAppService login-item toggle, and a
  minimal VERSION-file update check that alerts on a manual check and
  posts a quiet notification on the automatic one.

Also drops the standalone CLI in favour of GUI-only, and adds a
placeholder app icon drawn from vector shapes rather than composited on
top of Claude's own icon assets.

Claude Desktop is located at runtime rather than assumed: a path the user
picked previously, then /Applications, then a per-user ~/Applications
install, each accepted only if it actually contains the executable. If
none match, launching a profile asks the user to locate it once and
remembers the answer — a launch that silently does nothing gives them no
way to work out what's wrong.
2026-08-04 21:56:22 +06:00