# `keepmacawake` command-line reference

The `keepmacawake` tool controls the same session as the Keep Mac Awake menu bar panel. It is meant for people in a terminal and for AI agents; use over SSH as the logged-in user has not been verified yet. The installer links it as `/usr/local/bin/keepmacawake`; the binary itself stays inside the signed app.

The session belongs to a per-user background service (the coordinator). The tool sends one request, prints one answer and exits; the session continues after it exits. Quitting the menu bar app, or `keepmacawake app quit`, ends the session.

## Commands

| Command | What it does |
| --- | --- |
| `keepmacawake status` | Shows the session state. |
| `keepmacawake start --unlimited` | Starts a session without a time limit. |
| `keepmacawake start --hours N` | Starts a session of N whole hours, 1 to 168. |
| `keepmacawake stop` | Ends the session and restores the sleep setting. |
| `keepmacawake config get` | Shows the battery settings for the next session. |
| `keepmacawake config set --battery allowed\|ac-only [--min-battery N]` | Changes them. The threshold is 1 to 100%. A running session keeps its own settings. |
| `keepmacawake app launch` | Opens the menu bar app. |
| `keepmacawake app quit` | Ends the session, then quits the menu bar app. |
| `keepmacawake buy` | Opens the purchase page for this Mac in the browser and prints the link. |
| `keepmacawake restore` | Restores a purchase made for this Mac (one request to `keepmacawake.com`). |
| `keepmacawake capabilities --json` | Describes this contract: commands, options, phases, access states and exit codes. |

During the 3-day trial, counted from the first session on the Mac, a session lasts at most 8 hours; `start --unlimited` or `--hours` above 8 exits with 4 and `purchase_required` without touching anything, and so does any `start` after the trial. A running session is never ended by the trial.

`start` returns after the system service has confirmed the session, or refused it. With AC-only settings on battery the session is refused; with AC disconnected later, it waits for AC power (`phase` `waitingForAC`, `confirmed` false).

Options: `--json`, `--timeout SECONDS` (1-120, default 15), `--no-input` (the tool never prompts), `--help`, `--version`.

## JSON output

With `--json`, stdout carries exactly one JSON object on one line; diagnostics go to stderr. Keys are stable; new keys may be added.

```json
{"access":{"mac_id":"0123456789abcdef0123456789abcdef","max_hours":null,"state":"purchased","trial_seconds_left":null,"trial_started":true},"app_version":"1.0.0","config":{"battery":"ac-only","min_battery_percent":20},"protocol_version":"2","result":"ok","schema_version":1,"session":{"confirmed":true,"hours":8,"last_end_reason":null,"live":true,"message":"Sleep prevention is on.","min_battery_percent":null,"phase":"active","remaining_seconds":28734,"unlimited":false}}
```

| Key | Meaning |
| --- | --- |
| `result` | `ok` or `error` |
| `session.phase` | `checking`, `idle`, `starting`, `active`, `waitingForAC`, `stopping`, `unavailable` or `failed` |
| `session.confirmed` | True only while the system service has confirmed the session within the last 6 seconds |
| `session.live` | A session started through Keep Mac Awake is running |
| `session.remaining_seconds`, `session.hours`, `session.unlimited` | Time left and the accepted duration |
| `session.min_battery_percent` | The battery threshold of the running session, or null for AC only |
| `session.last_end_reason` | Why the last session ended, for example `durationElapsed`, `batteryThresholdReached`, `clientStopped` |
| `config.battery`, `config.min_battery_percent` | Settings for the next session |
| `access.state` | `purchased`, `trial` or `trialEnded` |
| `access.trial_seconds_left`, `access.trial_started` | Time left in the trial (its full length before the first session); null when purchased |
| `access.max_hours` | The longest session a `start` may ask for; null without a limit |
| `access.mac_id` | This Mac's ID, used by `buy` and `restore` and for support |
| `error.code`, `error.message`, `error.retryable` | Present when `result` is `error` |

## Exit codes

| Code | Meaning |
| --- | --- |
| 0 | Success |
| 1 | The request failed |
| 2 | Invalid arguments |
| 4 | Action needed from the user, for example AC power, a purchase (`purchase_required`), or running without `sudo` |
| 5 | Conflict: a session already runs, or there is no session to stop |
| 6 | The background service is not available or Keep Mac Awake is not installed |
| 7 | No answer in time. After a `start` or `stop` that timed out, run `status`: the request may still have completed |

## Installing from the command line

`curl -fsSL https://keepmacawake.com/install.sh | sh` installs or updates Keep Mac Awake; `sh -s -- --uninstall` removes it, `--dry-run` only downloads and checks the package, `--version X.Y.Z` picks a release. The script checks the package's SHA-256, Developer ID signature and notarization before running macOS Installer, asks for an administrator once (in the terminal, or in a system dialog when no terminal is attached, as for an AI agent) and refuses while a session runs. Its exit codes: 0 done, 1 failed, 2 invalid arguments, 3 this Mac is not supported, 4 action needed from the user, 5 a session is running.

## Rules and limits

- Run it as the logged-in user. `sudo keepmacawake` is refused, and a call from a user who is not at the console cannot start a session.
- Any process of the same user can run the tool. It cannot tell a trusted agent from an untrusted one; it can only do what the panel does, and it never passes commands, paths or addresses to the system service.
- Nothing starts automatically, also not after a restart.
