@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptic/maestro",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "Maestro — Autonomous AI agent operating system. Deploy AI employees on dedicated Mac minis.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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