@adaptic/maestro 1.1.5 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# boot-claude-session.sh — Launch interactive Claude Code session on boot
|
|
4
|
+
# =============================================================================
|
|
5
|
+
#
|
|
6
|
+
# Opens Terminal.app with a Claude Code interactive session in the agent's
|
|
7
|
+
# working directory. Called via launchd at login.
|
|
8
|
+
#
|
|
9
|
+
# This is separate from the sophie-daemon (which runs headless as a Node.js
|
|
10
|
+
# process for polling/dispatching). This script provides a visible, interactive
|
|
11
|
+
# Claude Code session that the operator can observe and interact with.
|
|
12
|
+
#
|
|
13
|
+
# Usage:
|
|
14
|
+
# ./scripts/setup/boot-claude-session.sh [agent-dir]
|
|
15
|
+
#
|
|
16
|
+
# =============================================================================
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
|
+
MAESTRO_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
22
|
+
|
|
23
|
+
# Detect agent directory — prefer sophie-ai if it exists
|
|
24
|
+
AGENT_DIR="${1:-}"
|
|
25
|
+
if [ -z "$AGENT_DIR" ]; then
|
|
26
|
+
if [ -d "$HOME/sophie-ai" ]; then
|
|
27
|
+
AGENT_DIR="$HOME/sophie-ai"
|
|
28
|
+
else
|
|
29
|
+
echo "ERROR: No agent directory specified and ~/sophie-ai not found" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
AGENT_NAME=$(basename "$AGENT_DIR")
|
|
35
|
+
LOG_FILE="$MAESTRO_DIR/logs/watchdog/$(date +%Y-%m-%d)-boot-session.log"
|
|
36
|
+
mkdir -p "$(dirname "$LOG_FILE")"
|
|
37
|
+
|
|
38
|
+
log() {
|
|
39
|
+
echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] $1" | tee -a "$LOG_FILE"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# Wait for the system to settle after login (network, services, etc.)
|
|
43
|
+
log "Waiting 15s for system to settle..."
|
|
44
|
+
sleep 15
|
|
45
|
+
|
|
46
|
+
# Check for emergency stop
|
|
47
|
+
if [ -f "$AGENT_DIR/.emergency-stop" ]; then
|
|
48
|
+
log "Emergency stop active — not starting Claude session"
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
if [ -f "$MAESTRO_DIR/.emergency-stop" ]; then
|
|
53
|
+
log "Emergency stop active in maestro — not starting Claude session"
|
|
54
|
+
exit 0
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Check if claude CLI is available
|
|
58
|
+
if ! command -v claude &>/dev/null; then
|
|
59
|
+
# Try common paths
|
|
60
|
+
CLAUDE_PATH=""
|
|
61
|
+
for p in "$HOME/.local/bin/claude" "/opt/homebrew/bin/claude" "/usr/local/bin/claude"; do
|
|
62
|
+
if [ -x "$p" ]; then
|
|
63
|
+
CLAUDE_PATH="$p"
|
|
64
|
+
break
|
|
65
|
+
fi
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
if [ -z "$CLAUDE_PATH" ]; then
|
|
69
|
+
log "ERROR: claude CLI not found"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
else
|
|
73
|
+
CLAUDE_PATH=$(which claude)
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
log "Starting Claude Code session in $AGENT_DIR (claude: $CLAUDE_PATH)"
|
|
77
|
+
|
|
78
|
+
# Open Terminal.app with Claude Code running in the agent directory
|
|
79
|
+
osascript <<APPLESCRIPT
|
|
80
|
+
tell application "Terminal"
|
|
81
|
+
activate
|
|
82
|
+
-- Open a new window with claude running in the agent directory
|
|
83
|
+
do script "cd '$AGENT_DIR' && clear && echo '╔══════════════════════════════════════════════════════════╗' && echo '║ Sophie AI — Boot Session ($(date +%Y-%m-%d)) ║' && echo '╠══════════════════════════════════════════════════════════╣' && echo '║ Agent dir: $AGENT_DIR' && echo '║ Claude: $CLAUDE_PATH' && echo '╚══════════════════════════════════════════════════════════╝' && echo '' && '$CLAUDE_PATH'"
|
|
84
|
+
-- Set the window title
|
|
85
|
+
set custom title of front window to "$AGENT_NAME — Claude Code"
|
|
86
|
+
end tell
|
|
87
|
+
APPLESCRIPT
|
|
88
|
+
|
|
89
|
+
log "Terminal window opened with Claude Code session"
|
|
@@ -70,6 +70,32 @@ configure_auto_login() {
|
|
|
70
70
|
defaults write com.apple.loginwindow LoginwindowLaunchesRelaunchApps -bool false
|
|
71
71
|
|
|
72
72
|
ok "Auto-login enabled for $SUDO_USER"
|
|
73
|
+
|
|
74
|
+
# --- Disable all password gates that could block unattended operation -------
|
|
75
|
+
local real_home
|
|
76
|
+
real_home=$(eval echo "~$SUDO_USER")
|
|
77
|
+
|
|
78
|
+
# Disable "Require password after sleep or screen saver"
|
|
79
|
+
sudo -u "$SUDO_USER" defaults write com.apple.screensaver askForPassword -int 0
|
|
80
|
+
sudo -u "$SUDO_USER" defaults write com.apple.screensaver askForPasswordDelay -int 0
|
|
81
|
+
ok "Screen saver password prompt disabled"
|
|
82
|
+
|
|
83
|
+
# Disable screen lock via sysadminctl
|
|
84
|
+
sysadminctl -screenLock off 2>/dev/null || true
|
|
85
|
+
ok "Screen lock disabled"
|
|
86
|
+
|
|
87
|
+
# Disable idle logout (Privacy & Security > Log out when idle)
|
|
88
|
+
defaults write /Library/Preferences/.GlobalPreferences com.apple.autologout.AutoLogOutDelay -int 0
|
|
89
|
+
ok "Idle auto-logout disabled"
|
|
90
|
+
|
|
91
|
+
# Disable screen lock on wake for current user
|
|
92
|
+
sudo -u "$SUDO_USER" defaults -currentHost write com.apple.screensaver idleTime -int 0
|
|
93
|
+
ok "Screen saver idle timer set to never"
|
|
94
|
+
|
|
95
|
+
# Prevent display from sleeping and requiring login on wake
|
|
96
|
+
# (already handled by pmset displaysleep 0, but belt-and-suspenders)
|
|
97
|
+
defaults write /Library/Preferences/com.apple.loginwindow DisableScreenLock -bool true 2>/dev/null || true
|
|
98
|
+
|
|
73
99
|
warn "NOTE: FileVault must be disabled for auto-login to work"
|
|
74
100
|
warn "Check: fdesetup status"
|
|
75
101
|
|
|
@@ -304,6 +330,65 @@ configure_app_launches() {
|
|
|
304
330
|
chown "$real_user:staff" "$d" 2>/dev/null || true
|
|
305
331
|
done
|
|
306
332
|
ok "Log and state directories verified (owned by $real_user)"
|
|
333
|
+
|
|
334
|
+
# --- Claude Code boot session (opens Terminal with interactive claude) ------
|
|
335
|
+
local BOOT_SCRIPT="$AGENT_DIR/scripts/setup/boot-claude-session.sh"
|
|
336
|
+
if [ -f "$BOOT_SCRIPT" ]; then
|
|
337
|
+
chmod +x "$BOOT_SCRIPT"
|
|
338
|
+
|
|
339
|
+
local PLIST_NAME="ai.maestro.boot-claude-session"
|
|
340
|
+
local PLIST_PATH="$real_home/Library/LaunchAgents/${PLIST_NAME}.plist"
|
|
341
|
+
local real_home
|
|
342
|
+
real_home=$(eval echo "~$real_user")
|
|
343
|
+
|
|
344
|
+
# Detect the agent working directory (prefer sophie-ai)
|
|
345
|
+
local boot_agent_dir="$HOME/sophie-ai"
|
|
346
|
+
[ -d "$boot_agent_dir" ] || boot_agent_dir="$AGENT_DIR"
|
|
347
|
+
|
|
348
|
+
cat > "$PLIST_PATH" << PLIST_EOF
|
|
349
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
350
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
351
|
+
<plist version="1.0">
|
|
352
|
+
<dict>
|
|
353
|
+
<key>Label</key>
|
|
354
|
+
<string>${PLIST_NAME}</string>
|
|
355
|
+
<key>ProgramArguments</key>
|
|
356
|
+
<array>
|
|
357
|
+
<string>/bin/bash</string>
|
|
358
|
+
<string>${BOOT_SCRIPT}</string>
|
|
359
|
+
<string>${boot_agent_dir}</string>
|
|
360
|
+
</array>
|
|
361
|
+
<key>RunAtLoad</key>
|
|
362
|
+
<true/>
|
|
363
|
+
<key>StandardOutPath</key>
|
|
364
|
+
<string>${AGENT_DIR}/logs/watchdog/boot-session-stdout.log</string>
|
|
365
|
+
<key>StandardErrorPath</key>
|
|
366
|
+
<string>${AGENT_DIR}/logs/watchdog/boot-session-stderr.log</string>
|
|
367
|
+
<key>EnvironmentVariables</key>
|
|
368
|
+
<dict>
|
|
369
|
+
<key>PATH</key>
|
|
370
|
+
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:${real_home}/.local/bin</string>
|
|
371
|
+
<key>HOME</key>
|
|
372
|
+
<string>${real_home}</string>
|
|
373
|
+
</dict>
|
|
374
|
+
</dict>
|
|
375
|
+
</plist>
|
|
376
|
+
PLIST_EOF
|
|
377
|
+
|
|
378
|
+
chown "$real_user:staff" "$PLIST_PATH" 2>/dev/null || true
|
|
379
|
+
|
|
380
|
+
# Load as the real user
|
|
381
|
+
if [ "$(id -u)" -eq 0 ]; then
|
|
382
|
+
su "$real_user" -c "launchctl unload '$PLIST_PATH' 2>/dev/null; launchctl load '$PLIST_PATH'" 2>/dev/null || true
|
|
383
|
+
else
|
|
384
|
+
launchctl unload "$PLIST_PATH" 2>/dev/null || true
|
|
385
|
+
launchctl load "$PLIST_PATH" 2>/dev/null || true
|
|
386
|
+
fi
|
|
387
|
+
|
|
388
|
+
ok "Claude Code boot session agent installed (opens Terminal + claude on login)"
|
|
389
|
+
else
|
|
390
|
+
warn "Boot session script not found at $BOOT_SCRIPT"
|
|
391
|
+
fi
|
|
307
392
|
}
|
|
308
393
|
|
|
309
394
|
# =============================================================================
|
|
@@ -30,6 +30,10 @@ MAESTRO_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
30
30
|
# The watchdog runs from maestro but protects the whole machine
|
|
31
31
|
AGENT_DIR="${AGENT_DIR:-}"
|
|
32
32
|
|
|
33
|
+
# --- Ensure system paths are available ----------------------------------------
|
|
34
|
+
# launchd PATH may not include /usr/sbin where sysctl lives
|
|
35
|
+
export PATH="/usr/sbin:/usr/bin:/bin:/usr/local/bin:/opt/homebrew/bin:$PATH"
|
|
36
|
+
|
|
33
37
|
# --- Configuration -----------------------------------------------------------
|
|
34
38
|
|
|
35
39
|
# Total physical RAM in KB
|