agent-relay 2.1.6 → 2.1.8

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 (76) hide show
  1. package/README.md +9 -1
  2. package/dist/index.cjs +109 -23
  3. package/dist/src/cli/commands/doctor.d.ts.map +1 -1
  4. package/dist/src/cli/commands/doctor.js +32 -7
  5. package/dist/src/cli/commands/doctor.js.map +1 -1
  6. package/dist/src/cli/index.d.ts.map +1 -1
  7. package/dist/src/cli/index.js +260 -27
  8. package/dist/src/cli/index.js.map +1 -1
  9. package/install.sh +627 -35
  10. package/package.json +18 -18
  11. package/packages/api-types/package.json +1 -1
  12. package/packages/benchmark/package.json +4 -4
  13. package/packages/bridge/dist/spawner.d.ts.map +1 -1
  14. package/packages/bridge/dist/spawner.js +3 -0
  15. package/packages/bridge/dist/spawner.js.map +1 -1
  16. package/packages/bridge/dist/types.d.ts +2 -0
  17. package/packages/bridge/dist/types.d.ts.map +1 -1
  18. package/packages/bridge/package.json +8 -8
  19. package/packages/bridge/src/spawner.ts +3 -0
  20. package/packages/bridge/src/types.ts +2 -0
  21. package/packages/cli-tester/package.json +1 -1
  22. package/packages/config/package.json +2 -2
  23. package/packages/continuity/package.json +2 -2
  24. package/packages/daemon/dist/connection.d.ts +2 -0
  25. package/packages/daemon/dist/connection.d.ts.map +1 -1
  26. package/packages/daemon/dist/connection.js +5 -0
  27. package/packages/daemon/dist/connection.js.map +1 -1
  28. package/packages/daemon/dist/router.d.ts +1 -0
  29. package/packages/daemon/dist/router.d.ts.map +1 -1
  30. package/packages/daemon/dist/router.js.map +1 -1
  31. package/packages/daemon/dist/server.d.ts.map +1 -1
  32. package/packages/daemon/dist/server.js +68 -12
  33. package/packages/daemon/dist/server.js.map +1 -1
  34. package/packages/daemon/package.json +12 -12
  35. package/packages/daemon/src/connection.ts +6 -0
  36. package/packages/daemon/src/router.ts +1 -0
  37. package/packages/daemon/src/server.ts +67 -12
  38. package/packages/hooks/package.json +4 -4
  39. package/packages/mcp/dist/bin.js +34 -3
  40. package/packages/mcp/dist/bin.js.map +1 -1
  41. package/packages/mcp/dist/install.d.ts.map +1 -1
  42. package/packages/mcp/dist/install.js +7 -8
  43. package/packages/mcp/dist/install.js.map +1 -1
  44. package/packages/mcp/package.json +4 -4
  45. package/packages/mcp/src/bin.ts +39 -3
  46. package/packages/mcp/src/install.ts +7 -8
  47. package/packages/memory/package.json +2 -2
  48. package/packages/policy/package.json +2 -2
  49. package/packages/protocol/dist/types.d.ts +8 -0
  50. package/packages/protocol/dist/types.d.ts.map +1 -1
  51. package/packages/protocol/package.json +1 -1
  52. package/packages/protocol/src/types.ts +8 -0
  53. package/packages/resiliency/package.json +1 -1
  54. package/packages/sdk/dist/client.d.ts +2 -0
  55. package/packages/sdk/dist/client.d.ts.map +1 -1
  56. package/packages/sdk/dist/client.js +1 -0
  57. package/packages/sdk/dist/client.js.map +1 -1
  58. package/packages/sdk/package.json +3 -3
  59. package/packages/sdk/src/client.ts +3 -0
  60. package/packages/spawner/package.json +1 -1
  61. package/packages/state/package.json +1 -1
  62. package/packages/storage/dist/sqlite-adapter.d.ts +1 -0
  63. package/packages/storage/dist/sqlite-adapter.d.ts.map +1 -1
  64. package/packages/storage/dist/sqlite-adapter.js +31 -3
  65. package/packages/storage/dist/sqlite-adapter.js.map +1 -1
  66. package/packages/storage/package.json +2 -2
  67. package/packages/storage/src/sqlite-adapter.ts +34 -6
  68. package/packages/telemetry/package.json +1 -1
  69. package/packages/trajectory/package.json +2 -2
  70. package/packages/user-directory/package.json +2 -2
  71. package/packages/utils/package.json +3 -3
  72. package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -1
  73. package/packages/wrapper/dist/relay-pty-orchestrator.js +12 -0
  74. package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -1
  75. package/packages/wrapper/package.json +6 -6
  76. package/packages/wrapper/src/relay-pty-orchestrator.ts +12 -0
