@conversionpros/aiva 1.0.1 → 2.0.0

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.
Files changed (149) hide show
  1. package/bin/aiva.js +26 -14
  2. package/lib/bluebubbles.js +145 -0
  3. package/lib/config-gen.js +253 -0
  4. package/lib/constants.js +72 -0
  5. package/lib/launch-agent.js +112 -0
  6. package/lib/prerequisites.js +236 -0
  7. package/lib/process.js +59 -145
  8. package/lib/setup.js +224 -194
  9. package/lib/validate.js +194 -0
  10. package/package.json +7 -32
  11. package/auto-deploy.js +0 -190
  12. package/cli-sync.js +0 -126
  13. package/d2a-prompt-template.txt +0 -106
  14. package/diagnostics-api.js +0 -304
  15. package/docs/ara-dedup-fix-scope.md +0 -112
  16. package/docs/ara-fix-round2-scope.md +0 -61
  17. package/docs/ara-greeting-fix-scope.md +0 -70
  18. package/docs/calendar-date-fix-scope.md +0 -28
  19. package/docs/getting-started.md +0 -115
  20. package/docs/network-architecture-rollout-scope.md +0 -43
  21. package/docs/scope-google-oauth-integration.md +0 -351
  22. package/docs/settings-page-scope.md +0 -50
  23. package/docs/xai-imagine-scope.md +0 -116
  24. package/docs/xai-voice-integration-scope.md +0 -115
  25. package/docs/xai-voice-tools-scope.md +0 -165
  26. package/email-router.js +0 -512
  27. package/follow-up-handler.js +0 -606
  28. package/gateway-monitor.js +0 -158
  29. package/google-email.js +0 -379
  30. package/google-oauth.js +0 -310
  31. package/grok-imagine.js +0 -97
  32. package/health-reporter.js +0 -287
  33. package/invisible-prefix-base.txt +0 -206
  34. package/invisible-prefix-owner.txt +0 -26
  35. package/invisible-prefix-slim.txt +0 -10
  36. package/invisible-prefix.txt +0 -43
  37. package/knowledge-base.js +0 -472
  38. package/lib/cli.js +0 -19
  39. package/lib/server.js +0 -42
  40. package/meta-capi.js +0 -206
  41. package/meta-leads.js +0 -411
  42. package/notion-oauth.js +0 -323
  43. package/public/agent-config.html +0 -241
  44. package/public/aiva-avatar-anime.png +0 -0
  45. package/public/css/docs.css.bak +0 -688
  46. package/public/css/onboarding.css +0 -543
  47. package/public/diagrams/claude-subscription-pool.html +0 -329
  48. package/public/diagrams/claude-subscription-pool.png +0 -0
  49. package/public/docs-icon.png +0 -0
  50. package/public/escalation.html +0 -237
  51. package/public/group-config.html +0 -300
  52. package/public/icon-192.png +0 -0
  53. package/public/icon-512.png +0 -0
  54. package/public/icons/agents.svg +0 -1
  55. package/public/icons/attach.svg +0 -1
  56. package/public/icons/characters.svg +0 -1
  57. package/public/icons/chat.svg +0 -1
  58. package/public/icons/docs.svg +0 -1
  59. package/public/icons/heartbeat.svg +0 -1
  60. package/public/icons/messages.svg +0 -1
  61. package/public/icons/mic.svg +0 -1
  62. package/public/icons/notes.svg +0 -1
  63. package/public/icons/settings.svg +0 -1
  64. package/public/icons/tasks.svg +0 -1
  65. package/public/images/onboarding/p0-communication-layer.png +0 -0
  66. package/public/images/onboarding/p0-infinite-surface.png +0 -0
  67. package/public/images/onboarding/p0-learning-model.png +0 -0
  68. package/public/images/onboarding/p0-meet-aiva.png +0 -0
  69. package/public/images/onboarding/p4-contact-intelligence.png +0 -0
  70. package/public/images/onboarding/p4-context-compounds.png +0 -0
  71. package/public/images/onboarding/p4-message-router.png +0 -0
  72. package/public/images/onboarding/p4-per-contact-rules.png +0 -0
  73. package/public/images/onboarding/p4-send-messages.png +0 -0
  74. package/public/images/onboarding/p6-be-precise.png +0 -0
  75. package/public/images/onboarding/p6-review-escalations.png +0 -0
  76. package/public/images/onboarding/p6-voice-input.png +0 -0
  77. package/public/images/onboarding/p7-completion.png +0 -0
  78. package/public/index.html +0 -11594
  79. package/public/js/onboarding.js +0 -699
  80. package/public/manifest.json +0 -24
  81. package/public/messages-v2.html +0 -2824
  82. package/public/permission-approve.html.bak +0 -107
  83. package/public/permissions.html +0 -150
  84. package/public/styles/design-system.css +0 -68
  85. package/router-db.js +0 -604
  86. package/router-utils.js +0 -28
  87. package/router-v2/adapters/imessage.js +0 -191
  88. package/router-v2/adapters/quo.js +0 -82
  89. package/router-v2/adapters/whatsapp.js +0 -192
  90. package/router-v2/contact-manager.js +0 -234
  91. package/router-v2/conversation-engine.js +0 -498
  92. package/router-v2/data/knowledge-base.json +0 -176
  93. package/router-v2/data/router-v2.db +0 -0
  94. package/router-v2/data/router-v2.db-shm +0 -0
  95. package/router-v2/data/router-v2.db-wal +0 -0
  96. package/router-v2/data/router.db +0 -0
  97. package/router-v2/db.js +0 -457
  98. package/router-v2/escalation-bridge.js +0 -540
  99. package/router-v2/follow-up-engine.js +0 -347
  100. package/router-v2/index.js +0 -441
  101. package/router-v2/ingestion.js +0 -213
  102. package/router-v2/knowledge-base.js +0 -231
  103. package/router-v2/lead-qualifier.js +0 -152
  104. package/router-v2/learning-loop.js +0 -202
  105. package/router-v2/outbound-sender.js +0 -160
  106. package/router-v2/package.json +0 -13
  107. package/router-v2/permission-gate.js +0 -86
  108. package/router-v2/playbook.js +0 -177
  109. package/router-v2/prompts/base.js +0 -52
  110. package/router-v2/prompts/first-contact.js +0 -38
  111. package/router-v2/prompts/lead-qualification.js +0 -37
  112. package/router-v2/prompts/scheduling.js +0 -72
  113. package/router-v2/prompts/style-overrides.js +0 -22
  114. package/router-v2/scheduler.js +0 -301
  115. package/router-v2/scripts/migrate-v1-to-v2.js +0 -215
  116. package/router-v2/scripts/seed-faq.js +0 -67
  117. package/router-v2/seed-knowledge-base.js +0 -39
  118. package/router-v2/utils/ai.js +0 -129
  119. package/router-v2/utils/phone.js +0 -52
  120. package/router-v2/utils/response-validator.js +0 -98
  121. package/router-v2/utils/sanitize.js +0 -222
  122. package/router.js +0 -5005
  123. package/routes/google-calendar.js +0 -186
  124. package/scripts/deploy.sh +0 -62
  125. package/scripts/macos-calendar.sh +0 -232
  126. package/scripts/onboard-device.sh +0 -466
  127. package/server.js +0 -5131
  128. package/start.sh +0 -24
  129. package/templates/AGENTS.md +0 -548
  130. package/templates/IDENTITY.md +0 -15
  131. package/templates/docs-agents.html +0 -132
  132. package/templates/docs-app.html +0 -130
  133. package/templates/docs-home.html +0 -83
  134. package/templates/docs-imessage.html +0 -121
  135. package/templates/docs-tasks.html +0 -123
  136. package/templates/docs-tips.html +0 -175
  137. package/templates/getting-started.html +0 -809
  138. package/templates/invisible-prefix-base.txt +0 -171
  139. package/templates/invisible-prefix-owner.txt +0 -282
  140. package/templates/invisible-prefix.txt +0 -338
  141. package/templates/manifest.json +0 -61
  142. package/templates/memory-org/clients.md +0 -7
  143. package/templates/memory-org/credentials.md +0 -9
  144. package/templates/memory-org/devices.md +0 -7
  145. package/templates/updates.html +0 -464
  146. package/tts-proxy.js +0 -96
  147. package/voice-call-local.js +0 -731
  148. package/voice-call.js +0 -732
  149. package/wa-listener.js +0 -354
