shhhhhh 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -0,0 +1,59 @@
1
+ # Plan: Homebrew Distribution for `shh`
2
+
3
+ ## Context
4
+ `shh` is a macOS CLI tool for managing notification settings. It's built in Python with click + rich, packaged with hatchling. Currently installable only via `pip install -e .` locally — not yet on PyPI or Homebrew. The goal is to make it installable via `brew install alexpriest/tap/shh`.
5
+
6
+ ## Steps
7
+
8
+ ### 1. Prepare `pyproject.toml` for PyPI
9
+ Add missing metadata fields that PyPI requires/expects:
10
+ - `license` (MIT)
11
+ - `authors`
12
+ - `urls` (homepage, repository)
13
+ - `classifiers` (macOS-only, CLI, Python 3.11+)
14
+
15
+ **File:** `/Users/alex/Code/.conductor/workspaces/shhhhhh/medan/pyproject.toml`
16
+
17
+ ### 2. Publish to PyPI
18
+ ```bash
19
+ cd /Users/alex/Code/.conductor/workspaces/shhhhhh/medan
20
+ python3.11 -m build
21
+ twine upload dist/shhhhhh-0.1.0*
22
+ ```
23
+ This produces the sdist `.tar.gz` that Homebrew needs.
24
+
25
+ ### 3. Create `alexpriest/homebrew-tap` GitHub repo
26
+ ```bash
27
+ gh repo create alexpriest/homebrew-tap --public --description "Homebrew formulae"
28
+ ```
29
+ Structure:
30
+ ```
31
+ homebrew-tap/
32
+ Formula/
33
+ shh.rb
34
+ README.md
35
+ ```
36
+
37
+ ### 4. Generate the Homebrew formula
38
+ Use `homebrew-pypi-poet` to auto-generate resource stanzas with correct URLs + SHA256 hashes:
39
+ ```bash
40
+ python3.11 -m venv /tmp/poet-env
41
+ source /tmp/poet-env/bin/activate
42
+ pip install shhhhhh homebrew-pypi-poet
43
+ poet -f shhhhhh
44
+ ```
45
+ Then edit the output to add: `depends_on :macos`, description, homepage, license, and test block.
46
+
47
+ ### 5. Push formula and test
48
+ - Commit `Formula/shh.rb` to the tap repo
49
+ - Test: `brew install alexpriest/tap/shh && shh --help`
50
+
51
+ ### 6. Update README with Homebrew install instructions
52
+ Add `brew install alexpriest/tap/shh` to the medan README.
53
+
54
+ **File:** `/Users/alex/Code/.conductor/workspaces/shhhhhh/medan/README.md`
55
+
56
+ ## Verification
57
+ 1. `brew install alexpriest/tap/shh` succeeds on a clean system
58
+ 2. `shh --help` outputs usage info
59
+ 3. `shh list` works (with Full Disk Access granted)
File without changes
shhhhhh-0.1.0/.git ADDED
@@ -0,0 +1 @@
1
+ gitdir: /Users/alex/Code/tools/shhhhhh/.git/worktrees/medan
@@ -0,0 +1,8 @@
1
+ .worktrees/
2
+ __pycache__/
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .eggs/
7
+ *.pyc
8
+ .venv/
shhhhhh-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: shhhhhh
3
+ Version: 0.1.0
4
+ Summary: Silence your Mac, app by app
5
+ Project-URL: Homepage, https://github.com/alexpriest/shhhhhh
6
+ Project-URL: Repository, https://github.com/alexpriest/shhhhhh
7
+ Author: Alex Priest
8
+ License-Expression: MIT
9
+ Classifier: Environment :: Console
10
+ Classifier: Operating System :: MacOS
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Topic :: Utilities
13
+ Requires-Python: >=3.11
14
+ Requires-Dist: click>=8.0
15
+ Requires-Dist: rich>=13.0
@@ -0,0 +1,44 @@
1
+ # shh
2
+
3
+ Silence your Mac, app by app.
4
+
5
+ A CLI tool for batch-managing macOS notification settings — toggle sound and badges for all apps or specific ones in a single command.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install shhhhhh
11
+ ```
12
+
13
+ ## Setup
14
+
15
+ `shh` needs **Full Disk Access** to manage notification settings.
16
+
17
+ 1. Open **System Settings → Privacy & Security → Full Disk Access**
18
+ 2. Enable your terminal app (Terminal, iTerm2, Ghostty, etc.)
19
+ 3. Restart your terminal
20
+
21
+ If you skip this step, `shh` will guide you through it on first run.
22
+
23
+ ## Usage
24
+
25
+ ```bash
26
+ shh list # show all apps + settings
27
+ shh sound off --all # mute everything
28
+ shh sound on Mail Messages # unmute specific apps
29
+ shh badges off --all # remove all badge icons
30
+ shh undo # restore previous settings
31
+ ```
32
+
33
+ ## How it works
34
+
35
+ `shh` reads and writes macOS notification preferences directly from the `usernoted` plist, then restarts the daemon to apply changes. A backup is automatically created before every change.
36
+
37
+ ## Requirements
38
+
39
+ - macOS 15+ (Sequoia / Tahoe)
40
+ - Python 3.11+
41
+
42
+ ## License
43
+
44
+ MIT
@@ -0,0 +1,54 @@
1
+ # Development
2
+
3
+ ## Setup
4
+
5
+ Requires Python 3.11+. The system Python's pip is too old for editable installs, so use a venv:
6
+
7
+ ```bash
8
+ cd ~/Code/tools/shhhhhh
9
+ python3.11 -m venv .venv
10
+ source .venv/bin/activate
11
+ pip install -e .
12
+ pip install pytest
13
+ ```
14
+
15
+ ## Running
16
+
17
+ ```bash
18
+ shh list # show all apps + settings
19
+ shh sound off --all # mute everything
20
+ shh sound on Mail Messages # unmute specific apps
21
+ shh badges off --all # remove all badge icons
22
+ shh undo # restore previous settings
23
+ ```
24
+
25
+ ## Tests
26
+
27
+ ```bash
28
+ python3 -m pytest tests/ -v
29
+ ```
30
+
31
+ 18 tests across 3 files: plist reader, plist writer, CLI commands.
32
+
33
+ ## Architecture
34
+
35
+ Three modules:
36
+
37
+ - `src/shhhhhh/plist.py` — reads/writes the macOS `usernoted` plist, bitmask manipulation, backup/restore
38
+ - `src/shhhhhh/display.py` — gradient logo, rich tables, result messages
39
+ - `src/shhhhhh/cli.py` — click commands wiring plist + display together
40
+
41
+ ## How it works
42
+
43
+ The tool reads `~/Library/Group Containers/group.com.apple.usernoted/Library/Preferences/group.com.apple.usernoted.plist`, which stores per-app notification flags as a bitmask:
44
+
45
+ - Bit 1 (value 2): badges
46
+ - Bit 2 (value 4): sound
47
+
48
+ After modifying flags, it restarts `usernoted` via `killall usernoted` to apply changes. A timestamped backup is saved to `~/.shh/` before every write.
49
+
50
+ ## Known gaps (v2)
51
+
52
+ - Ambiguous match warning: if you type `shh sound off Ma` and it matches both Mail and Maps, it silently applies to both. Design doc says it should show matches and ask the user to be specific.
53
+ - No `--version` flag
54
+ - No badges-specific CLI tests (shares code path with sound via factory pattern, low risk)
@@ -0,0 +1,137 @@
1
+ # shh (shhhhhh.sh) — Design Document
2
+
3
+ ## Overview
4
+
5
+ A Python CLI tool for batch-managing macOS notification settings. Reads and writes the `usernoted` plist directly, letting you toggle sound and badges for all apps or specific ones in a single command.
6
+
7
+ - **PyPI package**: `shhhhhh`
8
+ - **CLI command**: `shh`
9
+ - **Domain**: `shhhhhh.sh`
10
+
11
+ ## Commands
12
+
13
+ ```
14
+ shh list # show all apps + sound/badge status
15
+ shh sound off --all # mute all apps
16
+ shh sound on --all # unmute all apps
17
+ shh sound off Slack Zoom # mute specific apps (fuzzy match)
18
+ shh sound on Mail Messages # unmute specific apps
19
+ shh badges off --all # remove all badge icons
20
+ shh badges on Mail Messages # re-enable badges for specific apps
21
+ shh undo # restore most recent backup
22
+ ```
23
+
24
+ ## Branding
25
+
26
+ ### Logo
27
+ Box-drawing chunky "SHH" wordmark with top-to-bottom grayscale gradient (bright to dim, like sound fading out). Uses 256-color ANSI codes, one shade per line.
28
+
29
+ ```
30
+ ███████╗██╗ ██╗██╗ ██╗
31
+ ██╔════╝██║ ██║██║ ██║
32
+ ███████╗███████║███████║
33
+ ╚════██║██╔══██║██╔══██║
34
+ ███████║██║ ██║██║ ██║
35
+ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝
36
+ ```
37
+
38
+ ### Tagline
39
+ Dim text below logo: `silence your mac, app by app`
40
+
41
+ ### Colors
42
+ Grayscale palette throughout. Green checkmarks, dim crosses for status.
43
+
44
+ ## Data Layer
45
+
46
+ ### Source file
47
+ ```
48
+ ~/Library/Group Containers/group.com.apple.usernoted/Library/Preferences/group.com.apple.usernoted.plist
49
+ ```
50
+
51
+ ### Flags bitmask
52
+ - Bit 1 (value 2): Badge app icon
53
+ - Bit 2 (value 4): Play sound for notifications
54
+
55
+ ### App name resolution
56
+ 1. Extract from `path` field (e.g. `/Applications/Slack.app` -> `Slack`)
57
+ 2. Fall back to `bundle-id` if no path
58
+
59
+ ### Fuzzy matching
60
+ Case-insensitive substring match against friendly app names. If ambiguous, show matches and ask user to be more specific.
61
+
62
+ ### System apps
63
+ Skip entries where `bundle-id` starts with `_SYSTEM_CENTER_:`.
64
+
65
+ ### Write flow
66
+ 1. Read current plist
67
+ 2. Modify flags bitmask for targeted apps
68
+ 3. Write plist back
69
+ 4. Restart `usernoted` daemon via `killall usernoted`
70
+
71
+ ## Output Examples
72
+
73
+ ### `shh list`
74
+
75
+ ```
76
+ [gradient logo]
77
+
78
+ silence your mac, app by app
79
+
80
+ 47 apps · 43 with sound · 45 with badges
81
+
82
+ App Sound Badges
83
+ ────────────────────────────────────────
84
+ Calendar ✓ ✓
85
+ Chrome ✓ ✓
86
+ FaceTime ✓ ✓
87
+ Linear ✓ ✓
88
+ Mail ✓ ✓
89
+ Messages ✗ ✗
90
+ Slack ✗ ✓
91
+ ...
92
+ ```
93
+
94
+ ### `shh sound off --all`
95
+
96
+ ```
97
+ [gradient logo]
98
+
99
+ Muted 43 apps
100
+
101
+ To undo: shh sound on --all
102
+ ```
103
+
104
+ ## Safety
105
+
106
+ - Backup plist to `~/.shh/backup-<timestamp>.plist` before first write
107
+ - `shh undo` restores most recent backup
108
+ - Confirm before `--all` operations (skip with `--yes` / `-y`)
109
+
110
+ ## Tech Stack
111
+
112
+ - Python 3.11+
113
+ - `rich` — colored output, tables, status indicators
114
+ - `plistlib` (stdlib) — read/write plist
115
+ - `click` — CLI argument parsing
116
+ - `subprocess` — restart usernoted after changes
117
+
118
+ ## Project Structure
119
+
120
+ ```
121
+ ~/Code/tools/shhhhhh/
122
+ ├── README.md
123
+ ├── pyproject.toml
124
+ ├── src/
125
+ │ └── shhhhhh/
126
+ │ ├── __init__.py
127
+ │ ├── cli.py # click commands + banner
128
+ │ ├── plist.py # read/write usernoted plist
129
+ │ └── display.py # rich table + formatting
130
+ ```
131
+
132
+ ## Future (not v1)
133
+
134
+ - SwiftUI wrapper app (Option C from brainstorming)
135
+ - Additional settings: banners/alert type, lock screen, previews
136
+ - `shh profile save/load` — save/restore named configurations
137
+ - Homebrew formula