feat(ops): launchd jobs (nightly + market-open) + caffeinate + install scripts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DvdRZkyCy9NJpHYDdPqmS
This commit is contained in:
Aryan SinghandClaude Opus 4.8 committed 2026-07-01 16:29:40 -05:00
1 parent 05a8457067
commit afc9106773
8 files changed
+129

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
<?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">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.tradingagent.caffeinate</string>
<!-- Hold the machine awake from just before midnight through the 08:30 execution.
-i idle, -s system-sleep (effective on AC). Display may still sleep (no -d). -->
<key>ProgramArguments</key>
<array>
<string>/usr/bin/caffeinate</string>
<string>-is</string>
<string>-t</string>
<string>33000</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>23</integer>
<key>Minute</key><integer>56</integer>
</dict>
<key>StandardOutPath</key>
<string>/Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_caffeinate.log</string>
<key>StandardErrorPath</key>
<string>/Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_caffeinate.log</string>
</dict>
</plist>
+22
View File
@@ -0,0 +1,22 @@
<?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">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.tradingagent.market_open</string>
<key>ProgramArguments</key>
<array>
<string>/Users/aryan/Documents/GitHub/trading-agent/scripts/execute.sh</string>
</array>
<!-- 08:30 CT = 09:30 ET market open. The script gates on Alpaca's clock. -->
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>8</integer>
<key>Minute</key><integer>30</integer>
</dict>
<key>StandardOutPath</key>
<string>/Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_execution.log</string>
<key>StandardErrorPath</key>
<string>/Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_execution.log</string>
</dict>
</plist>
+22
View File
@@ -0,0 +1,22 @@
<?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">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.tradingagent.nightly</string>
<key>ProgramArguments</key>
<array>
<string>/Users/aryan/Documents/GitHub/trading-agent/scripts/nightly.sh</string>
</array>
<!-- 00:00 CT — research window start -->
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>0</integer>
<key>Minute</key><integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>/Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_nightly.log</string>
<key>StandardErrorPath</key>
<string>/Users/aryan/Documents/GitHub/trading-agent/state/logs/launchd_nightly.log</string>
</dict>
</plist>
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
# launchd wrapper for the market-open execution (08:30 CT = 09:30 ET). Gated on Alpaca's clock.
cd /Users/aryan/Documents/GitHub/trading-agent
export PATH="/opt/homebrew/bin:$PATH"
mkdir -p state/logs
exec uv run python -m execution.run_market_open >> state/logs/launchd_execution.log 2>&1
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
# Install the launchd jobs (caffeinate, nightly research, market-open execution).
set -euo pipefail
PROJ="/Users/aryan/Documents/GitHub/trading-agent"
LA="$HOME/Library/LaunchAgents"
mkdir -p "$LA" "$PROJ/state/logs"
chmod +x "$PROJ/scripts/nightly.sh" "$PROJ/scripts/execute.sh"
for p in caffeinate nightly market_open; do
cp "$PROJ/launchd/ai.tradingagent.$p.plist" "$LA/"
launchctl unload "$LA/ai.tradingagent.$p.plist" 2>/dev/null || true
launchctl load "$LA/ai.tradingagent.$p.plist"
echo "loaded ai.tradingagent.$p"
done
cat <<'EOF'
── ONE-TIME MANUAL STEP (needs sudo) ─────────────────────────────
Wake the Mac nightly at 23:55 CT so the 00:00 job can fire:
sudo pmset repeat wakeorpoweron MTWRFSU 23:55:00
── REQUIREMENTS for overnight runs ───────────────────────────────
• plugged into AC power
• lid OPEN (caffeinate can't beat clamshell sleep on a laptop)
• logged in (lock screen is fine; logged out = jobs won't run)
• oMLX running with a model available (it auto-starts on login)
• .env populated with Alpaca paper + Finnhub keys
──────────────────────────────────────────────────────────────────
EOF
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
# launchd wrapper for the nightly research run (00:00 CT).
cd /Users/aryan/Documents/GitHub/trading-agent
export PATH="/opt/homebrew/bin:$PATH"
mkdir -p state/logs
exec uv run python -m orchestration.run_nightly >> state/logs/launchd_nightly.log 2>&1
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Launch the local dashboard: uv run streamlit run web/dashboard.py
set -euo pipefail
cd "$(dirname "$0")/.."
exec uv run streamlit run web/dashboard.py "$@"
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Remove the launchd jobs and print how to clear the wake schedule.
set -euo pipefail
LA="$HOME/Library/LaunchAgents"
for p in caffeinate nightly market_open; do
launchctl unload "$LA/ai.tradingagent.$p.plist" 2>/dev/null || true
rm -f "$LA/ai.tradingagent.$p.plist"
echo "removed ai.tradingagent.$p"
done
echo
echo "Also clear the nightly wake schedule (needs sudo):"
echo " sudo pmset repeat cancel"