# schmeeve-toolz — Agent Guide

Personal macOS automation toolkit. Newer scripts deploy to `~/.local/bin/`; older scripts live in `~/Dropbox/bin/`. Mostly shell scripts for power management, network, and system automation, triggered by Keyboard Maestro and cron.

## Commands

No build/test/deploy infrastructure exists. Scripts run directly:

```sh
./scriptname          # run any script directly
chmod +x scriptname   # scripts should already be executable
```

Scripts are deployed by copying (or symlinking) to `~/.local/bin/` (newer) or `~/Dropbox/bin/` (legacy). There is no install step.

Check shebang (`#!/bin/sh` or `#!/bin/bash`) before running — some use bashisms like `[[ ]]` and arrays.

## Language & Style

| Aspect | Convention |
|---|---|
| **Shell** | `#!/bin/bash` for complex scripts, `#!/bin/sh` for simple one-liners. Mix of both. |
| **Python** | `#!/usr/bin/python3` for mail helpers. Hardcoded SMTP config block at top. |
| **AppleScript** | Compiled `.scpt` files (binary — cannot view as text). Shell scripts invoke via `/usr/bin/osascript`. |
| **Indentation** | Inconsistent across codebase. 2-space dominant but no enforced standard. |
| **Naming** | `lowercase-with-hyphens` for scripts. `UPPER_CASE` for config constants, `lower_case` for locals. |
| **Functions** | `name() {` syntax (rarely used). |
| **Quoting** | Inconsistent. Many older scripts use bare `$var`. Newer scripts use `"${var}"`. Assume unquoted vars will break on spaces. |

## Architecture

### What it is

A flat collection of ~60+ standalone scripts organized by function, NOT a structured project. No packages, no modules, no dependencies file.

### How scripts relate

```
presleep ──→ presleep_quitapps ──→ send_quitbrowsers_mail3.py
    │                                        │
    └──── send_sleep_mail3.py                (sends email)
    
idlecheck ──→ idlecheck_tasks ──→ idlecheck_quitvideowake
                  │              ──→ idlecheck_quitaudioprevent
                  └──── idlecheck_caffeinatestuck
    
wakenotify ──→ wakelogstart / wakelogend
    
sleep ──→ idlecheck_caffeinatestuck
    
pull-all ──→ iterates repos in ~/git/ matching *schmeeve* remote
checkin-all ──→ iterates repos in ~/git/ matching *schmeeve* remote
```

Sub-scripts are invoked via `/bin/bash` or `/bin/sh`, never sourced.

### Trigger chain

1. **Keyboard Maestro** (macros) — most common trigger. Evidence: `$KMINFO_MacroName` env var used in email subjects, `dactoggle` bound to hotkey.
2. **cron/launchd** — likely for `checkin-all`, `pull-all`, maintenance scripts.
3. **pmset schedule** — `wakenotify` and `maintwakes` are scheduled via `pmset repeat`.

### Power management flow

```
[Keyboard Maestro / cron / pmset schedule]
    │
    ▼
presleep / sleep / idlecheck / shutdown_safe / wakenotify
    │
    ├── pmset (sleep, assertions, schedule)
    ├── osascript (quit apps, shutdown)
    ├── HomeKit URL scheme (smart home)
    └── Python mailer (status email via SMTP)
```

## Gotchas & Non-Obvious

### Hardcoded paths

- `/Users/shughey/Dropbox/bin/` is hardcoded in many scripts (`sleep`, `presleep`, `wakenotify`, `idlecheck_tasks`, `maintwakes`). Will break on a different user's machine. Use `$HOME` when adding references.
- `/Users/shughey/git/` is hardcoded in `checkin-all` and `pull-all`.
- `/Usres/shughey/` (typo) exists in `Angus/tdarr-bounce` — affects the `Angus` machine only.

### Machine-specific branching

Several scripts branch on `scutil --get ComputerName` output:
- `dactoggle` — branches on `Angus` vs `Petula` vs `Callum` for HomeKit tokens.
- `presleep_quitapps` — same pattern.

Add new branches when adding machine-specific behavior.

### Authentication tokens in scripts

HomeKit x-callback-url tokens are **hardcoded** in `dactoggle` and `presleep_quitapps`. These are auth tokens for homecontrol.d27n.com. Do not commit to public repos.

### Email pipeline

All mail scripts:
1. Read `$ESUBJ` env var for subject (set by Keyboard Maestro)
2. Compute `CNAME` from `platform.node()` (Python) or `scutil --get ComputerName` (shell)
3. Send via `emailz.d27n.com:587` with hardcoded credentials

### Deprecated patterns to avoid

- `` `backtick command substitution` `` — use `$( )` instead
- `$[ arithmetic ]` — use `$(( ))` instead
- Bare `$var` without quotes — use `"${var}"`
- `export PATH=$PATH:/usr/bin/local` — `/usr/bin/local` doesn't exist on standard macOS (typo for `/usr/local/bin`)

### Risk zones (pmset)

These commands are **destructive** if run unintentionally:
- `pmset schedule cancelall` — wipes all scheduled sleep/wake events
- `pmset repeat cancel` — wipes recurring schedule
- `osascript -e 'tell application "System Events" to shut down'` — immediate shutdown
- `pmset sleepnow` / `pmset displaysleepnow` — immediate sleep

### Cloud sync artifacts

Conflicted copies from iCloud/Google Drive exist throughout the repo (`displaycount (Callum.local's conflicted copy YYYY-MM-DD).scpt`, `main (host's conflicted copy).scpt` inside `.app` bundles). These are stale and can be cleaned up.

### sudo requirements

Some scripts reference `sudo pmset ...` which requires `NOPASSWD` in sudoers (e.g., `/etc/sudoers.d/shughey`). Not portable.

### macOS-specific commands

All scripts depend on macOS-only commands:
- `pmset` — power management
- `scutil` — system config (ComputerName)
- `sw_vers` — macOS version
- `osascript` — AppleScript bridge
- `log show --style syslog` — unified logging
- `diskutil` — disk management
- `networksetup` — network config
- `sips` / `iconutil` — image processing (makeicns)
- `hdiutil` — disk images (bootableBigSur)

### arc-export subproject

`arc-export/` is a vendored third-party tool (from [ivnvxd/arc-export](https://github.com/ivnvxd/arc-export)) — converts Arc Browser pinned tabs to HTML bookmarks. Has its own MIT license. Don't modify unless fixing bugs.

### Test data files

- `wakemaints.txt` — maintenance window config (read by `maintwakes`)
- `test-caffeinate.txt` — test data for caffeinate detection
- `test.sh` — sanity check/test script
- `.nova/Configuration.json` — Nova editor config (sets default syntax to shell)

## .app Bundles

Two AppleScript `.app` bundles follow this structure:

```
*.app/
  Contents/
    Info.plist         # CFBundleExecutable=applet, CFBundlePackageType=APPL
    PkgInfo            # "APPLaplt"
    MacOS/applet       # Compiled runtime binary
    Resources/
      applet.icns      # Icon
      applet.rsrc      # Resource fork
      Scripts/main.scpt # The actual AppleScript (compiled binary)
    _CodeSignature/    # (unmount-cli only)
```

## What NOT to do

- Don't add comments to scripts unless the user asks. Many scripts have minimal or no comments.
- Don't fix inconsistent quoting/indentation across the codebase — it's a personal toolkit, not a shared project.
- Don't assume `set -euo pipefail` exists — only `checkin-all` and `pull-all` use it.
- Don't run `pmset schedule cancelall` or `pmset repeat cancel` unless explicitly asked.
- Don't commit changes without user confirmation (per agent rules).
