175 lines
7.0 KiB
Markdown
175 lines
7.0 KiB
Markdown
# schmeeve-toolz — Agent Guide
|
|
|
|
Personal macOS automation toolkit deployed to `~/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 `~/Dropbox/bin/`. 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).
|