package/install.sh CHANGED
@@ -2,9 +2,18 @@
2
2
  set -e
3
3
 
4
4
  # Agent Relay Installer
5
- # Usage: curl -fsSL https://raw.githubusercontent.com/khaliqgant/agent-relay/main/install.sh | bash
5
+ # Usage: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash
6
+ #
7
+ # Options (set as environment variables):
8
+ # AGENT_RELAY_VERSION - Specific version to install (default: latest)
9
+ # AGENT_RELAY_INSTALL_DIR - Installation directory (default: ~/.agent-relay)
10
+ # AGENT_RELAY_BIN_DIR - Binary directory (default: ~/.local/bin)
11
+ # AGENT_RELAY_NO_DASHBOARD - Skip dashboard installation (default: false)
12
+ # AGENT_RELAY_TELEMETRY_DISABLED - Disable anonymous install telemetry (default: false)
6
13
 
7
- REPO="khaliqgant/agent-relay"
14
+ REPO_RELAY="AgentWorkforce/relay"
15
+ REPO_DASHBOARD="AgentWorkforce/relay-dashboard"
16
+ VERSION="${AGENT_RELAY_VERSION:-latest}"
8
17
  INSTALL_DIR="${AGENT_RELAY_INSTALL_DIR:-$HOME/.agent-relay}"
9
18
  BIN_DIR="${AGENT_RELAY_BIN_DIR:-$HOME/.local/bin}"
10
19
 
@@ -13,65 +22,648 @@ RED='\033[0;31m'
13
22
  GREEN='\033[0;32m'
14
23
  YELLOW='\033[1;33m'
15
24
  BLUE='\033[0;34m'
25
+ CYAN='\033[0;36m'
26
+ BOLD='\033[1m'
16
27
  NC='\033[0m'
17
28
 
18
29
  info() { echo -e "${BLUE}[info]${NC} $1"; }
19
- success() { echo -e "${GREEN}[success]${NC} $1"; }
30
+ success() { echo -e "${GREEN}[]${NC} $1"; }
20
31
  warn() { echo -e "${YELLOW}[warn]${NC} $1"; }
