Skip to main content
강홍재/ James
← Work
Live2026 · Solo Builder· Started(First Commit date)

Sheen

A menu bar app for cleaning your Mac - lock the keyboard to wipe it, fill the screen with a flat color to reveal smudges, dust, and dead pixels, plus spill first-aid (bonus). No permissions, no data collection; sandboxed and shipped on the Mac App Store.

  • Swift 6
  • AppKit / SwiftUI
  • macOS Menu Bar
  • Mac App Store
  • Zero-permission / Sandboxed
Screenshots
  • Keyboard lock - "keystrokes won't register while you wipe; your trackpad still works." Unlock anytime, auto-unlocks in 60s so you're never stuck

  • Screen cleaning - a flat color fill makes every smudge, speck, and dead pixel stand out; cycle the six inspection colors along the bottom

  • Spill first-aid (bonus) - "SHUT DOWN NOW" sits huge at the top with the rest (unplug, tent to drain, dry) on one screen to read before powering off; it guides, it can't power the Mac off for you

Setup

Problem

Wiping a Mac keyboard presses keys and fires off stray input or commands. Screen smudges and dust only show when you tilt it under the light, and a spilled drink triggers panic that skips the right response order - all the way to motherboard damage.

Context

Started from a nuisance I kept running into. But keyboard locking itself is a five-second feature that free tools (KeyboardCleanTool and others) already do perfectly, so I decided you can't win by building a better lock. I moved the category from "keyboard locker" to "Mac cleaning ritual" - using the lock as the entry point and bundling the real adjacent needs around it (screen cleaning, a hygiene habit, spill first-aid).

Build

What I did
  • Keyboard lock for cleaning - a full-screen overlay swallows keystrokes (a local NSEvent monitor) so nothing types while you wipe. The trackpad and mouse stay live so you can always unlock, with a hold-Esc-1.5s escape hatch and a 60s auto-unlock so you're never stuck
  • Screen cleaning mode - fills every display with a flat color to reveal smudges, dust, and dead pixels; cycles six inspection colors (each labeled with what it reveals) via an auto-hiding toolbar
  • Cleaning streak + weekly reminder - each lock/screen-clean session builds a streak (shown in the menu bar), with an optional weekly notification to keep the habit
  • Spill first-aid (bonus) - one tap silences a wet, misbehaving keyboard and shows "SHUT DOWN NOW" huge at the top, with the rest of the steps (unplug, tent to drain, dry) on one screen
  • Zero-permission and sandboxed - runs with no Accessibility or Input Monitoring prompt (the only permission is a standard notification one, and only when you turn the weekly reminder on). No data collection, no network, no account
Product decisions
  • The keyboard lock as an entry point, not the hero - locking is already free and perfect, so I bundled screen cleaning, habit, and first-aid to move the category to "one app for cleaning your Mac"
  • Demoted spill first-aid from hero to bonus (decided 2026-07-08) - opening a menu bar app mid-panic is unrealistic, and being sandboxed the app can only guide, not actually power the Mac off. I put everyday cleaning (lock + screen + habit) up front instead, and wrote the risk into the spec myself: spill was the strongest differentiator, so demoting it makes the moat shallower
  • "You can never get stuck" as the first principle of the lock UX - trackpad stays live + hold-Esc + 60s auto-unlock, three layers of escape
  • The emergency screen's design rule: it must not require keeping a wet Mac powered on to read it. The early four-step pagination invited "wait while watching the screen," which was self-contradictory, so I put SHUT DOWN NOW huge at the top and packed the rest onto one screen to read within two seconds before powering off
  • Paid-only, one-time purchase ($4.99 / ₩4,400) - no free tier, no subscription, no IAP; buying it unlocks everything. A subscription felt wrong for a cleaning utility, so a small one-time price it is
QA considerations
  • Key-swallow completeness - no keystroke leaks to the app behind the overlay while active (including the accessory-focus regression, verified by hand)
  • Three independent escape hatches (live trackpad, hold-Esc, 60s auto-unlock) each work on their own
  • The keyboard lock never persists if the app quits unexpectedly - it always releases (fail-safe)
  • The screen-clean overlay covers every display on multi-monitor setups and the 6-color cycle is correct
  • Permission/sandbox boundary - zero Accessibility/Input-Monitoring prompts; verified the sandbox container is created and runs without a crash

Outcome

Metrics
  • Live on the Mac App Store - Utilities, macOS 13+, 4+, one-time purchase $4.99 / ₩4,400
  • Zero permission prompts, sandboxed, no data collection, network, or account
  • App size 346.7 KB, menu-bar only (no Dock icon)
  • Just launched - reviews, sales, and conversion metrics not measured yet

Process (planning → build)

The same template from problem and hypothesis through scope, spec (SSOT), build, the QA gate, and release - how this was planned and driven.

Problem & hypothesis

Started from keys getting pressed while wiping the keyboard. But I read the market coldly - keyboard locking is a five-second feature that free tools already do perfectly, so lock quality can't win. I reset the hypothesis to "use the lock as the entry point and bundle the real adjacent needs (screen cleaning, hygiene habit, spills)" and moved the category from "keyboard locker" to "Mac cleaning ritual."

Skills · Problem framing · hypothesis

Scope & priority

Ranked four angles - screen cleaning (the main differentiator), keyboard lock (safe escape), hygiene streak, and spill first-aid (bonus). Right before launch I made the call to demote spill from hero to bonus, and left the risk of lowering the strongest differentiator in the spec so I'd keep tracking it.

Skills · Scoping · prioritization

Spec-first (SSOT)

Kept SSOT.md ahead of the code - the rule was that when product direction changes, this document gets fixed before the code. Positioning, pricing, distribution constraints, and non-goals were split into "RESOLVED" and "open questions" so the decisions wouldn't drift even solo.

Skills · Spec · documentation

Build & iteration

Swift 6, a single XcodeGen build (project.yml -> .xcodeproj). An accessory app: an AppKit menu bar (NSStatusItem) with SwiftUI overlays. Lock, screen cleaning, and spill all share the same full-screen overlay structure, so code and UX stay in one frame.

Skills · Execution · delivery

Verification (QA gate)

Made "you can never get stuck" the first principle of the lock UX and verified the three layers (live trackpad, hold-Esc, 60s auto-unlock). Caught a real regression - because an accessory app doesn't grab key focus, keys leaked past the overlay to the app behind it - and fixed it with an activation switch. Confirmed sandbox eligibility down to the signed build creating a container and running without a crash.

Skills · Quality · risk

Release

Signed and notarized with a single sandbox entitlement (app-sandbox) and shipped to the Mac App Store as a paid-only app ($4.99 / ₩4,400). The first store screenshots lead with the keyboard lock and screen cleaning, so the answer to "but the free one is enough" shows on the very first screen.

Skills · Release

Tech stack
  • Swift 6
  • AppKit (NSStatusItem)
  • SwiftUI (overlays)
  • NSEvent local monitor
  • UserNotifications
  • XcodeGen
  • App Sandbox (Mac App Store)