Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ SmartAgent
├── Everclaw (decentralized inference)
│ ├── Morpheus API Gateway (open access, cloud)
│ ├── Morpheus P2P Proxy (local, staked MOR)
│ ├── Always-On Proxy-Router (launchd KeepAlive, auto-restart)
│ ├── Gateway Guardian v4 (billing-aware self-healing watchdog)
│ └── Smart Session Archiver (prevents dashboard overload)
└── SmartAgent Config
Expand Down
1 change: 1 addition & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ <h2>Under the Hood</h2>
├── <span class="hl3">Everclaw</span> <span style="color: var(--text-muted);">(decentralized inference)</span>
│ ├── Morpheus API Gateway <span style="color: var(--text-muted);">— open access, cloud</span>
│ ├── Morpheus P2P Proxy <span style="color: var(--text-muted);">— local, staked MOR</span>
│ ├── Always-On Router <span style="color: var(--text-muted);">— launchd KeepAlive, auto-restart</span>
│ ├── Gateway Guardian v4 <span style="color: var(--text-muted);">— billing-aware self-healing watchdog</span>
│ └── Session Archiver <span style="color: var(--text-muted);">— prevents dashboard overload</span>
└── <span class="hl">SmartAgent Config</span>
Expand Down
50 changes: 50 additions & 0 deletions scripts/mor-launch-headless.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash
# mor-launch-headless.sh — launchd-compatible Morpheus proxy-router launcher
#
# Retrieves wallet private key from 1Password at runtime via macOS Keychain.
# Designed to run under launchd KeepAlive — runs in foreground via exec.
#
# If 1Password is not configured, falls back to macOS Keychain (everclaw-wallet).
#
# Usage: Called by com.morpheus.router launchd plist (not manually)

MORPHEUS_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$MORPHEUS_DIR"

# Source .env for ETH_NODE_ADDRESS and other config
if [[ -f .env ]]; then
set -a
source .env
set +a
fi

# --- Key retrieval: try 1Password first, then macOS Keychain ---
WALLET_KEY=""

# Method 1: 1Password service account
OP_TOKEN=$(security find-generic-password -a "bernardo-agent" -s "op-service-account-token" -w 2>/dev/null || true)
if [[ -n "$OP_TOKEN" ]]; then
export OP_SERVICE_ACCOUNT_TOKEN="$OP_TOKEN"
WALLET_KEY=$(op item get "Base Session Key" --vault "Bernardo Agent Vault" --fields "Private Key" --reveal 2>/dev/null || true)
fi

# Method 2: macOS Keychain (everclaw-wallet.mjs stores keys here)
if [[ -z "$WALLET_KEY" ]]; then
WALLET_KEY=$(security find-generic-password -s "everclaw-wallet" -w 2>/dev/null || true)
fi

if [[ -z "$WALLET_KEY" ]]; then
echo "$(date -u +%Y-%m-%dT%H:%M:%S) FATAL: Cannot retrieve wallet key from 1Password or Keychain" >&2
exit 1
fi

export WALLET_PRIVATE_KEY="$WALLET_KEY"
export ETH_NODE_ADDRESS="${ETH_NODE_ADDRESS:-https://base-mainnet.public.blastapi.io}"

# Ensure log directory exists
mkdir -p "$MORPHEUS_DIR/data/logs"

echo "$(date -u +%Y-%m-%dT%H:%M:%S) Starting proxy-router (headless, launchd-managed)"

# Run in foreground so launchd can track the process
exec ./proxy-router
40 changes: 40 additions & 0 deletions templates/com.morpheus.router.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?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>com.morpheus.router</string>

<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>__MORPHEUS_DIR__/mor-launch-headless.sh</string>
</array>

<key>WorkingDirectory</key>
<string>__MORPHEUS_DIR__</string>

<key>KeepAlive</key>
<true/>

<key>RunAtLoad</key>
<true/>

<key>ThrottleInterval</key>
<integer>30</integer>

<key>StandardOutPath</key>
<string>__MORPHEUS_DIR__/data/logs/router-stdout.log</string>

<key>StandardErrorPath</key>
<string>__MORPHEUS_DIR__/data/logs/router-stderr.log</string>

<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
<key>HOME</key>
<string>__HOME__</string>
</dict>
</dict>
</plist>
Loading