Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pmset -g assertions | grep Vigil

- **LSUIElement = YES**: No Dock icon, no Cmd+Tab. The app only appears in the menu bar and Activity Monitor.
- **Sandbox enabled**: IOPMAssertion is sandbox-compatible — no special entitlements needed. Confirmed working in sandboxed Release + TestFlight builds.
- **App icon vs menu bar icon**: Two separate assets. App icon (1024px character artwork) shows in Finder. Menu bar icon (18px) shows in the menu bar strip.
- **App icon vs menu bar icon**: Two separate assets. App icon (1024px lighthouse artwork) shows in Finder. Menu bar icon (18px monochrome template) shows in the menu bar strip.
- **Assertion lifecycle**: The OS automatically releases all IOPMAssertions if the app crashes — no leaked assertions possible.
- **Verify it works**: `pmset -g assertions | grep Vigil` shows the active assertion type and reason string.
- **No colons in PRODUCT_NAME**: Apple rejects `.app` bundles with `:` in the name (ITMS-90267). The App Store display name can have colons/dashes, but PRODUCT_NAME must not.
4 changes: 0 additions & 4 deletions CREDITS
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
# Credits

## Icons

App icon based on "Awake" icon created by Freepik - Flaticon
https://www.flaticon.com/free-icons/awake
6 changes: 3 additions & 3 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A utility earns trust by being:
- **Quiet** — it stays out of the way until needed.
- **Obvious** — no learning curve, no surprises.

Vigil's only personality is the character icon. That icon carries the entire brand. Everything around it is system-native — invisible scaffolding that lets the icon and the primary toggle speak.
Vigil's only personality is the lighthouse icon. That icon carries the entire brand. Everything around it is system-native — invisible scaffolding that lets the icon and the primary toggle speak.

---

Expand All @@ -35,7 +35,7 @@ Every pixel of visual weight must be earned. The hierarchy:

| Weight | Element | Why it earns weight |
|--------|---------|-------------------|
| Heaviest | Character icon | Brand identity — the one thing that's "Vigil" |
| Heaviest | Lighthouse icon | Brand identity — the one thing that's "Vigil" |
| Heavy | Primary toggle | The reason the app exists |
| Medium | Mode selector | Modifies how the primary action works |
| Light | Settings rows | Used once, then forgotten |
Expand All @@ -45,7 +45,7 @@ Nothing outside this hierarchy gets visual weight. No decorative elements. No bo

### 3. One Personality Element

The character icon is Vigil's single personality element. It's playful, distinctive, and recognizable. **Everything else is invisible.** System fonts, system controls, system colors. The moment a second element competes for personality — a custom toggle, a branded color, a non-standard font — the interface becomes noisy and the icon loses its power.
The lighthouse icon is Vigil's single personality element. It's distinctive and recognizable. **Everything else is invisible.** System fonts, system controls, system colors. The moment a second element competes for personality — a custom toggle, a branded color, a non-standard font — the interface becomes noisy and the icon loses its power.

### 4. State as Reward

Expand Down
2 changes: 1 addition & 1 deletion PRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
- [ ] Notarized DMG for direct download

## Resolved Decisions
1. **Icon design**: Custom character artwork — full opacity when active, dimmed when inactive (menu bar + popover hero)
1. **Icon design**: Custom lighthouse artwork — full opacity when active, dimmed when inactive (popover hero)
2. **Sleep modes**: Two presets — "Display & System" and "System Only" — one active at a time
3. **Notifications (MVP)**: None — icon state change is sufficient for user-initiated toggles. Notifications reserved for timer expiry (v0.3)
4. **Quit while active**: No confirmation dialog — just quit and release
Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,3 @@ pid 1234(Vigil): PreventUserIdleDisplaySleep named: "Vigil is keeping your Mac a

Swift 6, SwiftUI, zero third-party dependencies. ~300 lines of code across three files.

## Credits

App icon based on "Awake" icon created by [Freepik - Flaticon](https://www.flaticon.com/free-icons/awake).
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_128x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_256x256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/Vigil/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
},
"properties" : {
"preserves-vector-representation" : false,
"template-rendering-intent" : "original"
"template-rendering-intent" : "template"
}
}
Binary file modified app/Vigil/Assets.xcassets/MenuBarIcon.imageset/menubar_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 7 additions & 6 deletions app/Vigil/MenuBarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ struct MenuBarView: View {
// MARK: - Hero

private var heroSection: some View {
VStack(spacing: 8) {
Image("MenuBarIcon")
VStack(spacing: 4) {
Image(nsImage: NSApplication.shared.applicationIconImage)
.resizable()
.scaledToFit()
.frame(height: 48)
.frame(height: 80)
.clipShape(RoundedRectangle(cornerRadius: 16))
.opacity(sleepManager.isActive ? 1.0 : 0.4)
.animation(.spring(duration: 0.25), value: sleepManager.isActive)

Expand All @@ -55,7 +56,7 @@ struct MenuBarView: View {
}

Text(sleepManager.isActive ? "Sleep prevention is on" : "Sleep prevention is off")
.font(.subheadline)
.font(.caption)
.foregroundStyle(.secondary)
}
.padding()
Expand Down Expand Up @@ -99,7 +100,7 @@ struct MenuBarView: View {
private var settingsSection: some View {
VStack(spacing: 0) {
Toggle(isOn: $launchAtLogin) {
Label("Launch at Login", systemImage: "sunrise")
Text("Launch at Login")
.frame(maxWidth: .infinity, alignment: .leading)
}
.onChange(of: launchAtLogin) { _, newValue in
Expand All @@ -117,7 +118,7 @@ struct MenuBarView: View {
get: { sleepManager.rememberLastState },
set: { sleepManager.rememberLastState = $0 }
)) {
Label("Remember Last State", systemImage: "arrow.counterclockwise")
Text("Remember Last State")
.frame(maxWidth: .infinity, alignment: .leading)
}
.padding(.vertical, 4)
Expand Down
Binary file added assets/appstore/one-click.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/appstore/two-modes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified website/img/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified website/img/scr1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified website/img/scr2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions website/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ <h1 class="animate-in delay-2">
</h1>
<p class="text-lg text-zinc-400 max-w-lg mx-auto mb-10 mt-6 leading-relaxed animate-in delay-3">
Most sleep prevention tools give you thirty features when all you needed was one click.
<br>
Vigil is that one click.
</p>
<div class="animate-in delay-4">
Expand Down