opensentinel 2.1.1

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/dist/bot-KJ26BG56.js +15 -0
  4. package/dist/bot-KJ26BG56.js.map +1 -0
  5. package/dist/charts-MMXM6BWW.js +241 -0
  6. package/dist/charts-MMXM6BWW.js.map +1 -0
  7. package/dist/chunk-4LVWXUNC.js +1079 -0
  8. package/dist/chunk-4LVWXUNC.js.map +1 -0
  9. package/dist/chunk-4TG2IG5K.js +5249 -0
  10. package/dist/chunk-4TG2IG5K.js.map +1 -0
  11. package/dist/chunk-6DRDKB45.js +251 -0
  12. package/dist/chunk-6DRDKB45.js.map +1 -0
  13. package/dist/chunk-6SNHU3CY.js +123 -0
  14. package/dist/chunk-6SNHU3CY.js.map +1 -0
  15. package/dist/chunk-CI6Q63MM.js +1613 -0
  16. package/dist/chunk-CI6Q63MM.js.map +1 -0
  17. package/dist/chunk-CQ4JURG7.js +57 -0
  18. package/dist/chunk-CQ4JURG7.js.map +1 -0
  19. package/dist/chunk-F6QUZQGI.js +51 -0
  20. package/dist/chunk-F6QUZQGI.js.map +1 -0
  21. package/dist/chunk-GK3E2I7A.js +216 -0
  22. package/dist/chunk-GK3E2I7A.js.map +1 -0
  23. package/dist/chunk-GUBEEYDW.js +211 -0
  24. package/dist/chunk-GUBEEYDW.js.map +1 -0
  25. package/dist/chunk-GVJVEWHI.js +29 -0
  26. package/dist/chunk-GVJVEWHI.js.map +1 -0
  27. package/dist/chunk-HH2HBTQM.js +806 -0
  28. package/dist/chunk-HH2HBTQM.js.map +1 -0
  29. package/dist/chunk-JXUP2X7V.js +129 -0
  30. package/dist/chunk-JXUP2X7V.js.map +1 -0
  31. package/dist/chunk-KHNYJY2Z.js +178 -0
  32. package/dist/chunk-KHNYJY2Z.js.map +1 -0
  33. package/dist/chunk-L3F43VPB.js +652 -0
  34. package/dist/chunk-L3F43VPB.js.map +1 -0
  35. package/dist/chunk-L3PDU3XN.js +803 -0
  36. package/dist/chunk-L3PDU3XN.js.map +1 -0
  37. package/dist/chunk-NSBPE2FW.js +17 -0
  38. package/dist/chunk-NSBPE2FW.js.map +1 -0
  39. package/dist/cli.d.ts +1 -0
  40. package/dist/cli.js +52 -0
  41. package/dist/cli.js.map +1 -0
  42. package/dist/commands/setup.d.ts +9 -0
  43. package/dist/commands/setup.js +374 -0
  44. package/dist/commands/setup.js.map +1 -0
  45. package/dist/commands/start.d.ts +8 -0
  46. package/dist/commands/start.js +27 -0
  47. package/dist/commands/start.js.map +1 -0
  48. package/dist/commands/status.d.ts +8 -0
  49. package/dist/commands/status.js +57 -0
  50. package/dist/commands/status.js.map +1 -0
  51. package/dist/commands/stop.d.ts +8 -0
  52. package/dist/commands/stop.js +37 -0
  53. package/dist/commands/stop.js.map +1 -0
  54. package/dist/commands/utils.d.ts +50 -0
  55. package/dist/commands/utils.js +36 -0
  56. package/dist/commands/utils.js.map +1 -0
  57. package/dist/discord-ZOJFTVTB.js +49 -0
  58. package/dist/discord-ZOJFTVTB.js.map +1 -0
  59. package/dist/imessage-JFRB6EJ7.js +14 -0
  60. package/dist/imessage-JFRB6EJ7.js.map +1 -0
  61. package/dist/lib.d.ts +855 -0
  62. package/dist/lib.js +274 -0
  63. package/dist/lib.js.map +1 -0
  64. package/dist/mcp-LS7Q3Z5W.js +30 -0
  65. package/dist/mcp-LS7Q3Z5W.js.map +1 -0
  66. package/dist/scheduler-EZ7CZMCS.js +42 -0
  67. package/dist/scheduler-EZ7CZMCS.js.map +1 -0
  68. package/dist/signal-T3MCSULM.js +14 -0
  69. package/dist/signal-T3MCSULM.js.map +1 -0
  70. package/dist/slack-N2M4FHAJ.js +54 -0
  71. package/dist/slack-N2M4FHAJ.js.map +1 -0
  72. package/dist/src-K7GASHRH.js +430 -0
  73. package/dist/src-K7GASHRH.js.map +1 -0
  74. package/dist/tools-24GZHYRF.js +16 -0
  75. package/dist/tools-24GZHYRF.js.map +1 -0
  76. package/dist/whatsapp-VCRUPAO5.js +14 -0
  77. package/dist/whatsapp-VCRUPAO5.js.map +1 -0
  78. package/drizzle/0000_chilly_shinobi_shaw.sql +75 -0
  79. package/drizzle/0001_freezing_shape.sql +274 -0
  80. package/drizzle/meta/0000_snapshot.json +529 -0
  81. package/drizzle/meta/0001_snapshot.json +2576 -0
  82. package/drizzle/meta/_journal.json +20 -0
  83. package/package.json +98 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/setup.ts"],"sourcesContent":["/**\n * OpenSentinel Setup Wizard\n *\n * Interactive setup that installs dependencies, configures the database,\n * generates config, and optionally installs a system service.\n */\n\nimport { writeFileSync, chmodSync, existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport {\n prompt,\n confirm,\n exec,\n which,\n detectPlatform,\n getConfigDir,\n getPackageRoot,\n getMigrationsDir,\n checkPostgres,\n checkRedis,\n colors,\n printBanner,\n type Platform,\n} from \"./utils\";\n\nexport default async function setup() {\n printBanner();\n console.log(`${colors.bold}Setup Wizard${colors.reset}\\n`);\n\n const platform = detectPlatform();\n if (platform.os === \"other\") {\n console.log(`${colors.yellow}Warning: Only Linux and macOS are fully supported.`);\n console.log(`On Windows, use WSL or Docker.${colors.reset}\\n`);\n }\n\n const configDir = getConfigDir();\n console.log(`${colors.dim}Config directory: ${configDir}${colors.reset}\\n`);\n\n // ── Step 1: API Keys ─────────────────────────────────────────────────────\n\n console.log(`${colors.cyan}${colors.bold}[1/5] API Keys${colors.reset}\\n`);\n\n let claudeKey = process.env.CLAUDE_API_KEY || \"\";\n if (!claudeKey) {\n claudeKey = await prompt(` Claude API Key ${colors.red}(required)${colors.reset}: `);\n if (!claudeKey) {\n console.error(`\\n${colors.red}Claude API Key is required. Get one at https://console.anthropic.com${colors.reset}`);\n process.exit(1);\n }\n } else {\n console.log(` Claude API Key: ${colors.green}configured${colors.reset} (***${claudeKey.slice(-4)})`);\n }\n\n const telegramToken = process.env.TELEGRAM_BOT_TOKEN || await prompt(` Telegram Bot Token ${colors.dim}(optional, Enter to skip)${colors.reset}: `);\n const telegramChatId = telegramToken ? (process.env.TELEGRAM_CHAT_ID || await prompt(` Telegram Chat ID: `)) : \"\";\n const discordToken = process.env.DISCORD_BOT_TOKEN || await prompt(` Discord Bot Token ${colors.dim}(optional, Enter to skip)${colors.reset}: `);\n const discordClientId = discordToken ? (process.env.DISCORD_CLIENT_ID || await prompt(` Discord Client ID: `)) : \"\";\n const discordGuildId = discordToken ? (process.env.DISCORD_GUILD_ID || await prompt(` Discord Guild ID: `)) : \"\";\n const discordAllowedUsers = discordToken ? (process.env.DISCORD_ALLOWED_USER_IDS || await prompt(` Discord Allowed User IDs ${colors.dim}(comma-separated)${colors.reset}: `)) : \"\";\n const openaiKey = process.env.OPENAI_API_KEY || await prompt(` OpenAI API Key ${colors.dim}(optional, for voice/images)${colors.reset}: `);\n const elevenlabsKey = process.env.ELEVENLABS_API_KEY || await prompt(` ElevenLabs API Key ${colors.dim}(optional, for TTS)${colors.reset}: `);\n const elevenlabsVoice = elevenlabsKey ? (process.env.ELEVENLABS_VOICE_ID || await prompt(` ElevenLabs Voice ID: `)) : \"\";\n\n console.log(`\\n${colors.green} API keys collected.${colors.reset}\\n`);\n\n // ── Step 2: Infrastructure ────────────────────────────────────────────────\n\n console.log(`${colors.cyan}${colors.bold}[2/5] Infrastructure${colors.reset}\\n`);\n\n const { databaseUrl } = await setupPostgres(platform);\n const { redisUrl } = await setupRedis(platform);\n\n // ── Step 3: Database Migrations ───────────────────────────────────────────\n\n console.log(`\\n${colors.cyan}${colors.bold}[3/5] Database${colors.reset}\\n`);\n\n await runMigrations(databaseUrl);\n\n // ── Step 4: Generate Config ───────────────────────────────────────────────\n\n console.log(`\\n${colors.cyan}${colors.bold}[4/5] Configuration${colors.reset}\\n`);\n\n const port = process.env.PORT || \"8030\";\n\n const envContent = `# OpenSentinel Configuration\n# Generated by opensentinel setup on ${new Date().toISOString()}\n\n# Core AI\nCLAUDE_API_KEY=${claudeKey}\n${openaiKey ? `OPENAI_API_KEY=${openaiKey}` : \"# OPENAI_API_KEY=\"}\n${elevenlabsKey ? `ELEVENLABS_API_KEY=${elevenlabsKey}` : \"# ELEVENLABS_API_KEY=\"}\n${elevenlabsVoice ? `ELEVENLABS_VOICE_ID=${elevenlabsVoice}` : \"# ELEVENLABS_VOICE_ID=\"}\n\n# Telegram\n${telegramToken ? `TELEGRAM_BOT_TOKEN=${telegramToken}` : \"# TELEGRAM_BOT_TOKEN=\"}\n${telegramChatId ? `TELEGRAM_CHAT_ID=${telegramChatId}` : \"# TELEGRAM_CHAT_ID=\"}\n\n# Discord\n${discordToken ? `DISCORD_BOT_TOKEN=${discordToken}` : \"# DISCORD_BOT_TOKEN=\"}\n${discordClientId ? `DISCORD_CLIENT_ID=${discordClientId}` : \"# DISCORD_CLIENT_ID=\"}\n${discordGuildId ? `DISCORD_GUILD_ID=${discordGuildId}` : \"# DISCORD_GUILD_ID=\"}\n${discordAllowedUsers ? `DISCORD_ALLOWED_USER_IDS=${discordAllowedUsers}` : \"# DISCORD_ALLOWED_USER_IDS=\"}\n\n# Database & Cache\nDATABASE_URL=${databaseUrl}\nREDIS_URL=${redisUrl}\n\n# Server\nPORT=${port}\nNODE_ENV=production\n`;\n\n const envPath = join(configDir, \".env\");\n writeFileSync(envPath, envContent);\n chmodSync(envPath, 0o600);\n console.log(` Config written to ${colors.green}${envPath}${colors.reset}`);\n\n // ── Step 5: System Service ────────────────────────────────────────────────\n\n console.log(`\\n${colors.cyan}${colors.bold}[5/5] System Service${colors.reset}\\n`);\n\n await setupDaemon(platform, configDir);\n\n // ── Done ──────────────────────────────────────────────────────────────────\n\n console.log(`\n${colors.green}${colors.bold}Setup complete!${colors.reset}\n\n${colors.bold}Quick reference:${colors.reset}\n opensentinel start Start the server\n opensentinel stop Stop the service\n opensentinel status Check health\n opensentinel help Show all commands\n\n${colors.bold}Config:${colors.reset} ${envPath}\n${colors.bold}Docs:${colors.reset} https://docs.opensentinel.ai\n`);\n}\n\n// ── PostgreSQL Setup ─────────────────────────────────────────────────────────\n\nasync function setupPostgres(platform: Platform): Promise<{ databaseUrl: string }> {\n const pg = await checkPostgres();\n\n if (pg.running) {\n console.log(` PostgreSQL: ${colors.green}running${colors.reset} (port ${pg.port})`);\n const useExisting = await confirm(\" Use existing PostgreSQL?\");\n if (useExisting) {\n return await configureExistingPostgres(pg.port);\n }\n } else if (pg.installed) {\n console.log(` PostgreSQL: ${colors.yellow}installed but not running${colors.reset}`);\n const startIt = await confirm(\" Start PostgreSQL?\");\n if (startIt) {\n await startPostgres(platform);\n return await configureExistingPostgres(5432);\n }\n } else {\n console.log(` PostgreSQL: ${colors.red}not found${colors.reset}`);\n }\n\n const install = await confirm(\" Install PostgreSQL 16 + pgvector?\");\n if (!install) {\n console.log(`\\n${colors.yellow} Skipping PostgreSQL. The app will start but memory and history won't persist.${colors.reset}`);\n return { databaseUrl: \"postgresql://localhost:5432/opensentinel\" };\n }\n\n return await installPostgres(platform);\n}\n\nasync function configureExistingPostgres(port: number): Promise<{ databaseUrl: string }> {\n // Try to create the database and user\n const dbUser = \"opensentinel\";\n const dbPass = \"opensentinel\";\n const dbName = \"opensentinel\";\n\n console.log(` Creating database '${dbName}'...`);\n\n // Try as postgres superuser first (common on Linux)\n try {\n await exec(`sudo -u postgres psql -c \"SELECT 1 FROM pg_roles WHERE rolname='${dbUser}'\" 2>/dev/null | grep -q 1 || sudo -u postgres psql -c \"CREATE USER ${dbUser} WITH PASSWORD '${dbPass}'\"`, { throws: false });\n await exec(`sudo -u postgres psql -c \"SELECT 1 FROM pg_database WHERE datname='${dbName}'\" 2>/dev/null | grep -q 1 || sudo -u postgres psql -c \"CREATE DATABASE ${dbName} OWNER ${dbUser}\"`, { throws: false });\n await exec(`sudo -u postgres psql -d ${dbName} -c \"CREATE EXTENSION IF NOT EXISTS vector\" 2>/dev/null`, { throws: false });\n console.log(` ${colors.green}Database ready.${colors.reset}`);\n } catch {\n // On macOS or systems where current user is superuser\n try {\n await exec(`psql -c \"SELECT 1 FROM pg_roles WHERE rolname='${dbUser}'\" postgres 2>/dev/null | grep -q 1 || createuser ${dbUser} 2>/dev/null`, { throws: false });\n await exec(`psql -c \"SELECT 1 FROM pg_database WHERE datname='${dbName}'\" postgres 2>/dev/null | grep -q 1 || createdb -O ${dbUser} ${dbName} 2>/dev/null`, { throws: false });\n await exec(`psql -d ${dbName} -c \"CREATE EXTENSION IF NOT EXISTS vector\" 2>/dev/null`, { throws: false });\n console.log(` ${colors.green}Database ready.${colors.reset}`);\n } catch {\n console.log(` ${colors.yellow}Could not auto-configure database. You may need to create it manually.${colors.reset}`);\n }\n }\n\n return { databaseUrl: `postgresql://${dbUser}:${dbPass}@localhost:${port}/${dbName}` };\n}\n\nasync function startPostgres(platform: Platform) {\n if (platform.os === \"linux\") {\n await exec(\"sudo systemctl start postgresql\", { throws: false });\n } else if (platform.os === \"darwin\") {\n await exec(\"brew services start postgresql@16\", { throws: false });\n }\n}\n\nasync function installPostgres(platform: Platform): Promise<{ databaseUrl: string }> {\n console.log(`\\n Installing PostgreSQL 16 + pgvector...`);\n\n if (platform.packageManager === \"apt\") {\n // Check if PostgreSQL APT repo is available for PG16\n const hasRepo = await exec(\"apt-cache show postgresql-16 2>/dev/null\", { throws: false });\n if (hasRepo.exitCode !== 0) {\n console.log(` Adding PostgreSQL APT repository...`);\n await exec(`sudo sh -c 'echo \"deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main\" > /etc/apt/sources.list.d/pgdg.list'`);\n await exec(\"curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg\");\n }\n await exec(\"sudo apt-get update -qq\");\n await exec(\"sudo apt-get install -y postgresql-16 postgresql-16-pgvector\");\n await exec(\"sudo systemctl enable postgresql\");\n await exec(\"sudo systemctl start postgresql\");\n } else if (platform.packageManager === \"brew\") {\n await exec(\"brew install postgresql@16 pgvector\");\n await exec(\"brew services start postgresql@16\");\n // Wait for PG to start\n await new Promise((r) => setTimeout(r, 2000));\n } else if (platform.packageManager === \"dnf\") {\n await exec(\"sudo dnf install -y postgresql16-server postgresql16-pgvector\");\n await exec(\"sudo postgresql-setup --initdb 2>/dev/null || true\");\n await exec(\"sudo systemctl enable postgresql\");\n await exec(\"sudo systemctl start postgresql\");\n } else {\n console.log(` ${colors.yellow}Unsupported package manager. Please install PostgreSQL 16 + pgvector manually.${colors.reset}`);\n return { databaseUrl: \"postgresql://opensentinel:opensentinel@localhost:5432/opensentinel\" };\n }\n\n console.log(` ${colors.green}PostgreSQL installed.${colors.reset}`);\n return await configureExistingPostgres(5432);\n}\n\n// ── Redis Setup ──────────────────────────────────────────────────────────────\n\nasync function setupRedis(platform: Platform): Promise<{ redisUrl: string }> {\n const redis = await checkRedis();\n\n if (redis.running) {\n console.log(` Redis: ${colors.green}running${colors.reset} (port ${redis.port})`);\n return { redisUrl: `redis://localhost:${redis.port}` };\n } else if (redis.installed) {\n console.log(` Redis: ${colors.yellow}installed but not running${colors.reset}`);\n const startIt = await confirm(\" Start Redis?\");\n if (startIt) {\n await startRedis(platform);\n return { redisUrl: \"redis://localhost:6379\" };\n }\n } else {\n console.log(` Redis: ${colors.red}not found${colors.reset}`);\n }\n\n const install = await confirm(\" Install Redis?\");\n if (!install) {\n console.log(`\\n${colors.yellow} Skipping Redis. Scheduled tasks and job queues will be unavailable.${colors.reset}`);\n return { redisUrl: \"redis://localhost:6379\" };\n }\n\n return await installRedis(platform);\n}\n\nasync function startRedis(platform: Platform) {\n if (platform.os === \"linux\") {\n await exec(\"sudo systemctl start redis-server 2>/dev/null || sudo systemctl start redis 2>/dev/null\", { throws: false });\n } else if (platform.os === \"darwin\") {\n await exec(\"brew services start redis\", { throws: false });\n }\n}\n\nasync function installRedis(platform: Platform): Promise<{ redisUrl: string }> {\n console.log(`\\n Installing Redis...`);\n\n if (platform.packageManager === \"apt\") {\n await exec(\"sudo apt-get install -y redis-server\");\n await exec(\"sudo systemctl enable redis-server\");\n await exec(\"sudo systemctl start redis-server\");\n } else if (platform.packageManager === \"brew\") {\n await exec(\"brew install redis\");\n await exec(\"brew services start redis\");\n } else if (platform.packageManager === \"dnf\") {\n await exec(\"sudo dnf install -y redis\");\n await exec(\"sudo systemctl enable redis\");\n await exec(\"sudo systemctl start redis\");\n } else {\n console.log(` ${colors.yellow}Unsupported package manager. Please install Redis manually.${colors.reset}`);\n return { redisUrl: \"redis://localhost:6379\" };\n }\n\n // Configure Redis for BullMQ (noeviction policy)\n await exec('redis-cli CONFIG SET maxmemory-policy noeviction 2>/dev/null', { throws: false });\n\n console.log(` ${colors.green}Redis installed.${colors.reset}`);\n return { redisUrl: \"redis://localhost:6379\" };\n}\n\n// ── Database Migrations ──────────────────────────────────────────────────────\n\nasync function runMigrations(databaseUrl: string) {\n console.log(` Running database migrations...`);\n\n try {\n const migrationsDir = getMigrationsDir();\n if (!existsSync(migrationsDir)) {\n console.log(` ${colors.yellow}Migrations folder not found at ${migrationsDir}. Skipping.${colors.reset}`);\n return;\n }\n\n // Use dynamic imports to load database modules\n const { default: postgres } = await import(\"postgres\");\n const { drizzle } = await import(\"drizzle-orm/postgres-js\");\n const { migrate } = await import(\"drizzle-orm/postgres-js/migrator\");\n\n const client = postgres(databaseUrl, { max: 1 });\n const db = drizzle(client);\n\n // Enable pgvector extension\n await client`CREATE EXTENSION IF NOT EXISTS vector`;\n\n await migrate(db, { migrationsFolder: migrationsDir });\n\n await client.end();\n console.log(` ${colors.green}Migrations complete.${colors.reset}`);\n } catch (err: any) {\n console.log(` ${colors.yellow}Migration warning: ${err.message}${colors.reset}`);\n console.log(` ${colors.dim}You can run migrations later with: opensentinel start${colors.reset}`);\n }\n}\n\n// ── Daemon Setup ─────────────────────────────────────────────────────────────\n\nasync function setupDaemon(platform: Platform, configDir: string) {\n const installDaemon = await confirm(\" Install as system service (auto-start on boot)?\");\n if (!installDaemon) {\n console.log(` ${colors.dim}Skipped. Run manually with: opensentinel start${colors.reset}`);\n return;\n }\n\n if (platform.os === \"linux\") {\n await setupSystemd(configDir);\n } else if (platform.os === \"darwin\") {\n await setupLaunchd(configDir);\n } else {\n console.log(` ${colors.yellow}Daemon setup not supported on this platform. Run manually with: opensentinel start${colors.reset}`);\n }\n}\n\nasync function setupSystemd(configDir: string) {\n const bunPath = await which(\"bun\") || \"/usr/local/bin/bun\";\n const opensentinelPath = await which(\"opensentinel\") || `${bunPath} ${join(getPackageRoot(), \"dist\", \"cli.js\")}`;\n const user = process.env.USER || \"root\";\n\n const unit = `[Unit]\nDescription=OpenSentinel AI Assistant\nAfter=network.target postgresql.service redis-server.service\nWants=postgresql.service redis-server.service\n\n[Service]\nType=simple\nUser=${user}\nWorkingDirectory=${configDir}\nEnvironmentFile=${configDir}/.env\nExecStart=${opensentinelPath} start\nRestart=on-failure\nRestartSec=5\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=opensentinel\n\n[Install]\nWantedBy=multi-user.target\n`;\n\n const unitPath = \"/etc/systemd/system/opensentinel.service\";\n writeFileSync(\"/tmp/opensentinel.service\", unit);\n await exec(`sudo cp /tmp/opensentinel.service ${unitPath}`);\n await exec(\"sudo systemctl daemon-reload\");\n await exec(\"sudo systemctl enable opensentinel\");\n\n console.log(` ${colors.green}Systemd service installed.${colors.reset}`);\n console.log(` ${colors.dim}Unit file: ${unitPath}${colors.reset}`);\n\n const startNow = await confirm(\" Start OpenSentinel now?\");\n if (startNow) {\n await exec(\"sudo systemctl start opensentinel\");\n console.log(` ${colors.green}Service started!${colors.reset}`);\n console.log(` ${colors.dim}Logs: journalctl -u opensentinel -f${colors.reset}`);\n }\n}\n\nasync function setupLaunchd(configDir: string) {\n const opensentinelPath = await which(\"opensentinel\") || join(getPackageRoot(), \"dist\", \"cli.js\");\n\n const logsDir = join(configDir, \"logs\");\n if (!existsSync(logsDir)) {\n const { mkdirSync } = await import(\"node:fs\");\n mkdirSync(logsDir, { recursive: true });\n }\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>ai.opensentinel.daemon</string>\n <key>ProgramArguments</key>\n <array>\n <string>${opensentinelPath}</string>\n <string>start</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${configDir}</string>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${logsDir}/opensentinel.log</string>\n <key>StandardErrorPath</key>\n <string>${logsDir}/opensentinel-error.log</string>\n</dict>\n</plist>`;\n\n const plistPath = join(homedir(), \"Library\", \"LaunchAgents\", \"ai.opensentinel.daemon.plist\");\n writeFileSync(plistPath, plist);\n\n console.log(` ${colors.green}LaunchAgent installed.${colors.reset}`);\n console.log(` ${colors.dim}Plist: ${plistPath}${colors.reset}`);\n\n const startNow = await confirm(\" Start OpenSentinel now?\");\n if (startNow) {\n await exec(`launchctl load ${plistPath}`);\n console.log(` ${colors.green}Service started!${colors.reset}`);\n console.log(` ${colors.dim}Logs: tail -f ${logsDir}/opensentinel.log${colors.reset}`);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * OpenSentinel Start Command
3
+ *
4
+ * Loads environment, starts all services, and handles graceful shutdown.
5
+ */
6
+ declare function start(): Promise<void>;
7
+
8
+ export { start as default };
@@ -0,0 +1,27 @@
1
+ import {
2
+ loadEnvFile
3
+ } from "../chunk-GUBEEYDW.js";
4
+ import "../chunk-NSBPE2FW.js";
5
+
6
+ // src/commands/start.ts
7
+ async function start() {
8
+ const envFile = loadEnvFile();
9
+ if (envFile) {
10
+ console.log(`[Config] Loaded ${envFile}`);
11
+ }
12
+ process.env.__OPENSENTINEL_CLI__ = "1";
13
+ const { main } = await import("../src-K7GASHRH.js");
14
+ const shutdown = await main();
15
+ process.on("SIGINT", async () => {
16
+ await shutdown();
17
+ process.exit(0);
18
+ });
19
+ process.on("SIGTERM", async () => {
20
+ await shutdown();
21
+ process.exit(0);
22
+ });
23
+ }
24
+ export {
25
+ start as default
26
+ };
27
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/start.ts"],"sourcesContent":["/**\n * OpenSentinel Start Command\n *\n * Loads environment, starts all services, and handles graceful shutdown.\n */\n\nimport { loadEnvFile } from \"./utils\";\n\nexport default async function start() {\n // Load .env from config directory chain\n const envFile = loadEnvFile();\n if (envFile) {\n console.log(`[Config] Loaded ${envFile}`);\n }\n\n // Mark as CLI so env validation throws on missing required vars\n process.env.__OPENSENTINEL_CLI__ = \"1\";\n\n const { main } = await import(\"../index\");\n\n const shutdown = await main();\n\n // Wire up graceful shutdown\n process.on(\"SIGINT\", async () => {\n await shutdown();\n process.exit(0);\n });\n process.on(\"SIGTERM\", async () => {\n await shutdown();\n process.exit(0);\n });\n}\n"],"mappings":";;;;;;AAQA,eAAO,QAA+B;AAEpC,QAAM,UAAU,YAAY;AAC5B,MAAI,SAAS;AACX,YAAQ,IAAI,mBAAmB,OAAO,EAAE;AAAA,EAC1C;AAGA,UAAQ,IAAI,uBAAuB;AAEnC,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,oBAAU;AAExC,QAAM,WAAW,MAAM,KAAK;AAG5B,UAAQ,GAAG,UAAU,YAAY;AAC/B,UAAM,SAAS;AACf,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACD,UAAQ,GAAG,WAAW,YAAY;AAChC,UAAM,SAAS;AACf,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":[]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * OpenSentinel Status Command
3
+ *
4
+ * Shows service health, database connectivity, and configuration info.
5
+ */
6
+ declare function status(): Promise<void>;
7
+
8
+ export { status as default };
@@ -0,0 +1,57 @@
1
+ import {
2
+ checkPostgres,
3
+ checkRedis,
4
+ colors,
5
+ exec,
6
+ getConfigDir,
7
+ printBanner
8
+ } from "../chunk-GUBEEYDW.js";
9
+ import "../chunk-NSBPE2FW.js";
10
+
11
+ // src/commands/status.ts
12
+ import { existsSync } from "fs";
13
+ import { join } from "path";
14
+ async function status() {
15
+ printBanner();
16
+ const platform = process.platform;
17
+ const configDir = getConfigDir();
18
+ let serviceStatus = "unknown";
19
+ if (platform === "linux") {
20
+ const result = await exec("systemctl is-active opensentinel 2>/dev/null", { throws: false });
21
+ serviceStatus = result.stdout.trim();
22
+ } else if (platform === "darwin") {
23
+ const result = await exec("launchctl list 2>/dev/null | grep opensentinel", { throws: false });
24
+ serviceStatus = result.exitCode === 0 ? "active" : "inactive";
25
+ }
26
+ const serviceIcon = serviceStatus === "active" ? colors.green : colors.red;
27
+ console.log(` Service: ${serviceIcon}${serviceStatus}${colors.reset}`);
28
+ const pg = await checkPostgres();
29
+ const pgIcon = pg.running ? colors.green : colors.red;
30
+ console.log(` PostgreSQL: ${pgIcon}${pg.running ? `running (port ${pg.port})` : "not reachable"}${colors.reset}`);
31
+ const redis = await checkRedis();
32
+ const redisIcon = redis.running ? colors.green : colors.red;
33
+ console.log(` Redis: ${redisIcon}${redis.running ? `running (port ${redis.port})` : "not reachable"}${colors.reset}`);
34
+ try {
35
+ const port = process.env.PORT || "8030";
36
+ const res = await fetch(`http://localhost:${port}/health`);
37
+ const data = await res.json();
38
+ console.log(` API: ${colors.green}healthy${colors.reset} (port ${port})`);
39
+ } catch {
40
+ console.log(` API: ${colors.red}not reachable${colors.reset}`);
41
+ }
42
+ const envPath = join(configDir, ".env");
43
+ const envExists = existsSync(envPath);
44
+ console.log(` Config: ${envExists ? colors.green + envPath : colors.yellow + "not found"}${colors.reset}`);
45
+ console.log("");
46
+ if (platform === "linux") {
47
+ console.log(` ${colors.dim}Logs: journalctl -u opensentinel -f${colors.reset}`);
48
+ } else if (platform === "darwin") {
49
+ const logPath = join(configDir, "logs", "opensentinel.log");
50
+ console.log(` ${colors.dim}Logs: tail -f ${logPath}${colors.reset}`);
51
+ }
52
+ console.log("");
53
+ }
54
+ export {
55
+ status as default
56
+ };
57
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/status.ts"],"sourcesContent":["/**\n * OpenSentinel Status Command\n *\n * Shows service health, database connectivity, and configuration info.\n */\n\nimport { exec, colors, printBanner, getConfigDir, checkPostgres, checkRedis } from \"./utils\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport default async function status() {\n printBanner();\n\n const platform = process.platform;\n const configDir = getConfigDir();\n\n // ── Service Status ──────────────────────────────────────────────────────\n\n let serviceStatus = \"unknown\";\n if (platform === \"linux\") {\n const result = await exec(\"systemctl is-active opensentinel 2>/dev/null\", { throws: false });\n serviceStatus = result.stdout.trim();\n } else if (platform === \"darwin\") {\n const result = await exec(\"launchctl list 2>/dev/null | grep opensentinel\", { throws: false });\n serviceStatus = result.exitCode === 0 ? \"active\" : \"inactive\";\n }\n\n const serviceIcon = serviceStatus === \"active\" ? colors.green : colors.red;\n console.log(` Service: ${serviceIcon}${serviceStatus}${colors.reset}`);\n\n // ── PostgreSQL ──────────────────────────────────────────────────────────\n\n const pg = await checkPostgres();\n const pgIcon = pg.running ? colors.green : colors.red;\n console.log(` PostgreSQL: ${pgIcon}${pg.running ? `running (port ${pg.port})` : \"not reachable\"}${colors.reset}`);\n\n // ── Redis ───────────────────────────────────────────────────────────────\n\n const redis = await checkRedis();\n const redisIcon = redis.running ? colors.green : colors.red;\n console.log(` Redis: ${redisIcon}${redis.running ? `running (port ${redis.port})` : \"not reachable\"}${colors.reset}`);\n\n // ── API Health ──────────────────────────────────────────────────────────\n\n try {\n const port = process.env.PORT || \"8030\";\n const res = await fetch(`http://localhost:${port}/health`);\n const data = await res.json() as any;\n console.log(` API: ${colors.green}healthy${colors.reset} (port ${port})`);\n } catch {\n console.log(` API: ${colors.red}not reachable${colors.reset}`);\n }\n\n // ── Config ──────────────────────────────────────────────────────────────\n\n const envPath = join(configDir, \".env\");\n const envExists = existsSync(envPath);\n console.log(` Config: ${envExists ? colors.green + envPath : colors.yellow + \"not found\"}${colors.reset}`);\n\n // ── Logs Hint ───────────────────────────────────────────────────────────\n\n console.log(\"\");\n if (platform === \"linux\") {\n console.log(` ${colors.dim}Logs: journalctl -u opensentinel -f${colors.reset}`);\n } else if (platform === \"darwin\") {\n const logPath = join(configDir, \"logs\", \"opensentinel.log\");\n console.log(` ${colors.dim}Logs: tail -f ${logPath}${colors.reset}`);\n }\n console.log(\"\");\n}\n"],"mappings":";;;;;;;;;;;AAOA,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AAGrB,eAAO,SAAgC;AACrC,cAAY;AAEZ,QAAM,WAAW,QAAQ;AACzB,QAAM,YAAY,aAAa;AAI/B,MAAI,gBAAgB;AACpB,MAAI,aAAa,SAAS;AACxB,UAAM,SAAS,MAAM,KAAK,gDAAgD,EAAE,QAAQ,MAAM,CAAC;AAC3F,oBAAgB,OAAO,OAAO,KAAK;AAAA,EACrC,WAAW,aAAa,UAAU;AAChC,UAAM,SAAS,MAAM,KAAK,kDAAkD,EAAE,QAAQ,MAAM,CAAC;AAC7F,oBAAgB,OAAO,aAAa,IAAI,WAAW;AAAA,EACrD;AAEA,QAAM,cAAc,kBAAkB,WAAW,OAAO,QAAQ,OAAO;AACvE,UAAQ,IAAI,mBAAmB,WAAW,GAAG,aAAa,GAAG,OAAO,KAAK,EAAE;AAI3E,QAAM,KAAK,MAAM,cAAc;AAC/B,QAAM,SAAS,GAAG,UAAU,OAAO,QAAQ,OAAO;AAClD,UAAQ,IAAI,mBAAmB,MAAM,GAAG,GAAG,UAAU,iBAAiB,GAAG,IAAI,MAAM,eAAe,GAAG,OAAO,KAAK,EAAE;AAInH,QAAM,QAAQ,MAAM,WAAW;AAC/B,QAAM,YAAY,MAAM,UAAU,OAAO,QAAQ,OAAO;AACxD,UAAQ,IAAI,mBAAmB,SAAS,GAAG,MAAM,UAAU,iBAAiB,MAAM,IAAI,MAAM,eAAe,GAAG,OAAO,KAAK,EAAE;AAI5H,MAAI;AACF,UAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,UAAM,MAAM,MAAM,MAAM,oBAAoB,IAAI,SAAS;AACzD,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,YAAQ,IAAI,mBAAmB,OAAO,KAAK,UAAU,OAAO,KAAK,UAAU,IAAI,GAAG;AAAA,EACpF,QAAQ;AACN,YAAQ,IAAI,mBAAmB,OAAO,GAAG,gBAAgB,OAAO,KAAK,EAAE;AAAA,EACzE;AAIA,QAAM,UAAU,KAAK,WAAW,MAAM;AACtC,QAAM,YAAY,WAAW,OAAO;AACpC,UAAQ,IAAI,mBAAmB,YAAY,OAAO,QAAQ,UAAU,OAAO,SAAS,WAAW,GAAG,OAAO,KAAK,EAAE;AAIhH,UAAQ,IAAI,EAAE;AACd,MAAI,aAAa,SAAS;AACxB,YAAQ,IAAI,KAAK,OAAO,GAAG,sCAAsC,OAAO,KAAK,EAAE;AAAA,EACjF,WAAW,aAAa,UAAU;AAChC,UAAM,UAAU,KAAK,WAAW,QAAQ,kBAAkB;AAC1D,YAAQ,IAAI,KAAK,OAAO,GAAG,iBAAiB,OAAO,GAAG,OAAO,KAAK,EAAE;AAAA,EACtE;AACA,UAAQ,IAAI,EAAE;AAChB;","names":[]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * OpenSentinel Stop Command
3
+ *
4
+ * Stops the system service.
5
+ */
6
+ declare function stop(): Promise<void>;
7
+
8
+ export { stop as default };
@@ -0,0 +1,37 @@
1
+ import {
2
+ colors,
3
+ exec
4
+ } from "../chunk-GUBEEYDW.js";
5
+ import "../chunk-NSBPE2FW.js";
6
+
7
+ // src/commands/stop.ts
8
+ import { homedir } from "os";
9
+ import { join } from "path";
10
+ async function stop() {
11
+ const platform = process.platform;
12
+ if (platform === "linux") {
13
+ const result = await exec("sudo systemctl stop opensentinel", { throws: false });
14
+ if (result.exitCode === 0) {
15
+ console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);
16
+ } else {
17
+ await exec("pkill -f 'opensentinel start' 2>/dev/null || pkill -f 'bun.*cli.ts' 2>/dev/null", { throws: false });
18
+ console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);
19
+ }
20
+ } else if (platform === "darwin") {
21
+ const plistPath = join(homedir(), "Library", "LaunchAgents", "ai.opensentinel.daemon.plist");
22
+ const result = await exec(`launchctl unload ${plistPath} 2>/dev/null`, { throws: false });
23
+ if (result.exitCode === 0) {
24
+ console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);
25
+ } else {
26
+ await exec("pkill -f 'opensentinel start' 2>/dev/null", { throws: false });
27
+ console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);
28
+ }
29
+ } else {
30
+ await exec("pkill -f 'opensentinel start' 2>/dev/null || pkill -f 'bun.*cli.ts' 2>/dev/null", { throws: false });
31
+ console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);
32
+ }
33
+ }
34
+ export {
35
+ stop as default
36
+ };
37
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/commands/stop.ts"],"sourcesContent":["/**\n * OpenSentinel Stop Command\n *\n * Stops the system service.\n */\n\nimport { exec, colors } from \"./utils\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport default async function stop() {\n const platform = process.platform;\n\n if (platform === \"linux\") {\n const result = await exec(\"sudo systemctl stop opensentinel\", { throws: false });\n if (result.exitCode === 0) {\n console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);\n } else {\n // Try killing the process directly\n await exec(\"pkill -f 'opensentinel start' 2>/dev/null || pkill -f 'bun.*cli.ts' 2>/dev/null\", { throws: false });\n console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);\n }\n } else if (platform === \"darwin\") {\n const plistPath = join(homedir(), \"Library\", \"LaunchAgents\", \"ai.opensentinel.daemon.plist\");\n const result = await exec(`launchctl unload ${plistPath} 2>/dev/null`, { throws: false });\n if (result.exitCode === 0) {\n console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);\n } else {\n await exec(\"pkill -f 'opensentinel start' 2>/dev/null\", { throws: false });\n console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);\n }\n } else {\n await exec(\"pkill -f 'opensentinel start' 2>/dev/null || pkill -f 'bun.*cli.ts' 2>/dev/null\", { throws: false });\n console.log(`${colors.green}OpenSentinel stopped.${colors.reset}`);\n }\n}\n"],"mappings":";;;;;;;AAOA,SAAS,eAAe;AACxB,SAAS,YAAY;AAErB,eAAO,OAA8B;AACnC,QAAM,WAAW,QAAQ;AAEzB,MAAI,aAAa,SAAS;AACxB,UAAM,SAAS,MAAM,KAAK,oCAAoC,EAAE,QAAQ,MAAM,CAAC;AAC/E,QAAI,OAAO,aAAa,GAAG;AACzB,cAAQ,IAAI,GAAG,OAAO,KAAK,wBAAwB,OAAO,KAAK,EAAE;AAAA,IACnE,OAAO;AAEL,YAAM,KAAK,mFAAmF,EAAE,QAAQ,MAAM,CAAC;AAC/G,cAAQ,IAAI,GAAG,OAAO,KAAK,wBAAwB,OAAO,KAAK,EAAE;AAAA,IACnE;AAAA,EACF,WAAW,aAAa,UAAU;AAChC,UAAM,YAAY,KAAK,QAAQ,GAAG,WAAW,gBAAgB,8BAA8B;AAC3F,UAAM,SAAS,MAAM,KAAK,oBAAoB,SAAS,gBAAgB,EAAE,QAAQ,MAAM,CAAC;AACxF,QAAI,OAAO,aAAa,GAAG;AACzB,cAAQ,IAAI,GAAG,OAAO,KAAK,wBAAwB,OAAO,KAAK,EAAE;AAAA,IACnE,OAAO;AACL,YAAM,KAAK,6CAA6C,EAAE,QAAQ,MAAM,CAAC;AACzE,cAAQ,IAAI,GAAG,OAAO,KAAK,wBAAwB,OAAO,KAAK,EAAE;AAAA,IACnE;AAAA,EACF,OAAO;AACL,UAAM,KAAK,mFAAmF,EAAE,QAAQ,MAAM,CAAC;AAC/G,YAAQ,IAAI,GAAG,OAAO,KAAK,wBAAwB,OAAO,KAAK,EAAE;AAAA,EACnE;AACF;","names":[]}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Shared CLI utilities for OpenSentinel commands.
3
+ */
4
+ declare const colors: {
5
+ reset: string;
6
+ bold: string;
7
+ dim: string;
8
+ green: string;
9
+ cyan: string;
10
+ yellow: string;
11
+ red: string;
12
+ magenta: string;
13
+ };
14
+ declare function prompt(question: string): Promise<string>;
15
+ declare function confirm(question: string, defaultYes?: boolean): Promise<boolean>;
16
+ declare function promptSecret(question: string): Promise<string>;
17
+ interface ExecResult {
18
+ stdout: string;
19
+ stderr: string;
20
+ exitCode: number;
21
+ }
22
+ declare function exec(cmd: string, opts?: {
23
+ throws?: boolean;
24
+ input?: string;
25
+ }): Promise<ExecResult>;
26
+ declare function which(binary: string): Promise<string | null>;
27
+ interface Platform {
28
+ os: "linux" | "darwin" | "other";
29
+ distro: string;
30
+ packageManager: "apt" | "brew" | "dnf" | "pacman" | "unknown";
31
+ }
32
+ declare function detectPlatform(): Platform;
33
+ declare function getConfigDir(): string;
34
+ declare function getPackageRoot(): string;
35
+ declare function getMigrationsDir(): string;
36
+ declare function checkPort(port: number): Promise<boolean>;
37
+ declare function checkPostgres(): Promise<{
38
+ installed: boolean;
39
+ running: boolean;
40
+ port: number;
41
+ }>;
42
+ declare function checkRedis(): Promise<{
43
+ installed: boolean;
44
+ running: boolean;
45
+ port: number;
46
+ }>;
47
+ declare function printBanner(): void;
48
+ declare function loadEnvFile(): string | null;
49
+
50
+ export { type ExecResult, type Platform, checkPort, checkPostgres, checkRedis, colors, confirm, detectPlatform, exec, getConfigDir, getMigrationsDir, getPackageRoot, loadEnvFile, printBanner, prompt, promptSecret, which };
@@ -0,0 +1,36 @@
1
+ import {
2
+ checkPort,
3
+ checkPostgres,
4
+ checkRedis,
5
+ colors,
6
+ confirm,
7
+ detectPlatform,
8
+ exec,
9
+ getConfigDir,
10
+ getMigrationsDir,
11
+ getPackageRoot,
12
+ loadEnvFile,
13
+ printBanner,
14
+ prompt,
15
+ promptSecret,
16
+ which
17
+ } from "../chunk-GUBEEYDW.js";
18
+ import "../chunk-NSBPE2FW.js";
19
+ export {
20
+ checkPort,
21
+ checkPostgres,
22
+ checkRedis,
23
+ colors,
24
+ confirm,
25
+ detectPlatform,
26
+ exec,
27
+ getConfigDir,
28
+ getMigrationsDir,
29
+ getPackageRoot,
30
+ loadEnvFile,
31
+ printBanner,
32
+ prompt,
33
+ promptSecret,
34
+ which
35
+ };
36
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,49 @@
1
+ import {
2
+ DiscordBot,
3
+ addToSession,
4
+ askCommand,
5
+ chatCommand,
6
+ clearCommand,
7
+ clearSession,
8
+ createDiscordBot,
9
+ discord_default,
10
+ getCommand,
11
+ getCommandData,
12
+ getSession,
13
+ helpCommand,
14
+ remindCommand,
15
+ sessions,
16
+ slashCommands,
17
+ splitMessage,
18
+ statusCommand,
19
+ voiceCommand
20
+ } from "./chunk-HH2HBTQM.js";
21
+ import "./chunk-F6QUZQGI.js";
22
+ import "./chunk-GVJVEWHI.js";
23
+ import "./chunk-4LVWXUNC.js";
24
+ import "./chunk-CI6Q63MM.js";
25
+ import "./chunk-4TG2IG5K.js";
26
+ import "./chunk-CQ4JURG7.js";
27
+ import "./chunk-L3F43VPB.js";
28
+ import "./chunk-NSBPE2FW.js";
29
+ export {
30
+ DiscordBot,
31
+ addToSession,
32
+ askCommand,
33
+ chatCommand,
34
+ clearCommand,
35
+ clearSession,
36
+ createDiscordBot,
37
+ discord_default as default,
38
+ getCommand,
39
+ getCommandData,
40
+ getSession,
41
+ helpCommand,
42
+ remindCommand,
43
+ sessions,
44
+ slashCommands,
45
+ splitMessage,
46
+ statusCommand,
47
+ voiceCommand
48
+ };
49
+ //# sourceMappingURL=discord-ZOJFTVTB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,14 @@
1
+ import {
2
+ iMessageBot,
3
+ imessage_default
4
+ } from "./chunk-GK3E2I7A.js";
5
+ import "./chunk-CI6Q63MM.js";
6
+ import "./chunk-4TG2IG5K.js";
7
+ import "./chunk-CQ4JURG7.js";
8
+ import "./chunk-L3F43VPB.js";
9
+ import "./chunk-NSBPE2FW.js";
10
+ export {
11
+ imessage_default as default,
12
+ iMessageBot
13
+ };
14
+ //# sourceMappingURL=imessage-JFRB6EJ7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}