get-claudia 1.10.0 → 1.10.2
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/bin/index.js +2 -2
- package/gateway/scripts/install.ps1 +222 -21
- package/gateway/scripts/install.sh +242 -21
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -309,8 +309,8 @@ ${colors.dim}She'll introduce herself and set things up for you.${colors.reset}
|
|
|
309
309
|
|
|
310
310
|
if (gatewayInstalled) {
|
|
311
311
|
console.log(`${colors.bold}Gateway:${colors.reset}
|
|
312
|
-
${colors.dim}
|
|
313
|
-
${colors.cyan}claudia-gateway start${colors.reset}
|
|
312
|
+
${colors.dim}If claudia-gateway isn't found, open a new terminal or run:${colors.reset}
|
|
313
|
+
${colors.cyan}~/.claudia/bin/claudia-gateway start${colors.reset}
|
|
314
314
|
${colors.dim}See ~/.claudia/gateway.json for settings.${colors.reset}
|
|
315
315
|
`);
|
|
316
316
|
}
|
|
@@ -230,11 +230,20 @@ node "%USERPROFILE%\.claudia\gateway\src\index.js" %*
|
|
|
230
230
|
Set-Content -Path $wrapperPath -Value $wrapperContent
|
|
231
231
|
Write-Host " ${GREEN}✓${NC} CLI installed at $wrapperPath"
|
|
232
232
|
|
|
233
|
-
# PATH
|
|
233
|
+
# Auto-add to user PATH if not already there
|
|
234
|
+
$PATH_ADDED = $false
|
|
234
235
|
$currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "User")
|
|
235
236
|
if ($currentPath -notlike "*$BIN_DIR*") {
|
|
236
|
-
|
|
237
|
-
|
|
237
|
+
try {
|
|
238
|
+
$newPath = if ($currentPath) { "$currentPath;$BIN_DIR" } else { $BIN_DIR }
|
|
239
|
+
[System.Environment]::SetEnvironmentVariable("PATH", $newPath, "User")
|
|
240
|
+
$env:PATH = "$BIN_DIR;$env:PATH"
|
|
241
|
+
Write-Host " ${GREEN}✓${NC} PATH updated (user environment)"
|
|
242
|
+
$PATH_ADDED = $true
|
|
243
|
+
} catch {
|
|
244
|
+
Write-Host " ${YELLOW}!${NC} Add to your PATH manually:"
|
|
245
|
+
Write-Host " ${DIM}[Environment]::SetEnvironmentVariable('PATH', `$env:PATH + ';$BIN_DIR', 'User')${NC}"
|
|
246
|
+
}
|
|
238
247
|
}
|
|
239
248
|
|
|
240
249
|
# Create scheduled task (disabled by default)
|
|
@@ -298,30 +307,218 @@ Write-Host " ║ ║"
|
|
|
298
307
|
Write-Host " ╚═══════════════════════════════════════════════════════════╝"
|
|
299
308
|
Write-Host "${NC}"
|
|
300
309
|
|
|
301
|
-
|
|
310
|
+
# Offer interactive setup guide
|
|
311
|
+
Write-Host " The gateway needs a chat platform (Telegram or Slack) to"
|
|
312
|
+
Write-Host " receive your messages. ${BOLD}Want a step-by-step setup guide?${NC}"
|
|
302
313
|
Write-Host ""
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
Write-Host "
|
|
314
|
+
$showGuide = Read-Host " Show setup guide? [y/n, default=y]"
|
|
315
|
+
if (-not $showGuide) { $showGuide = "y" }
|
|
316
|
+
|
|
317
|
+
if ($showGuide -match "^[Yy]") {
|
|
318
|
+
Write-Host ""
|
|
319
|
+
Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
320
|
+
Write-Host ""
|
|
321
|
+
Write-Host " ${BOLD}Which platform?${NC}"
|
|
322
|
+
Write-Host " ${CYAN}1)${NC} Telegram ${DIM}(easiest, 2 minutes)${NC}"
|
|
323
|
+
Write-Host " ${CYAN}2)${NC} Slack ${DIM}(requires workspace admin)${NC}"
|
|
324
|
+
Write-Host " ${CYAN}3)${NC} Skip ${DIM}(I'll set it up later)${NC}"
|
|
325
|
+
Write-Host ""
|
|
326
|
+
$platformChoice = Read-Host " Choice [1-3, default=1]"
|
|
327
|
+
if (-not $platformChoice) { $platformChoice = "1" }
|
|
328
|
+
|
|
329
|
+
if ($platformChoice -eq "1") {
|
|
330
|
+
Write-Host ""
|
|
331
|
+
Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
332
|
+
Write-Host ""
|
|
333
|
+
Write-Host " ${BOLD}Telegram Setup${NC}"
|
|
334
|
+
Write-Host ""
|
|
335
|
+
Write-Host " ${CYAN}Step 1:${NC} Open Telegram and search for ${BOLD}@BotFather${NC}"
|
|
336
|
+
Write-Host " (or open: ${DIM}https://t.me/BotFather${NC})"
|
|
337
|
+
Write-Host ""
|
|
338
|
+
Write-Host " ${CYAN}Step 2:${NC} Send ${BOLD}/newbot${NC} to BotFather"
|
|
339
|
+
Write-Host " He'll ask for a display name (anything, e.g. $([char]34)My Claudia$([char]34))"
|
|
340
|
+
Write-Host " Then a username (must end in 'bot', e.g. $([char]34)my_claudia_bot$([char]34))"
|
|
341
|
+
Write-Host ""
|
|
342
|
+
Write-Host " ${CYAN}Step 3:${NC} BotFather will reply with a token like:"
|
|
343
|
+
Write-Host " ${DIM}123456789:ABCdefGHIjklMNOpqrsTUVwxyz${NC}"
|
|
344
|
+
Write-Host " Copy that token."
|
|
345
|
+
Write-Host ""
|
|
346
|
+
$botToken = Read-Host " Paste your bot token here (or press Enter to skip)"
|
|
347
|
+
|
|
348
|
+
if ($botToken) {
|
|
349
|
+
Write-Host ""
|
|
350
|
+
Write-Host " ${CYAN}Step 4:${NC} Now get your Telegram user ID."
|
|
351
|
+
Write-Host " Search for ${BOLD}@userinfobot${NC} in Telegram"
|
|
352
|
+
Write-Host " (or open: ${DIM}https://t.me/userinfobot${NC})"
|
|
353
|
+
Write-Host " Send it any message. It replies with your ID (a number)."
|
|
354
|
+
Write-Host ""
|
|
355
|
+
$userId = Read-Host " Paste your user ID here (or press Enter to skip)"
|
|
356
|
+
|
|
357
|
+
if ($userId) {
|
|
358
|
+
# Write the config
|
|
359
|
+
$cfgData = @{}
|
|
360
|
+
if (Test-Path $CONFIG_FILE) {
|
|
361
|
+
try { $cfgData = Get-Content $CONFIG_FILE -Raw | ConvertFrom-Json } catch {}
|
|
362
|
+
}
|
|
363
|
+
if (-not $cfgData.channels) { $cfgData | Add-Member -NotePropertyName "channels" -NotePropertyValue @{} -Force }
|
|
364
|
+
$cfgData.channels | Add-Member -NotePropertyName "telegram" -NotePropertyValue @{
|
|
365
|
+
enabled = $true
|
|
366
|
+
allowedUsers = @($userId)
|
|
367
|
+
} -Force
|
|
368
|
+
$cfgData | ConvertTo-Json -Depth 10 | Set-Content $CONFIG_FILE
|
|
369
|
+
|
|
370
|
+
Write-Host ""
|
|
371
|
+
Write-Host " ${GREEN}✓${NC} Telegram configured in gateway.json"
|
|
372
|
+
Write-Host " ${GREEN}✓${NC} User $userId added to allowlist"
|
|
373
|
+
Write-Host ""
|
|
374
|
+
|
|
375
|
+
$env:TELEGRAM_BOT_TOKEN = $botToken
|
|
376
|
+
|
|
377
|
+
# Auto-persist token to PowerShell profile
|
|
378
|
+
$profilePath = $PROFILE.CurrentUserAllHosts
|
|
379
|
+
$profileDir = Split-Path $profilePath -Parent
|
|
380
|
+
if (-not (Test-Path $profileDir)) { New-Item -ItemType Directory -Force -Path $profileDir | Out-Null }
|
|
381
|
+
if (-not (Test-Path $profilePath)) { New-Item -ItemType File -Force -Path $profilePath | Out-Null }
|
|
382
|
+
|
|
383
|
+
$profileContent = Get-Content $profilePath -Raw -ErrorAction SilentlyContinue
|
|
384
|
+
$tokenLine = "`$env:TELEGRAM_BOT_TOKEN = '$botToken'"
|
|
385
|
+
|
|
386
|
+
if ($profileContent -match 'TELEGRAM_BOT_TOKEN') {
|
|
387
|
+
# Replace existing line
|
|
388
|
+
$profileContent = $profileContent -replace '(?m)^\$env:TELEGRAM_BOT_TOKEN\s*=.*$', $tokenLine
|
|
389
|
+
Set-Content -Path $profilePath -Value $profileContent
|
|
390
|
+
Write-Host " ${GREEN}✓${NC} Bot token updated in PowerShell profile"
|
|
391
|
+
} else {
|
|
392
|
+
Add-Content -Path $profilePath -Value "`n# Claudia Gateway - Telegram`n$tokenLine"
|
|
393
|
+
Write-Host " ${GREEN}✓${NC} Bot token saved to PowerShell profile"
|
|
394
|
+
}
|
|
395
|
+
} else {
|
|
396
|
+
Write-Host ""
|
|
397
|
+
Write-Host " ${YELLOW}!${NC} Skipped user ID. You'll need to add it manually:"
|
|
398
|
+
Write-Host " ${DIM}Edit $CONFIG_FILE and set:"
|
|
399
|
+
Write-Host " channels.telegram.allowedUsers = [$([char]34)YOUR_USER_ID$([char]34)]${NC}"
|
|
400
|
+
}
|
|
401
|
+
} else {
|
|
402
|
+
Write-Host ""
|
|
403
|
+
Write-Host " ${DIM}No worries. When you have your token, run:${NC}"
|
|
404
|
+
Write-Host " ${CYAN}`$env:TELEGRAM_BOT_TOKEN = 'your-token-here'${NC}"
|
|
405
|
+
Write-Host " ${CYAN}claudia-gateway start${NC}"
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
} elseif ($platformChoice -eq "2") {
|
|
409
|
+
Write-Host ""
|
|
410
|
+
Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
411
|
+
Write-Host ""
|
|
412
|
+
Write-Host " ${BOLD}Slack Setup${NC}"
|
|
413
|
+
Write-Host ""
|
|
414
|
+
Write-Host " ${CYAN}Step 1:${NC} Go to ${BOLD}https://api.slack.com/apps${NC}"
|
|
415
|
+
Write-Host " Click ${BOLD}Create New App${NC} > ${BOLD}From scratch${NC}"
|
|
416
|
+
Write-Host " Pick a name and workspace."
|
|
417
|
+
Write-Host ""
|
|
418
|
+
Write-Host " ${CYAN}Step 2:${NC} Enable ${BOLD}Socket Mode${NC} (in Settings sidebar)"
|
|
419
|
+
Write-Host " This generates an app-level token (starts with ${DIM}xapp-${NC})"
|
|
420
|
+
Write-Host " Name it anything (e.g. $([char]34)claudia-socket$([char]34)). Copy it."
|
|
421
|
+
Write-Host ""
|
|
422
|
+
Write-Host " ${CYAN}Step 3:${NC} Go to ${BOLD}OAuth & Permissions${NC}. Add these bot token scopes:"
|
|
423
|
+
Write-Host " ${DIM}app_mentions:read, chat:write, im:history, im:read, im:write${NC}"
|
|
424
|
+
Write-Host ""
|
|
425
|
+
Write-Host " ${CYAN}Step 4:${NC} Go to ${BOLD}Event Subscriptions${NC}. Enable events."
|
|
426
|
+
Write-Host " Subscribe to: ${DIM}message.im${NC} and ${DIM}app_mention${NC}"
|
|
427
|
+
Write-Host ""
|
|
428
|
+
Write-Host " ${CYAN}Step 5:${NC} Click ${BOLD}Install to Workspace${NC} (in sidebar or OAuth page)"
|
|
429
|
+
Write-Host " This generates a bot token (starts with ${DIM}xoxb-${NC}). Copy it."
|
|
430
|
+
Write-Host ""
|
|
431
|
+
Write-Host " ${CYAN}Step 6:${NC} Get your Slack user ID:"
|
|
432
|
+
Write-Host " Click your profile picture > ${BOLD}Profile${NC} > ${BOLD}...${NC} (more) > ${BOLD}Copy member ID${NC}"
|
|
433
|
+
Write-Host ""
|
|
434
|
+
$slackBot = Read-Host " Paste your bot token (xoxb-...)"
|
|
435
|
+
$slackApp = Read-Host " Paste your app token (xapp-...)"
|
|
436
|
+
$slackUser = Read-Host " Paste your user ID (U...)"
|
|
437
|
+
|
|
438
|
+
if ($slackBot -and $slackApp -and $slackUser) {
|
|
439
|
+
$cfgData = @{}
|
|
440
|
+
if (Test-Path $CONFIG_FILE) {
|
|
441
|
+
try { $cfgData = Get-Content $CONFIG_FILE -Raw | ConvertFrom-Json } catch {}
|
|
442
|
+
}
|
|
443
|
+
if (-not $cfgData.channels) { $cfgData | Add-Member -NotePropertyName "channels" -NotePropertyValue @{} -Force }
|
|
444
|
+
$cfgData.channels | Add-Member -NotePropertyName "slack" -NotePropertyValue @{
|
|
445
|
+
enabled = $true
|
|
446
|
+
allowedUsers = @($slackUser)
|
|
447
|
+
} -Force
|
|
448
|
+
$cfgData | ConvertTo-Json -Depth 10 | Set-Content $CONFIG_FILE
|
|
449
|
+
|
|
450
|
+
# Export tokens for this session
|
|
451
|
+
$env:SLACK_BOT_TOKEN = $slackBot
|
|
452
|
+
$env:SLACK_APP_TOKEN = $slackApp
|
|
453
|
+
|
|
454
|
+
Write-Host ""
|
|
455
|
+
Write-Host " ${GREEN}✓${NC} Slack configured in gateway.json"
|
|
456
|
+
Write-Host " ${GREEN}✓${NC} User $slackUser added to allowlist"
|
|
457
|
+
|
|
458
|
+
# Auto-persist tokens to PowerShell profile
|
|
459
|
+
$profilePath = $PROFILE.CurrentUserAllHosts
|
|
460
|
+
$profileDir = Split-Path $profilePath -Parent
|
|
461
|
+
if (-not (Test-Path $profileDir)) { New-Item -ItemType Directory -Force -Path $profileDir | Out-Null }
|
|
462
|
+
if (-not (Test-Path $profilePath)) { New-Item -ItemType File -Force -Path $profilePath | Out-Null }
|
|
463
|
+
|
|
464
|
+
$profileContent = Get-Content $profilePath -Raw -ErrorAction SilentlyContinue
|
|
465
|
+
$sbotLine = "`$env:SLACK_BOT_TOKEN = '$slackBot'"
|
|
466
|
+
$sappLine = "`$env:SLACK_APP_TOKEN = '$slackApp'"
|
|
467
|
+
|
|
468
|
+
if ($profileContent -match 'SLACK_BOT_TOKEN') {
|
|
469
|
+
$profileContent = $profileContent -replace '(?m)^\$env:SLACK_BOT_TOKEN\s*=.*$', $sbotLine
|
|
470
|
+
$profileContent = $profileContent -replace '(?m)^\$env:SLACK_APP_TOKEN\s*=.*$', $sappLine
|
|
471
|
+
Set-Content -Path $profilePath -Value $profileContent
|
|
472
|
+
Write-Host " ${GREEN}✓${NC} Slack tokens updated in PowerShell profile"
|
|
473
|
+
} else {
|
|
474
|
+
Add-Content -Path $profilePath -Value "`n# Claudia Gateway - Slack`n$sbotLine`n$sappLine"
|
|
475
|
+
Write-Host " ${GREEN}✓${NC} Slack tokens saved to PowerShell profile"
|
|
476
|
+
}
|
|
477
|
+
} else {
|
|
478
|
+
Write-Host ""
|
|
479
|
+
Write-Host " ${DIM}Missing some values. When you have all tokens, run:${NC}"
|
|
480
|
+
Write-Host " ${CYAN}`$env:SLACK_BOT_TOKEN = 'xoxb-...'${NC}"
|
|
481
|
+
Write-Host " ${CYAN}`$env:SLACK_APP_TOKEN = 'xapp-...'${NC}"
|
|
482
|
+
Write-Host " ${CYAN}claudia-gateway start${NC}"
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
Write-Host ""
|
|
487
|
+
Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
488
|
+
Write-Host ""
|
|
489
|
+
|
|
490
|
+
# Show the "How to Use" box if a platform was configured
|
|
491
|
+
if ($platformChoice -eq "1" -or $platformChoice -eq "2") {
|
|
492
|
+
Write-Host " ${BOLD}${CYAN}How It Works: Two Terminals${NC}"
|
|
493
|
+
Write-Host ""
|
|
494
|
+
Write-Host " The gateway is a separate program that connects your"
|
|
495
|
+
Write-Host " chat app (Telegram/Slack) to Claudia. It needs to run"
|
|
496
|
+
Write-Host " in its own terminal window while you use Claude in another."
|
|
497
|
+
Write-Host ""
|
|
498
|
+
Write-Host " ${BOLD}Terminal 1 (gateway):${NC}"
|
|
499
|
+
Write-Host " ${CYAN}claudia-gateway start${NC}"
|
|
500
|
+
Write-Host " ${DIM}Keep this running. It connects to your bot.${NC}"
|
|
501
|
+
Write-Host ""
|
|
502
|
+
Write-Host " ${BOLD}Terminal 2 (Claude):${NC}"
|
|
503
|
+
Write-Host " ${CYAN}cd your-project && claude${NC}"
|
|
504
|
+
Write-Host " ${DIM}Your normal Claude Code sessions.${NC}"
|
|
505
|
+
Write-Host ""
|
|
506
|
+
Write-Host " ${YELLOW}!${NC} The gateway must be running before you message the bot."
|
|
507
|
+
Write-Host " If the gateway is stopped, your bot won't respond."
|
|
508
|
+
Write-Host ""
|
|
509
|
+
Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
510
|
+
Write-Host ""
|
|
511
|
+
}
|
|
308
512
|
}
|
|
309
|
-
|
|
310
|
-
Write-Host "
|
|
311
|
-
Write-Host " ${YELLOW}□${NC} Never commit API keys to git or store them in gateway.json"
|
|
312
|
-
Write-Host ""
|
|
313
|
-
Write-Host "${BOLD}Quick start:${NC}"
|
|
513
|
+
|
|
514
|
+
Write-Host "${BOLD}Security reminders:${NC}"
|
|
314
515
|
Write-Host ""
|
|
315
516
|
if (-not $LOCAL_MODEL) {
|
|
316
|
-
Write-Host " ${
|
|
317
|
-
Write-Host " ${CYAN}2.${NC} `$env:TELEGRAM_BOT_TOKEN = '123456:ABC...'"
|
|
318
|
-
Write-Host " ${CYAN}3.${NC} Edit $CONFIG_FILE (enable channel, set allowedUsers)"
|
|
319
|
-
Write-Host " ${CYAN}4.${NC} claudia-gateway start"
|
|
517
|
+
Write-Host " ${YELLOW}□${NC} Set ANTHROPIC_API_KEY as an environment variable"
|
|
320
518
|
} else {
|
|
321
|
-
Write-Host " ${
|
|
322
|
-
Write-Host " ${CYAN}2.${NC} Edit $CONFIG_FILE (enable channel, set allowedUsers)"
|
|
323
|
-
Write-Host " ${CYAN}3.${NC} claudia-gateway start"
|
|
519
|
+
Write-Host " ${GREEN}✓${NC} Local model $LOCAL_MODEL (no API key needed)"
|
|
324
520
|
}
|
|
521
|
+
Write-Host " ${YELLOW}□${NC} Never commit API keys to git or store them in config files"
|
|
325
522
|
Write-Host ""
|
|
326
523
|
Write-Host "${BOLD}Installed:${NC}"
|
|
327
524
|
Write-Host ""
|
|
@@ -329,6 +526,10 @@ Write-Host " ${CYAN}◆${NC} Gateway source ${DIM}$GATEWAY_DIR${NC}"
|
|
|
329
526
|
Write-Host " ${CYAN}◆${NC} Config ${DIM}$CONFIG_FILE${NC}"
|
|
330
527
|
Write-Host " ${CYAN}◆${NC} CLI ${DIM}$wrapperPath${NC}"
|
|
331
528
|
Write-Host " ${CYAN}◆${NC} Logs ${DIM}$CLAUDIA_DIR\gateway.log${NC}"
|
|
529
|
+
if ($PATH_ADDED) {
|
|
530
|
+
Write-Host ""
|
|
531
|
+
Write-Host " ${YELLOW}!${NC} PATH was updated. Restart your terminal for it to take effect."
|
|
532
|
+
}
|
|
332
533
|
Write-Host ""
|
|
333
534
|
Write-Host "${BOLD}CLI commands:${NC}"
|
|
334
535
|
Write-Host ""
|
|
@@ -239,10 +239,36 @@ WRAPPER
|
|
|
239
239
|
chmod +x "$BIN_DIR/claudia-gateway"
|
|
240
240
|
echo -e " ${GREEN}✓${NC} CLI installed at ~/.claudia/bin/claudia-gateway"
|
|
241
241
|
|
|
242
|
-
#
|
|
242
|
+
# Auto-add to PATH via shell rc file if not already there
|
|
243
|
+
PATH_ADDED=0
|
|
243
244
|
if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
PATH_LINE='export PATH="$HOME/.claudia/bin:$PATH"'
|
|
246
|
+
|
|
247
|
+
# Detect shell rc file
|
|
248
|
+
SHELL_RC=""
|
|
249
|
+
if [ -n "$ZSH_VERSION" ] || [ "$(basename "$SHELL")" = "zsh" ]; then
|
|
250
|
+
SHELL_RC="$HOME/.zshrc"
|
|
251
|
+
elif [ -n "$BASH_VERSION" ] || [ "$(basename "$SHELL")" = "bash" ]; then
|
|
252
|
+
SHELL_RC="$HOME/.bashrc"
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
if [ -n "$SHELL_RC" ]; then
|
|
256
|
+
# Check if already in rc file (even if not in current PATH)
|
|
257
|
+
if [ -f "$SHELL_RC" ] && grep -q '\.claudia/bin' "$SHELL_RC" 2>/dev/null; then
|
|
258
|
+
echo -e " ${GREEN}✓${NC} PATH already configured in $(basename "$SHELL_RC")"
|
|
259
|
+
else
|
|
260
|
+
echo "" >> "$SHELL_RC"
|
|
261
|
+
echo "# Claudia CLI" >> "$SHELL_RC"
|
|
262
|
+
echo "$PATH_LINE" >> "$SHELL_RC"
|
|
263
|
+
echo -e " ${GREEN}✓${NC} PATH added to ~/${SHELL_RC##*/}"
|
|
264
|
+
PATH_ADDED=1
|
|
265
|
+
fi
|
|
266
|
+
# Also add to current session
|
|
267
|
+
export PATH="$HOME/.claudia/bin:$PATH"
|
|
268
|
+
else
|
|
269
|
+
echo -e " ${YELLOW}!${NC} Add to your PATH manually:"
|
|
270
|
+
echo -e " ${DIM}${PATH_LINE}${NC}"
|
|
271
|
+
fi
|
|
246
272
|
fi
|
|
247
273
|
|
|
248
274
|
# Create LaunchAgent / systemd unit (disabled by default)
|
|
@@ -338,30 +364,221 @@ cat << 'EOF'
|
|
|
338
364
|
EOF
|
|
339
365
|
echo -e "${NC}"
|
|
340
366
|
|
|
341
|
-
|
|
367
|
+
# Offer interactive setup guide
|
|
368
|
+
echo -e " The gateway needs a chat platform (Telegram or Slack) to"
|
|
369
|
+
echo -e " receive your messages. ${BOLD}Want a step-by-step setup guide?${NC}"
|
|
342
370
|
echo
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
echo
|
|
371
|
+
read -p " Show setup guide? [y/n, default=y]: " SHOW_GUIDE
|
|
372
|
+
SHOW_GUIDE="${SHOW_GUIDE:-y}"
|
|
373
|
+
|
|
374
|
+
if [[ "$SHOW_GUIDE" =~ ^[Yy] ]]; then
|
|
375
|
+
echo
|
|
376
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
377
|
+
echo
|
|
378
|
+
echo -e " ${BOLD}Which platform?${NC}"
|
|
379
|
+
echo -e " ${CYAN}1)${NC} Telegram ${DIM}(easiest, 2 minutes)${NC}"
|
|
380
|
+
echo -e " ${CYAN}2)${NC} Slack ${DIM}(requires workspace admin)${NC}"
|
|
381
|
+
echo -e " ${CYAN}3)${NC} Skip ${DIM}(I'll set it up later)${NC}"
|
|
382
|
+
echo
|
|
383
|
+
read -p " Choice [1-3, default=1]: " PLATFORM_CHOICE
|
|
384
|
+
PLATFORM_CHOICE="${PLATFORM_CHOICE:-1}"
|
|
385
|
+
|
|
386
|
+
if [ "$PLATFORM_CHOICE" = "1" ]; then
|
|
387
|
+
echo
|
|
388
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
389
|
+
echo
|
|
390
|
+
echo -e " ${BOLD}Telegram Setup${NC}"
|
|
391
|
+
echo
|
|
392
|
+
echo -e " ${CYAN}Step 1:${NC} Open Telegram and search for ${BOLD}@BotFather${NC}"
|
|
393
|
+
echo -e " (or tap: ${DIM}https://t.me/BotFather${NC})"
|
|
394
|
+
echo
|
|
395
|
+
echo -e " ${CYAN}Step 2:${NC} Send ${BOLD}/newbot${NC} to BotFather"
|
|
396
|
+
echo -e " He'll ask for a display name (anything, e.g. \"My Claudia\")"
|
|
397
|
+
echo -e " Then a username (must end in 'bot', e.g. \"my_claudia_bot\")"
|
|
398
|
+
echo
|
|
399
|
+
echo -e " ${CYAN}Step 3:${NC} BotFather will reply with a token like:"
|
|
400
|
+
echo -e " ${DIM}123456789:ABCdefGHIjklMNOpqrsTUVwxyz${NC}"
|
|
401
|
+
echo -e " Copy that token."
|
|
402
|
+
echo
|
|
403
|
+
read -p " Paste your bot token here (or press Enter to skip): " BOT_TOKEN
|
|
404
|
+
|
|
405
|
+
if [ -n "$BOT_TOKEN" ]; then
|
|
406
|
+
echo
|
|
407
|
+
echo -e " ${CYAN}Step 4:${NC} Now get your Telegram user ID."
|
|
408
|
+
echo -e " Search for ${BOLD}@userinfobot${NC} in Telegram"
|
|
409
|
+
echo -e " (or tap: ${DIM}https://t.me/userinfobot${NC})"
|
|
410
|
+
echo -e " Send it any message. It replies with your ID (a number)."
|
|
411
|
+
echo
|
|
412
|
+
read -p " Paste your user ID here (or press Enter to skip): " USER_ID
|
|
413
|
+
|
|
414
|
+
if [ -n "$USER_ID" ]; then
|
|
415
|
+
# Write the config
|
|
416
|
+
node -e "
|
|
417
|
+
const fs = require('fs');
|
|
418
|
+
const path = '$CONFIG_FILE';
|
|
419
|
+
let c = {};
|
|
420
|
+
try { c = JSON.parse(fs.readFileSync(path, 'utf8')); } catch {}
|
|
421
|
+
if (!c.channels) c.channels = {};
|
|
422
|
+
if (!c.channels.telegram) c.channels.telegram = {};
|
|
423
|
+
c.channels.telegram.enabled = true;
|
|
424
|
+
c.channels.telegram.allowedUsers = ['$USER_ID'];
|
|
425
|
+
fs.writeFileSync(path, JSON.stringify(c, null, 2));
|
|
426
|
+
" 2>/dev/null
|
|
427
|
+
|
|
428
|
+
echo
|
|
429
|
+
echo -e " ${GREEN}✓${NC} Telegram configured in gateway.json"
|
|
430
|
+
echo -e " ${GREEN}✓${NC} User ${USER_ID} added to allowlist"
|
|
431
|
+
echo
|
|
432
|
+
|
|
433
|
+
# Export the token for this session
|
|
434
|
+
export TELEGRAM_BOT_TOKEN="$BOT_TOKEN"
|
|
435
|
+
|
|
436
|
+
# Auto-persist token to shell rc file
|
|
437
|
+
TOKEN_LINE="export TELEGRAM_BOT_TOKEN=\"$BOT_TOKEN\""
|
|
438
|
+
if [ -n "$SHELL_RC" ]; then
|
|
439
|
+
if [ -f "$SHELL_RC" ] && grep -q 'TELEGRAM_BOT_TOKEN' "$SHELL_RC" 2>/dev/null; then
|
|
440
|
+
# Replace existing line
|
|
441
|
+
sed -i.bak "s|^export TELEGRAM_BOT_TOKEN=.*|$TOKEN_LINE|" "$SHELL_RC" && rm -f "${SHELL_RC}.bak"
|
|
442
|
+
echo -e " ${GREEN}✓${NC} Bot token updated in ~/${SHELL_RC##*/}"
|
|
443
|
+
else
|
|
444
|
+
echo "" >> "$SHELL_RC"
|
|
445
|
+
echo "# Claudia Gateway - Telegram" >> "$SHELL_RC"
|
|
446
|
+
echo "$TOKEN_LINE" >> "$SHELL_RC"
|
|
447
|
+
echo -e " ${GREEN}✓${NC} Bot token saved to ~/${SHELL_RC##*/}"
|
|
448
|
+
fi
|
|
449
|
+
else
|
|
450
|
+
echo -e " ${YELLOW}!${NC} Add this to your shell profile to persist the token:"
|
|
451
|
+
echo -e " ${DIM}${TOKEN_LINE}${NC}"
|
|
452
|
+
fi
|
|
453
|
+
else
|
|
454
|
+
echo
|
|
455
|
+
echo -e " ${YELLOW}!${NC} Skipped user ID. You'll need to add it manually:"
|
|
456
|
+
echo -e " ${DIM}Edit ~/.claudia/gateway.json and set:"
|
|
457
|
+
echo -e " channels.telegram.allowedUsers = [\"YOUR_USER_ID\"]${NC}"
|
|
458
|
+
fi
|
|
459
|
+
else
|
|
460
|
+
echo
|
|
461
|
+
echo -e " ${DIM}No worries. When you have your token, run:${NC}"
|
|
462
|
+
echo -e " ${CYAN}export TELEGRAM_BOT_TOKEN=\"your-token-here\"${NC}"
|
|
463
|
+
echo -e " ${CYAN}claudia-gateway start${NC}"
|
|
464
|
+
fi
|
|
465
|
+
|
|
466
|
+
elif [ "$PLATFORM_CHOICE" = "2" ]; then
|
|
467
|
+
echo
|
|
468
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
469
|
+
echo
|
|
470
|
+
echo -e " ${BOLD}Slack Setup${NC}"
|
|
471
|
+
echo
|
|
472
|
+
echo -e " ${CYAN}Step 1:${NC} Go to ${BOLD}https://api.slack.com/apps${NC}"
|
|
473
|
+
echo -e " Click ${BOLD}Create New App${NC} > ${BOLD}From scratch${NC}"
|
|
474
|
+
echo -e " Pick a name and workspace."
|
|
475
|
+
echo
|
|
476
|
+
echo -e " ${CYAN}Step 2:${NC} Enable ${BOLD}Socket Mode${NC} (in Settings sidebar)"
|
|
477
|
+
echo -e " This generates an app-level token (starts with ${DIM}xapp-${NC})"
|
|
478
|
+
echo -e " Name it anything (e.g. \"claudia-socket\"). Copy it."
|
|
479
|
+
echo
|
|
480
|
+
echo -e " ${CYAN}Step 3:${NC} Go to ${BOLD}OAuth & Permissions${NC}. Add these bot token scopes:"
|
|
481
|
+
echo -e " ${DIM}app_mentions:read, chat:write, im:history, im:read, im:write${NC}"
|
|
482
|
+
echo
|
|
483
|
+
echo -e " ${CYAN}Step 4:${NC} Go to ${BOLD}Event Subscriptions${NC}. Enable events."
|
|
484
|
+
echo -e " Subscribe to: ${DIM}message.im${NC} and ${DIM}app_mention${NC}"
|
|
485
|
+
echo
|
|
486
|
+
echo -e " ${CYAN}Step 5:${NC} Click ${BOLD}Install to Workspace${NC} (in sidebar or OAuth page)"
|
|
487
|
+
echo -e " This generates a bot token (starts with ${DIM}xoxb-${NC}). Copy it."
|
|
488
|
+
echo
|
|
489
|
+
echo -e " ${CYAN}Step 6:${NC} Get your Slack user ID:"
|
|
490
|
+
echo -e " Click your profile picture > ${BOLD}Profile${NC} > ${BOLD}...${NC} (more) > ${BOLD}Copy member ID${NC}"
|
|
491
|
+
echo
|
|
492
|
+
read -p " Paste your bot token (xoxb-...): " SLACK_BOT
|
|
493
|
+
read -p " Paste your app token (xapp-...): " SLACK_APP
|
|
494
|
+
read -p " Paste your user ID (U...): " SLACK_USER
|
|
495
|
+
|
|
496
|
+
if [ -n "$SLACK_BOT" ] && [ -n "$SLACK_APP" ] && [ -n "$SLACK_USER" ]; then
|
|
497
|
+
node -e "
|
|
498
|
+
const fs = require('fs');
|
|
499
|
+
const path = '$CONFIG_FILE';
|
|
500
|
+
let c = {};
|
|
501
|
+
try { c = JSON.parse(fs.readFileSync(path, 'utf8')); } catch {}
|
|
502
|
+
if (!c.channels) c.channels = {};
|
|
503
|
+
if (!c.channels.slack) c.channels.slack = {};
|
|
504
|
+
c.channels.slack.enabled = true;
|
|
505
|
+
c.channels.slack.allowedUsers = ['$SLACK_USER'];
|
|
506
|
+
fs.writeFileSync(path, JSON.stringify(c, null, 2));
|
|
507
|
+
" 2>/dev/null
|
|
508
|
+
|
|
509
|
+
# Export tokens for this session
|
|
510
|
+
export SLACK_BOT_TOKEN="$SLACK_BOT"
|
|
511
|
+
export SLACK_APP_TOKEN="$SLACK_APP"
|
|
512
|
+
|
|
513
|
+
echo
|
|
514
|
+
echo -e " ${GREEN}✓${NC} Slack configured in gateway.json"
|
|
515
|
+
echo -e " ${GREEN}✓${NC} User ${SLACK_USER} added to allowlist"
|
|
516
|
+
|
|
517
|
+
# Auto-persist tokens to shell rc file
|
|
518
|
+
SBOT_LINE="export SLACK_BOT_TOKEN=\"$SLACK_BOT\""
|
|
519
|
+
SAPP_LINE="export SLACK_APP_TOKEN=\"$SLACK_APP\""
|
|
520
|
+
if [ -n "$SHELL_RC" ]; then
|
|
521
|
+
if [ -f "$SHELL_RC" ] && grep -q 'SLACK_BOT_TOKEN' "$SHELL_RC" 2>/dev/null; then
|
|
522
|
+
sed -i.bak "s|^export SLACK_BOT_TOKEN=.*|$SBOT_LINE|" "$SHELL_RC" && rm -f "${SHELL_RC}.bak"
|
|
523
|
+
sed -i.bak "s|^export SLACK_APP_TOKEN=.*|$SAPP_LINE|" "$SHELL_RC" && rm -f "${SHELL_RC}.bak"
|
|
524
|
+
echo -e " ${GREEN}✓${NC} Slack tokens updated in ~/${SHELL_RC##*/}"
|
|
525
|
+
else
|
|
526
|
+
echo "" >> "$SHELL_RC"
|
|
527
|
+
echo "# Claudia Gateway - Slack" >> "$SHELL_RC"
|
|
528
|
+
echo "$SBOT_LINE" >> "$SHELL_RC"
|
|
529
|
+
echo "$SAPP_LINE" >> "$SHELL_RC"
|
|
530
|
+
echo -e " ${GREEN}✓${NC} Slack tokens saved to ~/${SHELL_RC##*/}"
|
|
531
|
+
fi
|
|
532
|
+
else
|
|
533
|
+
echo -e " ${YELLOW}!${NC} Add these to your shell profile to persist the tokens:"
|
|
534
|
+
echo -e " ${DIM}${SBOT_LINE}${NC}"
|
|
535
|
+
echo -e " ${DIM}${SAPP_LINE}${NC}"
|
|
536
|
+
fi
|
|
537
|
+
else
|
|
538
|
+
echo
|
|
539
|
+
echo -e " ${DIM}Missing some values. When you have all tokens, run:${NC}"
|
|
540
|
+
echo -e " ${CYAN}export SLACK_BOT_TOKEN=\"xoxb-...\"${NC}"
|
|
541
|
+
echo -e " ${CYAN}export SLACK_APP_TOKEN=\"xapp-...\"${NC}"
|
|
542
|
+
echo -e " ${CYAN}claudia-gateway start${NC}"
|
|
543
|
+
fi
|
|
544
|
+
fi
|
|
545
|
+
|
|
546
|
+
echo
|
|
547
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
548
|
+
echo
|
|
549
|
+
|
|
550
|
+
# Show the "How to Use" box if a platform was configured
|
|
551
|
+
if [ "$PLATFORM_CHOICE" = "1" ] || [ "$PLATFORM_CHOICE" = "2" ]; then
|
|
552
|
+
echo -e " ${BOLD}${CYAN}How It Works: Two Terminals${NC}"
|
|
553
|
+
echo
|
|
554
|
+
echo -e " The gateway is a separate program that connects your"
|
|
555
|
+
echo -e " chat app (Telegram/Slack) to Claudia. It needs to run"
|
|
556
|
+
echo -e " in its own terminal window while you use Claude in another."
|
|
557
|
+
echo
|
|
558
|
+
echo -e " ${BOLD}Terminal 1 (gateway):${NC}"
|
|
559
|
+
echo -e " ${CYAN}claudia-gateway start${NC}"
|
|
560
|
+
echo -e " ${DIM}Keep this running. It connects to your bot.${NC}"
|
|
561
|
+
echo
|
|
562
|
+
echo -e " ${BOLD}Terminal 2 (Claude):${NC}"
|
|
563
|
+
echo -e " ${CYAN}cd your-project && claude${NC}"
|
|
564
|
+
echo -e " ${DIM}Your normal Claude Code sessions.${NC}"
|
|
565
|
+
echo
|
|
566
|
+
echo -e " ${YELLOW}!${NC} The gateway must be running before you message the bot."
|
|
567
|
+
echo -e " If the gateway is stopped, your bot won't respond."
|
|
568
|
+
echo
|
|
569
|
+
echo -e "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
570
|
+
echo
|
|
571
|
+
fi
|
|
348
572
|
fi
|
|
349
|
-
|
|
350
|
-
echo -e "
|
|
351
|
-
echo -e " ${YELLOW}□${NC} Never commit API keys to git or store them in gateway.json"
|
|
352
|
-
echo
|
|
353
|
-
echo -e "${BOLD}Quick start:${NC}"
|
|
573
|
+
|
|
574
|
+
echo -e "${BOLD}Security reminders:${NC}"
|
|
354
575
|
echo
|
|
355
576
|
if [ -z "$LOCAL_MODEL" ]; then
|
|
356
|
-
echo -e " ${
|
|
357
|
-
echo -e " ${CYAN}2.${NC} export TELEGRAM_BOT_TOKEN=123456:ABC..."
|
|
358
|
-
echo -e " ${CYAN}3.${NC} Edit ~/.claudia/gateway.json (enable channel, set allowedUsers)"
|
|
359
|
-
echo -e " ${CYAN}4.${NC} claudia-gateway start"
|
|
577
|
+
echo -e " ${YELLOW}□${NC} Set ANTHROPIC_API_KEY as an environment variable"
|
|
360
578
|
else
|
|
361
|
-
echo -e " ${
|
|
362
|
-
echo -e " ${CYAN}2.${NC} Edit ~/.claudia/gateway.json (enable channel, set allowedUsers)"
|
|
363
|
-
echo -e " ${CYAN}3.${NC} claudia-gateway start"
|
|
579
|
+
echo -e " ${GREEN}✓${NC} Local model ${LOCAL_MODEL} (no API key needed)"
|
|
364
580
|
fi
|
|
581
|
+
echo -e " ${YELLOW}□${NC} Never commit API keys to git or store them in config files"
|
|
365
582
|
echo
|
|
366
583
|
echo -e "${BOLD}Installed:${NC}"
|
|
367
584
|
echo
|
|
@@ -369,6 +586,10 @@ echo -e " ${CYAN}◆${NC} Gateway source ${DIM}$GATEWAY_DIR${NC}"
|
|
|
369
586
|
echo -e " ${CYAN}◆${NC} Config ${DIM}~/.claudia/gateway.json${NC}"
|
|
370
587
|
echo -e " ${CYAN}◆${NC} CLI ${DIM}~/.claudia/bin/claudia-gateway${NC}"
|
|
371
588
|
echo -e " ${CYAN}◆${NC} Logs ${DIM}~/.claudia/gateway.log${NC}"
|
|
589
|
+
if [ "$PATH_ADDED" = "1" ]; then
|
|
590
|
+
echo
|
|
591
|
+
echo -e " ${YELLOW}!${NC} PATH was updated. Run ${BOLD}source ~/${SHELL_RC##*/}${NC} or open a new terminal."
|
|
592
|
+
fi
|
|
372
593
|
echo
|
|
373
594
|
echo -e "${BOLD}CLI commands:${NC}"
|
|
374
595
|
echo
|