@@ -1,466 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ============================================================================
3
- # AIVA Device Onboarding Script
4
- # Fully provisions a fresh Mac Mini as an AIVA client device.
5
- # Idempotent — safe to run multiple times.
6
- #
7
- # Usage:
8
- # ./onboard-device.sh \
9
- # --client-name "Kurt Burgan" \
10
- # --device-id "kurt-mac-mini" \
11
- # --dashboard-url "http://100.x.x.x:3851" \
12
- # --tailscale-key "tskey-auth-xxx"
13
- #
14
- # Optional:
15
- # --webhook-secret "xxx" GitHub webhook secret for auto-deploy
16
- # --skip-tailscale Skip Tailscale join (already on tailnet)
17
- # --app-port 3847 AIVA app port (default: 3847)
18
- # --deploy-port 3849 Auto-deploy port (default: 3849)
19
- # ============================================================================
20
-
21
- set -euo pipefail
22
-
23
- # ── Colors & helpers ────────────────────────────────────────────────────────
24
- RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'
25
- CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
26
-
27
- step_num=0
28
- step_results=()
29
-
30
- log() { echo -e "${BLUE}[INFO]${NC} $*"; }
31
- ok() { echo -e "${GREEN}[ OK]${NC} $*"; step_results+=("✅ $*"); }
32
- warn() { echo -e "${YELLOW}[WARN]${NC} $*"; step_results+=("⚠️ $*"); }
33
- fail() { echo -e "${RED}[FAIL]${NC} $*"; step_results+=("❌ $*"); }
34
- die() { fail "$*"; print_summary; exit 1; }
35
-
36
- step() {
37
- step_num=$((step_num + 1))
38
- echo ""
39
- echo -e "${CYAN}${BOLD}━━━ Step ${step_num}: $* ━━━${NC}"
40
- }
41
-
42
- # ── Parse arguments ─────────────────────────────────────────────────────────
43
- CLIENT_NAME=""
44
- DEVICE_ID=""
45
- DASHBOARD_URL=""
46
- TAILSCALE_KEY=""
47
- WEBHOOK_SECRET=""
48
- SKIP_TAILSCALE=false
49
- APP_PORT=3847
50
- DEPLOY_PORT=3849
51
-
52
- while [[ $# -gt 0 ]]; do
53
- case "$1" in
54
- --client-name) CLIENT_NAME="$2"; shift 2 ;;
55
- --device-id) DEVICE_ID="$2"; shift 2 ;;
56
- --dashboard-url) DASHBOARD_URL="$2"; shift 2 ;;
57
- --tailscale-key) TAILSCALE_KEY="$2"; shift 2 ;;
58
- --webhook-secret) WEBHOOK_SECRET="$2"; shift 2 ;;
59
- --skip-tailscale) SKIP_TAILSCALE=true; shift ;;
60
- --app-port) APP_PORT="$2"; shift 2 ;;
61
- --deploy-port) DEPLOY_PORT="$2"; shift 2 ;;
62
- -h|--help)
63
- echo "Usage: $0 --client-name NAME --device-id ID --dashboard-url URL [--tailscale-key KEY] [--webhook-secret SECRET] [--skip-tailscale] [--app-port PORT] [--deploy-port PORT]"
64
- exit 0 ;;
65
- *) echo "Unknown option: $1"; exit 1 ;;
66
- esac
67
- done
68
-
69
- # Validate required args
70
- [[ -z "$CLIENT_NAME" ]] && die "Missing --client-name"
71
- [[ -z "$DEVICE_ID" ]] && die "Missing --device-id"
72
- [[ -z "$DASHBOARD_URL" ]] && die "Missing --dashboard-url"
73
-
74
- REPO_URL="git@github.com:mistermakeithappen/aiva-app.git"
75
- APP_DIR="$HOME/aiva-tasks"
76
- CURRENT_USER=$(whoami)
77
-
78
- echo ""
79
- echo -e "${BOLD}${CYAN}╔══════════════════════════════════════════════╗${NC}"
80
- echo -e "${BOLD}${CYAN}║ AIVA Device Onboarding ║${NC}"
81
- echo -e "${BOLD}${CYAN}╚══════════════════════════════════════════════╝${NC}"
82
- echo ""
83
- echo -e " Client: ${BOLD}${CLIENT_NAME}${NC}"
84
- echo -e " Device ID: ${BOLD}${DEVICE_ID}${NC}"
85
- echo -e " Dashboard: ${BOLD}${DASHBOARD_URL}${NC}"
86
- echo -e " User: ${BOLD}${CURRENT_USER}${NC}"
87
- echo -e " App Dir: ${BOLD}${APP_DIR}${NC}"
88
- echo ""
89
-
90
- # ── Step 1: Validate prerequisites ──────────────────────────────────────────
91
- step "Validate prerequisites"
92
-
93
- # macOS check
94
- if [[ "$(uname)" != "Darwin" ]]; then
95
- die "This script only runs on macOS. Detected: $(uname)"
96
- fi
97
- MACOS_VERSION=$(sw_vers -productVersion)
98
- log "macOS version: $MACOS_VERSION"
99
- ok "macOS $MACOS_VERSION detected"
100
-
101
- # Xcode CLI tools (needed for git)
102
- if ! xcode-select -p &>/dev/null; then
103
- log "Installing Xcode Command Line Tools..."
104
- xcode-select --install 2>/dev/null || true
105
- warn "Xcode CLI tools installing — you may need to accept the dialog and re-run this script"
106
- fi
107
-
108
- # Homebrew
109
- if ! command -v brew &>/dev/null; then
110
- log "Installing Homebrew..."
111
- /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
112
- # Add to path for Apple Silicon
113
- if [[ -f /opt/homebrew/bin/brew ]]; then
114
- eval "$(/opt/homebrew/bin/brew shellenv)"
115
- # Persist for future shells
116
- echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> "$HOME/.zprofile" 2>/dev/null || true
117
- fi
118
- ok "Homebrew installed"
119
- else
120
- ok "Homebrew present ($(brew --version | head -1))"
121
- fi
122
-
123
- # Git
124
- if ! command -v git &>/dev/null; then
125
- log "Installing git via Homebrew..."
126
- brew install git
127
- ok "Git installed"
128
- else
129
- ok "Git present ($(git --version))"
130
- fi
131
-
132
- # Node.js
133
- if ! command -v node &>/dev/null; then
134
- log "Installing Node.js via Homebrew..."
135
- brew install node
136
- ok "Node.js installed ($(node --version))"
137
- else
138
- NODE_VERSION=$(node --version)
139
- ok "Node.js present ($NODE_VERSION)"
140
- fi
141
-
142
- # npm
143
- if ! command -v npm &>/dev/null; then
144
- die "npm not found even though Node.js is installed"
145
- fi
146
- ok "npm present ($(npm --version))"
147
-
148
- # ── Step 2: Join Tailscale ───────────────────────────────────────────────────
149
- step "Join Tailscale network"
150
-
151
- if [[ "$SKIP_TAILSCALE" == "true" ]]; then
152
- log "Skipping Tailscale (--skip-tailscale flag)"
153
- ok "Tailscale skipped by request"
154
- elif [[ -z "$TAILSCALE_KEY" ]]; then
155
- warn "No --tailscale-key provided — skipping Tailscale join. Device must already be on tailnet."
156
- else
157
- if ! command -v tailscale &>/dev/null; then
158
- log "Tailscale CLI not found. Install Tailscale from https://tailscale.com/download/mac"
159
- warn "Tailscale not installed — install manually and re-run"
160
- else
161
- # Check if already connected
162
- TS_STATUS=$(tailscale status --json 2>/dev/null | grep -o '"BackendState":"[^"]*"' | cut -d'"' -f4 || echo "unknown")
163
- if [[ "$TS_STATUS" == "Running" ]]; then
164
- ok "Tailscale already connected"
165
- else
166
- log "Joining Tailscale with auth key..."
167
- sudo tailscale up --authkey="$TAILSCALE_KEY" --hostname="$DEVICE_ID"
168
- ok "Tailscale joined as $DEVICE_ID"
169
- fi
170
- fi
171
- fi
172
-
173
- # Get Tailscale IP
174
- TAILSCALE_IP=""
175
- if command -v tailscale &>/dev/null; then
176
- TAILSCALE_IP=$(tailscale ip -4 2>/dev/null || echo "")
177
- fi
178
- if [[ -z "$TAILSCALE_IP" ]]; then
179
- TAILSCALE_IP=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | head -1 | awk '{print $2}')
180
- warn "Could not get Tailscale IP — using local IP: $TAILSCALE_IP"
181
- else
182
- ok "Tailscale IP: $TAILSCALE_IP"
183
- fi
184
-
185
- # ── Step 3: Create directory structure ───────────────────────────────────────
186
- step "Create directory structure"
187
-
188
- mkdir -p "$APP_DIR"
189
- mkdir -p "$APP_DIR/data"
190
- ok "Directory structure ready: $APP_DIR"
191
-
192
- # ── Step 4: Clone or update repo ────────────────────────────────────────────
193
- step "Clone/update AIVA app repository"
194
-
195
- if [[ -d "$APP_DIR/.git" ]]; then
196
- log "Repository already exists — pulling latest..."
197
- cd "$APP_DIR"
198
- git fetch origin
199
- git reset --hard origin/main
200
- ok "Repository updated (git pull)"
201
- else
202
- # Check if directory has files (avoid clobbering)
203
- if [[ -n "$(ls -A "$APP_DIR" 2>/dev/null)" ]]; then
204
- log "Directory not empty but no git repo — backing up and cloning fresh"
205
- mv "$APP_DIR" "${APP_DIR}.bak.$(date +%s)"
206
- mkdir -p "$APP_DIR"
207
- fi
208
- log "Cloning repository..."
209
- git clone "$REPO_URL" "$APP_DIR"
210
- ok "Repository cloned"
211
- fi
212
-
213
- cd "$APP_DIR"
214
-
215
- # ── Step 5: Install dependencies ────────────────────────────────────────────
216
- step "Install Node.js dependencies"
217
-
218
- cd "$APP_DIR"
219
- npm install --production 2>&1 | tail -3
220
- ok "Dependencies installed"
221
-
222
- # ── Step 6: Configure environment ────────────────────────────────────────────
223
- step "Configure environment (.env)"
224
-
225
- ENV_FILE="$APP_DIR/.env"
226
-
227
- # Only create/update if needed — preserve existing keys
228
- if [[ -f "$ENV_FILE" ]]; then
229
- log "Existing .env found — merging configuration"
230
- # Helper: set a key in .env (update if exists, append if not)
231
- set_env() {
232
- local key="$1" val="$2"
233
- if grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then
234
- sed -i '' "s|^${key}=.*|${key}=${val}|" "$ENV_FILE"
235
- else
236
- echo "${key}=${val}" >> "$ENV_FILE"
237
- fi
238
- }
239
- else
240
- log "Creating new .env file"
241
- touch "$ENV_FILE"
242
- set_env() {
243
- echo "$1=$2" >> "$ENV_FILE"
244
- }
245
- fi
246
-
247
- set_env "DEVICE_ID" "$DEVICE_ID"
248
- set_env "CLIENT_NAME" "$CLIENT_NAME"
249
- set_env "DASHBOARD_URL" "$DASHBOARD_URL"
250
- set_env "APP_PORT" "$APP_PORT"
251
- set_env "AUTO_DEPLOY_PORT" "$DEPLOY_PORT"
252
-
253
- if [[ -n "$WEBHOOK_SECRET" ]]; then
254
- set_env "GITHUB_WEBHOOK_SECRET" "$WEBHOOK_SECRET"
255
- fi
256
-
257
- # Ensure CODING_ENABLED defaults to false for client devices
258
- if ! grep -q "^CODING_ENABLED=" "$ENV_FILE" 2>/dev/null; then
259
- set_env "CODING_ENABLED" "false"
260
- fi
261
-
262
- ok "Environment configured"
263
-
264
- # ── Step 7: Start AIVA app ──────────────────────────────────────────────────
265
- step "Start AIVA app service"
266
-
267
- PLIST_DIR="$HOME/Library/LaunchAgents"
268
- AIVA_PLIST="$PLIST_DIR/com.aiva.app.plist"
269
- DEPLOY_PLIST="$PLIST_DIR/com.aiva.auto-deploy.plist"
270
-
271
- # Prefer PM2 if available, otherwise LaunchAgent
272
- if command -v pm2 &>/dev/null; then
273
- log "PM2 detected — using PM2 for process management"
274
-
275
- # Stop existing if running
276
- pm2 delete aiva-app 2>/dev/null || true
277
- pm2 delete aiva-auto-deploy 2>/dev/null || true
278
-
279
- cd "$APP_DIR"
280
- pm2 start server.js --name aiva-app --cwd "$APP_DIR"
281
- pm2 start auto-deploy.js --name aiva-auto-deploy --cwd "$APP_DIR"
282
- pm2 save
283
-
284
- # Ensure PM2 starts on boot
285
- pm2 startup 2>/dev/null || true
286
-
287
- ok "AIVA app started via PM2"
288
- else
289
- log "PM2 not found — using macOS LaunchAgent"
290
- mkdir -p "$PLIST_DIR"
291
-
292
- # AIVA App LaunchAgent
293
- cat > "$AIVA_PLIST" << PLIST
294
- <?xml version="1.0" encoding="UTF-8"?>
295
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
296
- <plist version="1.0">
297
- <dict>
298
- <key>Label</key>
299
- <string>com.aiva.app</string>
300
- <key>ProgramArguments</key>
301
- <array>
302
- <string>$(which node)</string>
303
- <string>${APP_DIR}/server.js</string>
304
- </array>
305
- <key>WorkingDirectory</key>
306
- <string>${APP_DIR}</string>
307
- <key>EnvironmentVariables</key>
308
- <dict>
309
- <key>PATH</key>
310
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
311
- <key>HOME</key>
312
- <string>${HOME}</string>
313
- </dict>
314
- <key>RunAtLoad</key>
315
- <true/>
316
- <key>KeepAlive</key>
317
- <true/>
318
- <key>StandardOutPath</key>
319
- <string>${APP_DIR}/data/aiva-app.log</string>
320
- <key>StandardErrorPath</key>
321
- <string>${APP_DIR}/data/aiva-app-error.log</string>
322
- </dict>
323
- </plist>
324
- PLIST
325
-
326
- # Auto-Deploy LaunchAgent
327
- cat > "$DEPLOY_PLIST" << PLIST
328
- <?xml version="1.0" encoding="UTF-8"?>
329
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
330
- <plist version="1.0">
331
- <dict>
332
- <key>Label</key>
333
- <string>com.aiva.auto-deploy</string>
334
- <key>ProgramArguments</key>
335
- <array>
336
- <string>$(which node)</string>
337
- <string>${APP_DIR}/auto-deploy.js</string>
338
- </array>
339
- <key>WorkingDirectory</key>
340
- <string>${APP_DIR}</string>
341
- <key>EnvironmentVariables</key>
342
- <dict>
343
- <key>PATH</key>
344
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
345
- <key>HOME</key>
346
- <string>${HOME}</string>
347
- </dict>
348
- <key>RunAtLoad</key>
349
- <true/>
350
- <key>KeepAlive</key>
351
- <true/>
352
- <key>StandardOutPath</key>
353
- <string>${APP_DIR}/data/auto-deploy.log</string>
354
- <key>StandardErrorPath</key>
355
- <string>${APP_DIR}/data/auto-deploy-error.log</string>
356
- </dict>
357
- </plist>
358
- PLIST
359
-
360
- # Unload then load (idempotent)
361
- launchctl unload "$AIVA_PLIST" 2>/dev/null || true
362
- launchctl load "$AIVA_PLIST"
363
- launchctl unload "$DEPLOY_PLIST" 2>/dev/null || true
364
- launchctl load "$DEPLOY_PLIST"
365
-
366
- ok "AIVA app started via LaunchAgent"
367
- fi
368
-
369
- # ── Step 8: Disable sleep ───────────────────────────────────────────────────
370
- step "Configure power management (prevent sleep)"
371
-
372
- sudo pmset -a sleep 0 displaysleep 0 disksleep 0 2>/dev/null && \
373
- ok "Sleep disabled (pmset)" || \
374
- warn "Could not set pmset — may need sudo password"
375
-
376
- # ── Step 9: Register with dashboard ─────────────────────────────────────────
377
- step "Register with dashboard"
378
-
379
- # Wait a moment for the app to start
380
- sleep 3
381
-
382
- # Get macOS version and Node version for registration
383
- OS_VERSION=$(sw_vers -productVersion)
384
- NODE_VER=$(node --version)
385
- MAC_ADDR=$(ifconfig en0 2>/dev/null | grep ether | awk '{print $2}' || echo "unknown")
386
-
387
- REGISTER_BODY=$(cat << EOF
388
- {
389
- "deviceId": "${DEVICE_ID}",
390
- "clientName": "${CLIENT_NAME}",
391
- "tailscaleIp": "${TAILSCALE_IP}",
392
- "macAddress": "${MAC_ADDR}",
393
- "osVersion": "${OS_VERSION}",
394
- "nodeVersion": "${NODE_VER}",
395
- "appPath": "${APP_DIR}",
396
- "sshUser": "${CURRENT_USER}"
397
- }
398
- EOF
399
- )
400
-
401
- REGISTER_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
402
- "${DASHBOARD_URL}/api/devices/register" \
403
- -H "Content-Type: application/json" \
404
- -d "$REGISTER_BODY" 2>/dev/null || echo -e "\n000")
405
-
406
- HTTP_CODE=$(echo "$REGISTER_RESPONSE" | tail -1)
407
- RESPONSE_BODY=$(echo "$REGISTER_RESPONSE" | sed '$d')
408
-
409
- if [[ "$HTTP_CODE" == "200" || "$HTTP_CODE" == "201" ]]; then
410
- ok "Registered with dashboard (HTTP $HTTP_CODE)"
411
- log "Response: $RESPONSE_BODY"
412
- else
413
- warn "Dashboard registration returned HTTP $HTTP_CODE — device may need manual registration"
414
- [[ -n "$RESPONSE_BODY" ]] && log "Response: $RESPONSE_BODY"
415
- fi
416
-
417
- # ── Step 10: Self-test ───────────────────────────────────────────────────────
418
- step "Run self-test"
419
-
420
- sleep 2
421
-
422
- # Test AIVA app
423
- APP_CHECK=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${APP_PORT}" 2>/dev/null || echo "000")
424
- if [[ "$APP_CHECK" == "200" ]]; then
425
- ok "AIVA app responding on port $APP_PORT"
426
- else
427
- warn "AIVA app returned HTTP $APP_CHECK on port $APP_PORT (may still be starting)"
428
- fi
429
-
430
- # Test auto-deploy
431
- DEPLOY_CHECK=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${DEPLOY_PORT}" 2>/dev/null || echo "000")
432
- if [[ "$DEPLOY_CHECK" == "200" || "$DEPLOY_CHECK" == "404" ]]; then
433
- ok "Auto-deploy service responding on port $DEPLOY_PORT"
434
- else
435
- warn "Auto-deploy returned HTTP $DEPLOY_CHECK on port $DEPLOY_PORT"
436
- fi
437
-
438
- # Test git status
439
- cd "$APP_DIR"
440
- GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
441
- GIT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
442
- ok "Git: branch=$GIT_BRANCH commit=$GIT_HASH"
443
-
444
- # ── Summary ──────────────────────────────────────────────────────────────────
445
- print_summary() {
446
- echo ""
447
- echo -e "${BOLD}${CYAN}╔══════════════════════════════════════════════╗${NC}"
448
- echo -e "${BOLD}${CYAN}║ Onboarding Summary ║${NC}"
449
- echo -e "${BOLD}${CYAN}╚══════════════════════════════════════════════╝${NC}"
450
- echo ""
451
- for result in "${step_results[@]}"; do
452
- echo -e " $result"
453
- done
454
- echo ""
455
- echo -e " ${BOLD}Device ID:${NC} $DEVICE_ID"
456
- echo -e " ${BOLD}Client:${NC} $CLIENT_NAME"
457
- echo -e " ${BOLD}Tailscale IP:${NC} $TAILSCALE_IP"
458
- echo -e " ${BOLD}App URL:${NC} http://${TAILSCALE_IP}:${APP_PORT}"
459
- echo -e " ${BOLD}App Dir:${NC} $APP_DIR"
460
- echo -e " ${BOLD}Git:${NC} $GIT_BRANCH @ $GIT_HASH"
461
- echo ""
462
- echo -e " ${GREEN}${BOLD}Onboarding complete!${NC}"
463
- echo ""
464
- }
465
-
466
- print_summary