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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ and this project adheres to [Semantic Versioning 2.0.0](https://semver.org/spec/

## [Unreleased]

### Added
- **`mm setup` / `mm uninstall` registram os agents do launchd** depois de
`brew` / `pipx` / `pip`. Homebrew instalava só o CLI; log diário e
alerta de bateria ficavam no `./install.sh`. `mm setup` grava os plists
em `~/Library/LaunchAgents/` apontando para o `mm` invocado (caminho
absoluto, sem seguir o symlink do Cellar) e manda stdout/stderr do
agent para Application Support. `mm uninstall` tira só os agents —
o CLI e o CSV ficam. `./install.sh` passa a chamar `mm setup`.

## [0.1.2] — 2026-08-14

### Added
Expand Down
50 changes: 42 additions & 8 deletions COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mm --version # installed version
| **Hardware/system** | [`mm`](#mm-status), [`mm battery`](#mm-battery), [`mm health`](#mm-health), [`mm disk`](#mm-disk), [`mm clean`](#mm-clean), [`mm net`](#mm-net) |
| **Visualization** | [`mm watch`](#mm-watch), [`mm doctor`](#mm-doctor) |
| **Battery — history** | [`mm log`](#mm-log), [`mm history`](#mm-history), [`mm alerts`](#mm-alerts) |
| **Setup** | [`mm setup`](#mm-setup), [`mm uninstall`](#mm-uninstall) |
| **Security** | [`mm security`](#mm-security) |
| **Development** | [`mm dev`](#mm-dev), [`mm dev --all`](#mm-dev---all), [`mm dev --check`](#mm-dev---check) |

Expand Down Expand Up @@ -224,6 +225,36 @@ mm alerts

---

## Setup

### `mm setup`
**What it does:** registers the two launchd agents so Homebrew / pipx / pip installs get the same background automation as `./install.sh`.

**Writes** `~/Library/LaunchAgents/com.macmanager.battery-log.plist` and `com.macmanager.battery-alert.plist`, pointing at the `mm` you just ran (absolute path, without following Homebrew's Cellar symlink). Agent stdout/stderr go to `~/Library/Application Support/mac-manager/`.

**When to use:** once after `brew install` or `pipx install`. Safe to re-run after an upgrade.

```bash
mm setup
```

macOS only. Exits `1` on Linux or if the `mm` binary cannot be found.

---

### `mm uninstall`
**What it does:** unloads and deletes those launchd agents. Does **not** uninstall the CLI, the venv, or the CSV history.

**When to use:** you want to stop daily logs and notifications but keep `mm`.

```bash
mm uninstall
```

To remove the CLI itself: `brew uninstall mac-manager` or `pipx uninstall mac-manager`. Source installs can still run `./uninstall.sh` (agents + symlink + venv).

---

## Security

### `mm security`
Expand Down Expand Up @@ -315,7 +346,7 @@ mm dev --check

## Commands invoked by launchd (background)

You normally **don't** run these manually — they stay active automatically after `install.sh`:
You normally **don't** run these manually — they stay active after `mm setup` (or `./install.sh`):

| When it runs | Command | What it does |
|---|---|---|
Expand All @@ -327,10 +358,10 @@ To confirm they're active:
launchctl list | grep macmanager
```

To stop/restart manually:
To stop/restart:
```bash
launchctl unload ~/Library/LaunchAgents/com.macmanager.battery-log.plist
launchctl load ~/Library/LaunchAgents/com.macmanager.battery-log.plist
mm uninstall # stop
mm setup # start / refresh after an upgrade
```

---
Expand Down Expand Up @@ -361,6 +392,7 @@ mm history -n 30
## Output and exit codes

- All commands exit with `0` on success.
- `mm setup` exits `1` on non-macOS or if the `mm` binary cannot be found / launchctl rejects the plist.
- `mm alerts` always exits with `0` (even when it fires a critical alert — it's just a notification).
- Commands that fail to collect a metric (e.g. sandbox blocking) return `WARN`/`?` instead of erroring out.

Expand All @@ -370,12 +402,14 @@ mm history -n 30
|---|---|
| `~/Library/Application Support/mac-manager/battery.csv` | Append-only history of battery measurements |
| `~/Library/Application Support/mac-manager/.alert_state` | Timestamps of the last notification of each type (JSON, controls cooldown) |
| `logs/launchd-log.{out,err}` | stdout/stderr of the agent that runs `mm log` (source install) |
| `logs/launchd-alert.{out,err}` | stdout/stderr of the agent that runs `mm alerts` (source install) |
| `~/Library/Application Support/mac-manager/launchd-log.{out,err}` | stdout/stderr of the agent that runs `mm log` |
| `~/Library/Application Support/mac-manager/launchd-alert.{out,err}` | stdout/stderr of the agent that runs `mm alerts` |

## Reinstall / uninstall

```bash
./install.sh # creates venv, symlink ~/.local/bin/mm and loads launchd agents
./uninstall.sh # removes everything (preserves CSVs in Application Support)
mm setup # register (or refresh) launchd agents — Homebrew, pipx, source
mm uninstall # remove launchd agents only; keeps CLI and CSV
./install.sh # source install: venv, symlink ~/.local/bin/mm, then mm setup
./uninstall.sh # source install: mm uninstall + symlink + venv
```
32 changes: 25 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ pipx install mac-manager # isolated, recommended
pip install --user mac-manager
```

After installation, the `mm` command is on your `PATH`.
After installation, the `mm` command is on your `PATH`. Register the
background agents (daily battery log + alerts) with:

> `pipx`/`pip` installs give you the CLI only. The background
> `launchd` agents (daily log + battery alerts) are set up by the
> source install below, or you can register them manually later.
```bash
mm setup
```

`mm uninstall` removes those agents. It does **not** uninstall the CLI —
use `brew uninstall mac-manager` or `pipx uninstall mac-manager` for that.

### From source

Expand Down Expand Up @@ -90,6 +94,12 @@ source ~/.zshrc
| `mm history -n 20` | Last N recorded measurements |
| `mm alerts` | Runs the alert check (called by launchd) |

### Setup
| Command | What it does |
|---|---|
| `mm setup` | Registers launchd agents (daily log at 09:00 + alerts every 15 min) |
| `mm uninstall` | Removes those agents; keeps the CLI and battery history |

### Security
| Command | What it does |
|---|---|
Expand Down Expand Up @@ -153,11 +163,19 @@ mac-manager/
## Uninstallation

```bash
./uninstall.sh
mm uninstall # launchd agents only (Homebrew / pipx / source)
./uninstall.sh # source install: agents + symlink + venv
```

`mm uninstall` does not remove the CLI. For packaged installs:

```bash
brew uninstall mac-manager
# or
pipx uninstall mac-manager
```

Removes launchd agents, symlink and venv. Preserves battery history in
`~/Library/Application Support/mac-manager/`.
Battery history in `~/Library/Application Support/mac-manager/` is preserved.

## Status

Expand Down
28 changes: 11 additions & 17 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,16 @@ mkdir -p "$HOME/.local/bin"
ln -sf "$SCRIPT_DIR/mm" "$HOME/.local/bin/mm"
echo "==> symlink: $HOME/.local/bin/mm -> $SCRIPT_DIR/mm"

# 4. Ensure logs directory
mkdir -p "$SCRIPT_DIR/logs"

# 5. Install launchd agents (daily log + alerts)
LAUNCH_DIR="$HOME/Library/LaunchAgents"
mkdir -p "$LAUNCH_DIR"

for name in com.macmanager.battery-log com.macmanager.battery-alert; do
src="launchd/${name}.plist"
dest="$LAUNCH_DIR/${name}.plist"
sed "s|{{SCRIPT_DIR}}|$SCRIPT_DIR|g" "$src" > "$dest"
launchctl unload "$dest" 2>/dev/null || true
launchctl load "$dest"
echo "==> launchd: $name loaded"
done
# 4. Register launchd agents via the same path brew/pipx users get:
# `mm setup` writes plists that point at this wrapper and log into
# ~/Library/Application Support/mac-manager/.
if "$HOME/.local/bin/mm" setup; then
echo "==> launchd agents registered"
else
echo "[warning] could not register launchd agents. Run: mm setup" >&2
fi

# 6. PATH check
# 5. PATH check
case ":$PATH:" in
*":$HOME/.local/bin:"*) ;;
*)
Expand All @@ -75,4 +68,5 @@ echo "Active automation:"
echo " • Daily log at 09:00 → ~/Library/Application Support/mac-manager/battery.csv"
echo " • Battery alerts every 15 min (native notifications)"
echo ""
echo "To uninstall everything: ./uninstall.sh"
echo "To unregister agents: mm uninstall"
echo "To uninstall everything (source install): ./uninstall.sh"
7 changes: 4 additions & 3 deletions launchd/com.macmanager.battery-alert.plist
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Reference template. Live plists are generated by `mm setup`. -->
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.macmanager.battery-alert</string>

<key>ProgramArguments</key>
<array>
<string>{{SCRIPT_DIR}}/mm</string>
<string>{{MM_BIN}}</string>
<string>alerts</string>
</array>

Expand All @@ -20,8 +21,8 @@
<true/>

<key>StandardOutPath</key>
<string>{{SCRIPT_DIR}}/logs/launchd-alert.out</string>
<string>{{LOGS_DIR}}/launchd-alert.out</string>
<key>StandardErrorPath</key>
<string>{{SCRIPT_DIR}}/logs/launchd-alert.err</string>
<string>{{LOGS_DIR}}/launchd-alert.err</string>
</dict>
</plist>
7 changes: 4 additions & 3 deletions launchd/com.macmanager.battery-log.plist
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Reference template. Live plists are generated by `mm setup`. -->
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.macmanager.battery-log</string>

<key>ProgramArguments</key>
<array>
<string>{{SCRIPT_DIR}}/mm</string>
<string>{{MM_BIN}}</string>
<string>log</string>
</array>

Expand All @@ -25,8 +26,8 @@
<true/>

<key>StandardOutPath</key>
<string>{{SCRIPT_DIR}}/logs/launchd-log.out</string>
<string>{{LOGS_DIR}}/launchd-log.out</string>
<key>StandardErrorPath</key>
<string>{{SCRIPT_DIR}}/logs/launchd-log.err</string>
<string>{{LOGS_DIR}}/launchd-log.err</string>
</dict>
</plist>
Loading
Loading