21
- error() { echo -e "${RED}[error]${NC} $1"; exit 1; }
32
+ error() {
33
+ echo -e "${RED}[error]${NC} $1"
34
+ # Track failure if telemetry is initialized
35
+ if [ -n "$INSTALL_ID" ]; then
36
+ # Escape special characters for JSON (newlines, quotes, backslashes)
37
+ local escaped_error
38
+ escaped_error=$(printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g' | tr '\n' ' ')
39
+ track_event "install_failed" ", \"error\": \"$escaped_error\""
40
+ fi
41
+ exit 1
42
+ }
43
+ step() { echo -e "\n${CYAN}${BOLD}$1${NC}"; }
44
+
45
+ # Telemetry (respects AGENT_RELAY_TELEMETRY_DISABLED)
46
+ POSTHOG_API_KEY="phc_2uDu01GtnLABJpVkWw4ri1OgScLU90aEmXmDjufGdqr"
47
+ POSTHOG_HOST="https://us.i.posthog.com"
48
+ INSTALL_ID=""
49
+ INSTALL_METHOD=""
50
+
51
+ telemetry_enabled() {
52
+ # Respect opt-out
53
+ if [ "${AGENT_RELAY_TELEMETRY_DISABLED:-}" = "1" ] || [ "${AGENT_RELAY_TELEMETRY_DISABLED:-}" = "true" ]; then
54
+ return 1
55
+ fi
56
+ # Also check DO_NOT_TRACK (standard env var)
57
+ if [ "${DO_NOT_TRACK:-}" = "1" ]; then
58
+ return 1
59
+ fi
60
+ return 0
61
+ }
62
+
63
+ generate_install_id() {
64
+ # Generate a random ID for this install session
65
+ if command -v uuidgen &> /dev/null; then
66
+ INSTALL_ID=$(uuidgen | tr '[:upper:]' '[:lower:]')
67
+ elif [ -f /proc/sys/kernel/random/uuid ]; then
68
+ INSTALL_ID=$(cat /proc/sys/kernel/random/uuid)
69
+ else
70
+ # Fallback: use timestamp + random
71
+ INSTALL_ID="install-$(date +%s)-$RANDOM"
72
+ fi
73
+ }
74
+
75
+ track_event() {
76
+ if ! telemetry_enabled; then
77
+ return 0
78
+ fi
79
+
80
+ local event="$1"
81
+ local extra_props="${2:-}"
82
+
83
+ # Send async (don't block install)
84
+ (curl -sS --max-time 5 -X POST "${POSTHOG_HOST}/capture/" \
85
+ -H "Content-Type: application/json" \
86
+ -d "{
87
+ \"api_key\": \"${POSTHOG_API_KEY}\",
88
+ \"event\": \"${event}\",
89
+ \"distinct_id\": \"${INSTALL_ID}\",
90
+ \"properties\": {
91
+ \"platform\": \"${PLATFORM:-unknown}\",
92
+ \"version\": \"${VERSION:-unknown}\",
93
+ \"method\": \"${INSTALL_METHOD:-unknown}\",
94
+ \"os\": \"${OS:-unknown}\",
95
+ \"arch\": \"${ARCH:-unknown}\",
96
+ \"has_node\": \"${HAS_NODE:-false}\"${extra_props}
97
+ }
98
+ }" > /dev/null 2>&1 &) || true
99
+ }
100
+
101
+ # Detect OS and architecture
102
+ detect_platform() {
103
+ OS="$(uname -s)"
104
+ ARCH="$(uname -m)"
105
+
106
+ case "$OS" in
107
+ Linux*) OS="linux" ;;
108
+ Darwin*) OS="darwin" ;;
109
+ *) error "Unsupported OS: $OS" ;;
110
+ esac
111
+
112
+ case "$ARCH" in
113
+ x86_64|amd64) ARCH="x64" ;;
114
+ arm64|aarch64) ARCH="arm64" ;;
115
+ *) error "Unsupported architecture: $ARCH" ;;
116
+ esac
117
+
118
+ PLATFORM="${OS}-${ARCH}"
119
+ info "Detected platform: $PLATFORM"
120
+ }
121
+
122
+ # Get latest version from GitHub
123
+ get_latest_version() {
124
+ if [ "$VERSION" = "latest" ]; then
125
+ VERSION=$(curl -fsSL "https://api.github.com/repos/$REPO_RELAY/releases/latest" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
126
+ if [ -z "$VERSION" ]; then
127
+ error "Failed to fetch latest version"
128
+ fi
129
+ fi
130
+ # Remove 'v' prefix if present
131
+ VERSION="${VERSION#v}"
132
+ info "Installing version: $VERSION"
133
+ }
134
+
135
+ # Check if Node.js is available
136
+ check_node() {
137
+ if command -v node &> /dev/null; then
138
+ NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
139
+ if [ "$NODE_VERSION" -ge 18 ]; then
140
+ HAS_NODE=true
141
+ info "Node.js $(node -v) detected"
142
+ return 0
143
+ fi
144
+ fi
145
+ HAS_NODE=false
146
+ return 1
147
+ }
148
+
149
+ # Download relay-pty binary
150
+ download_relay_pty() {
151
+ step "Downloading relay-pty binary..."
152
+
153
+ local binary_name="relay-pty-${PLATFORM}"
154
+ local download_url="https://github.com/$REPO_RELAY/releases/download/v${VERSION}/${binary_name}"
155
+ local target_path="$INSTALL_DIR/bin/relay-pty"
156
+
157
+ mkdir -p "$INSTALL_DIR/bin"
158
+
159
+ # Try to download - curl -f will fail on 404
160
+ if curl -fsSL "$download_url" -o "$target_path" 2>/dev/null; then
161
+ chmod +x "$target_path"
162
+ # Verify binary works
163
+ if "$target_path" --help &>/dev/null; then
164
+ success "Downloaded relay-pty binary"
165
+ return 0
166
+ else
167
+ warn "relay-pty binary failed verification"
168
+ rm -f "$target_path"
169
+ return 1
170
+ fi
171
+ else
172
+ warn "No prebuilt relay-pty binary for $PLATFORM"
173
+ return 1
174
+ fi
175
+ }
176
+
177
+ # Download standalone dashboard-server binary
178
+ download_dashboard_binary() {
179
+ if [ "${AGENT_RELAY_NO_DASHBOARD}" = "true" ]; then
180
+ info "Skipping dashboard installation (AGENT_RELAY_NO_DASHBOARD=true)"
181
+ return 0
182
+ fi
183
+
184
+ step "Downloading dashboard-server binary..."
185
+
186
+ local binary_name="relay-dashboard-server-${PLATFORM}"
187
+ local compressed_url="https://github.com/$REPO_DASHBOARD/releases/latest/download/${binary_name}.gz"
188
+ local uncompressed_url="https://github.com/$REPO_DASHBOARD/releases/latest/download/${binary_name}"
189
+ local target_path="$BIN_DIR/relay-dashboard-server"
190
+ local temp_file="/tmp/dashboard-download-$$"
191
+
192
+ mkdir -p "$BIN_DIR"
193
+
194
+ # Setup cleanup trap for temp files
195
+ trap 'rm -f "${temp_file}.gz" "${temp_file}"' EXIT
196
+
197
+ # Try compressed binary first (faster download)
198
+ if has_command gunzip; then
199
+ info "Trying compressed dashboard binary..."
200
+
201
+ if curl -fsSL "$compressed_url" -o "${temp_file}.gz" 2>/dev/null; then
202
+ # Check if we got a valid gzip file
203
+ local is_gzip=false
204
+ if has_command file; then
205
+ file "${temp_file}.gz" 2>/dev/null | grep -q "gzip" && is_gzip=true
206
+ else
207
+ head -c 2 "${temp_file}.gz" 2>/dev/null | od -An -tx1 | grep -q "1f 8b" && is_gzip=true
208
+ fi
209
+
210
+ if [ "$is_gzip" = true ]; then
211
+ if gunzip -c "${temp_file}.gz" > "$target_path" 2>/dev/null; then
212
+ rm -f "${temp_file}.gz"
213
+ chmod +x "$target_path"
214
+
215
+ if "$target_path" --version &>/dev/null; then
216
+ success "Downloaded standalone dashboard-server binary"
217
+ trap - EXIT
218
+ return 0
219
+ else
220
+ warn "Dashboard binary failed verification, trying uncompressed..."
221
+ rm -f "$target_path"
222
+ fi
223
+ else
224
+ rm -f "${temp_file}.gz" "$target_path"
225
+ fi
226
+ else
227
+ rm -f "${temp_file}.gz"
228
+ fi
229
+ fi
230
+ fi
231
+
232
+ # Fall back to uncompressed binary
233
+ info "Trying uncompressed dashboard binary..."
234
+
235
+ if curl -fsSL "$uncompressed_url" -o "$target_path" 2>/dev/null; then
236
+ local file_size
237
+ file_size=$(stat -f%z "$target_path" 2>/dev/null || stat -c%s "$target_path" 2>/dev/null || echo "0")
238
+
239
+ if [ "$file_size" -gt 1000000 ]; then
240
+ chmod +x "$target_path"
241
+
242
+ if "$target_path" --version &>/dev/null; then
243
+ success "Downloaded standalone dashboard-server binary"
244
+ trap - EXIT
245
+ return 0
246
+ else
247
+ warn "Dashboard binary failed verification"
248
+ rm -f "$target_path"
249
+ fi
250
+ else
251
+ rm -f "$target_path"
252
+ fi
253
+ fi
254
+
255
+ trap - EXIT
256
+ info "No standalone dashboard binary available for $PLATFORM"
257
+ return 1
258
+ }
259
+
260
+ # Check if a command exists
261
+ has_command() {
262
+ command -v "$1" &> /dev/null
263
+ }
264
+
265
+ # Download with progress indicator
266
+ download_with_progress() {
267
+ local url="$1"
268
+ local output="$2"
269
+
270
+ if [ -t 1 ]; then
271
+ # TTY available - show progress bar
272
+ curl -fSL --progress-bar "$url" -o "$output"
273
+ else
274
+ # No TTY - silent download
275
+ curl -fsSL "$url" -o "$output"
276
+ fi
277
+ }
22
278
 
23
- check_requirements() {
24
- if ! command -v node &> /dev/null; then
25
- error "Node.js is required. Please install Node.js 20+ first."
279
+ # Download standalone agent-relay binary (no Node.js required)
280
+ download_standalone_binary() {
281
+ step "Checking for standalone binary..."
282
+
283
+ local binary_name="agent-relay-${PLATFORM}"
284
+ local compressed_url="https://github.com/$REPO_RELAY/releases/download/v${VERSION}/${binary_name}.gz"
285
+ local uncompressed_url="https://github.com/$REPO_RELAY/releases/download/v${VERSION}/${binary_name}"
286
+ local target_path="$BIN_DIR/agent-relay"
287
+ local temp_file="/tmp/agent-relay-download-$$"
288
+
289
+ mkdir -p "$BIN_DIR"
290
+
291
+ # Setup cleanup trap for temp files
292
+ trap 'rm -f "${temp_file}.gz" "${temp_file}"' EXIT
293
+
294
+ # Try compressed binary first (faster download, ~60-70% smaller)
295
+ # Only if gunzip is available
296
+ if has_command gunzip; then
297
+ info "Downloading compressed binary (~25MB instead of ~70MB)..."
298
+
299
+ if curl -fsSL "$compressed_url" -o "${temp_file}.gz" 2>/dev/null; then
300
+ # Check if we got a valid gzip file (not an error page)
301
+ # Use file command if available, otherwise check magic bytes
302
+ local is_gzip=false
303
+ if has_command file; then
304
+ file "${temp_file}.gz" 2>/dev/null | grep -q "gzip" && is_gzip=true
305
+ else
306
+ # Check gzip magic bytes (1f 8b)
307
+ head -c 2 "${temp_file}.gz" 2>/dev/null | od -An -tx1 | grep -q "1f 8b" && is_gzip=true
308
+ fi
309
+
310
+ if [ "$is_gzip" = true ]; then
311
+ # Decompress
312
+ if gunzip -c "${temp_file}.gz" > "$target_path" 2>/dev/null; then
313
+ rm -f "${temp_file}.gz"
314
+ chmod +x "$target_path"
315
+
316
+ # Verify the binary works
317
+ if "$target_path" --version &>/dev/null; then
318
+ success "Downloaded standalone agent-relay binary (no Node.js required!)"
319
+ trap - EXIT # Clear trap
320
+ return 0
321
+ else
322
+ warn "Downloaded binary failed verification, trying uncompressed..."
323
+ rm -f "$target_path"
324
+ fi
325
+ else
326
+ warn "Decompression failed, trying uncompressed binary..."
327
+ rm -f "${temp_file}.gz" "$target_path"
328
+ fi
329
+ else
330
+ info "Compressed binary not available, trying uncompressed..."
331
+ rm -f "${temp_file}.gz"
332
+ fi
333
+ else
334
+ info "Compressed binary not available, trying uncompressed..."
335
+ rm -f "${temp_file}.gz"
336
+ fi
337
+ else
338
+ info "gunzip not available, trying uncompressed binary..."
339
+ fi
340
+
341
+ # Fall back to uncompressed binary
342
+ info "Downloading standalone binary..."
343
+
344
+ if curl -fsSL "$uncompressed_url" -o "$target_path" 2>/dev/null; then
345
+ # Check file size - error pages are typically small (<1MB)
346
+ local file_size
347
+ file_size=$(stat -f%z "$target_path" 2>/dev/null || stat -c%s "$target_path" 2>/dev/null || echo "0")
348
+
349
+ if [ "$file_size" -gt 1000000 ]; then
350
+ chmod +x "$target_path"
351
+
352
+ # Verify the binary works
353
+ if "$target_path" --version &>/dev/null; then
354
+ success "Downloaded standalone agent-relay binary (no Node.js required!)"
355
+ trap - EXIT # Clear trap
356
+ return 0
357
+ else
358
+ warn "Downloaded binary failed verification"
359
+ rm -f "$target_path"
360
+ fi
361
+ else
362
+ info "Uncompressed binary not available (file too small: ${file_size} bytes)"
363
+ rm -f "$target_path"
364
+ fi
365
+ fi
366
+
367
+ trap - EXIT # Clear trap
368
+ info "No standalone binary available for $PLATFORM, falling back to npm"
369
+ return 1
370
+ }
371
+
372
+ # Install via npm (fallback or primary method)
373
+ install_via_npm() {
374
+ step "Installing via npm..."
375
+
376
+ if ! check_node; then
377
+ error "Node.js 18+ is required for npm installation. Please install Node.js first:
378
+
379
+ macOS: brew install node
380
+ Linux: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs
381
+
382
+ Or use nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash"
26
383
  fi
27
384
 
28
- NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
29
- if [ "$NODE_VERSION" -lt 20 ]; then
30
- error "Node.js 20+ required. Found: $(node -v)"
385
+ # Install agent-relay globally
386
+ info "Installing agent-relay..."
387
+
388
+ # Try installation - capture output and exit code separately
389
+ local npm_log="/tmp/npm-install-$$.log"
390
+ local npm_exit=0
391
+
392
+ npm install -g agent-relay@"$VERSION" > "$npm_log" 2>&1 || npm_exit=$?
393
+
394
+ if [ $npm_exit -ne 0 ]; then
395
+ # First attempt failed, try without version
396
+ npm install -g agent-relay >> "$npm_log" 2>&1 || npm_exit=$?
31
397
  fi
32
- info "Node.js $(node -v) detected"
398
+
399
+ if [ $npm_exit -ne 0 ]; then
400
+ # Show the error output
401
+ cat "$npm_log"
402
+
403
+ # Check if it's a native module compilation failure
404
+ if grep -q "Unable to detect compiler type\|node-gyp\|prebuild-install\|gyp ERR" "$npm_log" 2>/dev/null; then
405
+ warn "Native module compilation failed. This is usually due to missing build tools."
406
+ echo ""
407
+ echo "Please install build tools and try again:"
408
+ echo ""
409
+ if [ "$OS" = "darwin" ]; then
410
+ echo " xcode-select --install"
411
+ elif command -v apt-get &> /dev/null; then
412
+ echo " sudo apt-get install build-essential python3"
413
+ elif command -v dnf &> /dev/null; then
414
+ echo " sudo dnf install gcc gcc-c++ make python3"
415
+ elif command -v apk &> /dev/null; then
416
+ echo " apk add build-base python3"
417
+ else
418
+ echo " Install gcc, g++, make, and python3"
419
+ fi
420
+ echo ""
421
+ echo "Retrying installation with optional native modules disabled..."
422
+ if npm install -g --ignore-scripts agent-relay@"$VERSION" 2>/dev/null || npm install -g --ignore-scripts agent-relay 2>/dev/null; then
423
+ warn "Installed with native module compilation skipped"
424
+ rm -f "$npm_log"
425
+ else
426
+ rm -f "$npm_log"
427
+ error "Installation failed. Please install build tools and try again."
428
+ fi
429
+ else
430
+ rm -f "$npm_log"
431
+ error "npm installation failed. Please check the error messages above."
432
+ fi
433
+ else
434
+ rm -f "$npm_log"
435
+ fi
436
+
437
+ # Install dashboard if not skipped
438
+ if [ "${AGENT_RELAY_NO_DASHBOARD}" != "true" ]; then
439
+ # Try binary first, fall back to npm
440
+ if ! download_dashboard_binary; then
441
+ info "Installing dashboard via npm..."
442
+ npm install -g @agent-relay/dashboard-server 2>/dev/null || true
443
+ fi
444
+ fi
445
+
446
+ success "Installed via npm"
33
447
  }
34
448
 
35
- install_source() {
36
- info "Installing from source..."
37
- mkdir -p "$INSTALL_DIR" "$BIN_DIR"
449
+ # Install from source (for development or when npm fails)
450
+ install_from_source() {
451
+ step "Installing from source..."
452
+
453
+ if ! check_node; then
454
+ error "Node.js 18+ is required for source installation"
455
+ fi
456
+
457
+ mkdir -p "$INSTALL_DIR"
38
458
 
39
459
  if command -v git &> /dev/null; then
40
- [ -d "$INSTALL_DIR/.git" ] && cd "$INSTALL_DIR" && git pull || git clone "https://github.com/$REPO.git" "$INSTALL_DIR"
460
+ if [ -d "$INSTALL_DIR/.git" ]; then
461
+ info "Updating existing installation..."
462
+ cd "$INSTALL_DIR" && git fetch && git checkout "v$VERSION" 2>/dev/null || git pull
463
+ else
464
+ info "Cloning repository..."
465
+ rm -rf "$INSTALL_DIR"
466
+ git clone --depth 1 --branch "v$VERSION" "https://github.com/$REPO_RELAY.git" "$INSTALL_DIR" 2>/dev/null || \
467
+ git clone --depth 1 "https://github.com/$REPO_RELAY.git" "$INSTALL_DIR"
468
+ fi
469
+ else
470
+ info "Downloading source tarball..."
471
+ curl -fsSL "https://github.com/$REPO_RELAY/archive/v$VERSION.tar.gz" -o /tmp/relay.tar.gz 2>/dev/null || \
472
+ curl -fsSL "https://github.com/$REPO_RELAY/archive/main.tar.gz" -o /tmp/relay.tar.gz
473
+ rm -rf "$INSTALL_DIR"
474
+ mkdir -p "$INSTALL_DIR"
475
+ tar -xzf /tmp/relay.tar.gz -C "$INSTALL_DIR" --strip-components=1
476
+ rm /tmp/relay.tar.gz
477
+ fi
478
+
479
+ cd "$INSTALL_DIR"
480
+
481
+ # Install dependencies and build
482
+ info "Installing dependencies..."
483
+ if command -v pnpm &> /dev/null; then
484
+ pnpm install --frozen-lockfile 2>/dev/null || pnpm install
41
485
  else
42
- curl -fsSL "https://github.com/$REPO/archive/main.tar.gz" | tar -xz -C "$INSTALL_DIR" --strip-components=1
486
+ npm ci 2>/dev/null || npm install
43
487
  fi
44
488
 
45
- cd "$INSTALL_DIR" && npm ci && npm rebuild better-sqlite3 && npm run build
489
+ info "Building..."
490
+ npm run build
46
491
 
47
- # Remove any existing symlink or file (old installs used symlinks which cause issues)
492
+ # Create wrapper script
493
+ mkdir -p "$BIN_DIR"
48
494
  rm -f "$BIN_DIR/agent-relay"
49
495
 
50
- # Create wrapper script that runs from install dir (for node_modules resolution)
51
496
  cat > "$BIN_DIR/agent-relay" << WRAPPER
52
497
  #!/usr/bin/env bash
53
- cd "$INSTALL_DIR" && exec node dist/cli/index.js "\$@"
498
+ cd "$INSTALL_DIR" && exec node dist/src/cli/index.js "\$@"
54
499
  WRAPPER
55
500
  chmod +x "$BIN_DIR/agent-relay"
56
501
 
57
- [[ ":$PATH:" != *":$BIN_DIR:"* ]] && warn "Add to PATH: export PATH=\"\$PATH:$BIN_DIR\""
58
- success "Installed to $INSTALL_DIR"
502
+ success "Installed from source"
503
+ }
504
+
505
+ # Setup PATH
506
+ setup_path() {
507
+ if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
508
+ warn "Add to your PATH by running:"
509
+ echo ""
510
+ echo " export PATH=\"\$PATH:$BIN_DIR\""
511
+ echo ""
512
+ echo " # Or add to your shell profile:"
513
+ echo " echo 'export PATH=\"\$PATH:$BIN_DIR\"' >> ~/.bashrc # for bash"
514
+ echo " echo 'export PATH=\"\$PATH:$BIN_DIR\"' >> ~/.zshrc # for zsh"
515
+ echo ""
516
+ fi
517
+ }
518
+
519
+ # Verify installation
520
+ verify_installation() {
521
+ step "Verifying installation..."
522
+
523
+ # Check if agent-relay is available
524
+ if command -v agent-relay &> /dev/null; then
525
+ local installed_version=$(agent-relay --version 2>/dev/null || echo "unknown")
526
+ success "agent-relay $installed_version installed successfully!"
527
+ elif [ -x "$BIN_DIR/agent-relay" ]; then
528
+ local installed_version=$("$BIN_DIR/agent-relay" --version 2>/dev/null || echo "unknown")
529
+ success "agent-relay $installed_version installed to $BIN_DIR"
530
+ setup_path
531
+ else
532
+ error "Installation verification failed"
533
+ fi
59
534
  }
60
535
 
536
+ # Print usage instructions
537
+ print_usage() {
538
+ echo ""
539
+ echo -e "${BOLD}Quick Start:${NC}"
540
+ echo ""
541
+ echo " # Start the daemon with dashboard"
542
+ echo " agent-relay up --dashboard"
543
+ echo ""
544
+ echo " # Check status"
545
+ echo " agent-relay status"
546
+ echo ""
547
+ echo " # Open dashboard"
548
+ echo " open http://localhost:3888"
549
+ echo ""
550
+ echo " # Stop daemon"
551
+ echo " agent-relay down"
552
+ echo ""
553
+ echo -e "${BOLD}Documentation:${NC} https://github.com/AgentWorkforce/relay"
554
+ echo ""
555
+ }
556
+
557
+ # Main installation flow
61
558
  main() {
62
- echo -e "\n${YELLOW}⚡ Agent Relay${NC} Installer\n"
63
- check_requirements
64
- install_source
65
- echo -e "\nQuick Start:"
66
- echo -e " # Start the daemon"
67
- echo -e " agent-relay start -f"
68
- echo -e ""
69
- echo -e " # Wrap an agent (tmux mode is default)"
70
- echo -e " agent-relay wrap -n MyAgent \"claude\""
71
- echo -e ""
72
- echo -e " # Open the dashboard"
73
- echo -e " agent-relay dashboard"
74
- echo -e ""
559
+ echo ""
560
+ echo -e "${YELLOW}${BOLD}⚡ Agent Relay${NC} Installer"
561
+ echo ""
562
+
563
+ # Initialize telemetry
564
+ generate_install_id
565
+
566
+ detect_platform
567
+ get_latest_version
568
+
569
+ # Track install started
570
+ track_event "install_started"
571
+
572
+ # Try installation methods in order of preference:
573
+ # 1. Standalone binary (no dependencies required!)
574
+ # 2. npm (if Node.js available)
575
+ # 3. source (fallback)
576
+
577
+ # Try standalone binary first - works without Node.js
578
+ if download_standalone_binary; then
579
+ INSTALL_METHOD="binary"
580
+ # Also download relay-pty binary if available
581
+ download_relay_pty || true
582
+ # Download dashboard-server binary if available
583
+ download_dashboard_binary || true
584
+ verify_installation && print_usage && track_event "install_completed" && exit 0
585
+ fi
586
+
587
+ # Fall back to npm if Node.js is available
588
+ if check_node; then
589
+ INSTALL_METHOD="npm"
590
+ install_via_npm && verify_installation && print_usage && track_event "install_completed" && exit 0
591
+ warn "npm installation failed, trying source..."
592
+ INSTALL_METHOD="source"
593
+ install_from_source && verify_installation && print_usage && track_event "install_completed" && exit 0
594
+ else
595
+ echo ""
596
+ warn "No standalone binary available and Node.js not found."
597
+ echo ""
598
+ echo -e "${BOLD}Options:${NC}"
599
+ echo ""
600
+ echo " 1. Wait for standalone binaries (coming soon for your platform)"
601
+ echo ""
602
+ echo " 2. Install Node.js 18+ using one of these methods:"
603
+ echo ""
604
+ echo " # Using nvm (recommended - works on macOS and Linux)"
605
+ echo " curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash"
606
+ echo " source ~/.bashrc # or ~/.zshrc"
607
+ echo " nvm install 20"
608
+ echo ""
609
+
610
+ if [ "$OS" = "darwin" ]; then
611
+ echo " # macOS - Official installer"
612
+ echo " https://nodejs.org/en/download"
613
+ echo ""
614
+ echo " # macOS - via Homebrew (if installed)"
615
+ echo " brew install node"
616
+ elif [ "$OS" = "linux" ]; then
617
+ # Detect package manager
618
+ if command -v apt-get &> /dev/null; then
619
+ echo " # Ubuntu/Debian"
620
+ echo " curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -"
621
+ echo " sudo apt-get install -y nodejs"
622
+ elif command -v dnf &> /dev/null; then
623
+ echo " # Fedora/RHEL"
624
+ echo " sudo dnf install nodejs npm"
625
+ elif command -v pacman &> /dev/null; then
626
+ echo " # Arch Linux"
627
+ echo " sudo pacman -S nodejs npm"
628
+ elif command -v apk &> /dev/null; then
629
+ echo " # Alpine Linux"
630
+ echo " apk add nodejs npm"
631
+ else
632
+ echo " # Download from nodejs.org"
633
+ echo " https://nodejs.org/en/download"
634
+ fi
635
+ fi
636
+
637
+ echo ""
638
+ echo "Then re-run this installer."
639
+ track_event "install_failed" ", \"error\": \"no_nodejs_or_binary\""
640
+ exit 1
641
+ fi
75
642
  }
76
643
 
644
+ # Handle command line arguments
645
+ case "${1:-}" in
646
+ --help|-h)
647
+ echo "Agent Relay Installer"
648
+ echo ""
649
+ echo "Usage: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash"
650
+ echo ""
651
+ echo "Environment variables:"
652
+ echo " AGENT_RELAY_VERSION Specific version to install (default: latest)"
653
+ echo " AGENT_RELAY_INSTALL_DIR Installation directory (default: ~/.agent-relay)"
654
+ echo " AGENT_RELAY_BIN_DIR Binary directory (default: ~/.local/bin)"
655
+ echo " AGENT_RELAY_NO_DASHBOARD Skip dashboard installation (default: false)"
656
+ echo " AGENT_RELAY_TELEMETRY_DISABLED Disable anonymous install telemetry (default: false)"
657
+ echo ""
658
+ echo "Telemetry: This installer collects anonymous usage data to improve the product."
659
+ echo " Set AGENT_RELAY_TELEMETRY_DISABLED=1 or DO_NOT_TRACK=1 to opt out."
660
+ exit 0
661
+ ;;
662
+ --version|-v)
663
+ echo "Installer for Agent Relay"
664
+ echo "Repository: https://github.com/AgentWorkforce/relay"
665
+ exit 0
666
+ ;;
667
+ esac
668
+
77
669
  main "$@"