agent-window 1.4.1 → 1.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-window",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "A window to interact with AI agents through chat interfaces. Simplified interaction, powerful backend capabilities.",
5
5
  "type": "module",
6
6
  "main": "src/bot.js",
@@ -11,6 +11,8 @@
11
11
  "ui": "node bin/cli.js ui",
12
12
  "ui:dev": "cd web && npm run dev",
13
13
  "ui:build": "cd web && npm run build",
14
+ "cleanup-pm2": "bash scripts/cleanup-pm2.sh",
15
+ "check-node": "node -e \"const v=process.version; const n=parseInt(v.slice(1)); if(n>=23){console.error('⚠️ Node.js',v,'not supported. Use v18 or v20 LTS.'); process.exit(1);}else{console.log('✓ Node.js',v,'is supported');}\"",
14
16
  "pm2:start": "pm2 start ecosystem.config.cjs",
15
17
  "pm2:stop": "pm2 stop bot-corp",
16
18
  "pm2:restart": "pm2 restart bot-corp",
@@ -26,7 +28,8 @@
26
28
  "author": "",
27
29
  "license": "MIT",
28
30
  "engines": {
29
- "node": ">=18.0.0"
31
+ "node": ">=18.0.0 <23.0.0",
32
+ "npm": ">=9.0.0"
30
33
  },
31
34
  "dependencies": {
32
35
  "@fastify/static": "^6.0.0",
@@ -0,0 +1,130 @@
1
+ #!/bin/bash
2
+ # PM2 Deep Cleanup Script
3
+ # AgentWindow Multi-Instance Bug Recovery Tool
4
+ #
5
+ # This script cleans up:
6
+ # - Multiple PM2 God Daemon processes (200+ leaked instances)
7
+ # - Orphaned bot processes
8
+ # - Stale PM2 dump files
9
+ # - Duplicate instances
10
+
11
+ set -e
12
+
13
+ echo "🧹 PM2 Deep Cleanup Script"
14
+ echo "======================================"
15
+ echo ""
16
+
17
+ # Color codes for output
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ NC='\033[0m' # No Color
22
+
23
+ # Step 1: Check PM2 processes before cleanup
24
+ echo "[1/7] Analyzing current state..."
25
+ echo "-----------------------------------"
26
+
27
+ PM2_COUNT=$(pgrep -f "PM2.*God Daemon" | wc -l | tr -d ' ' || echo "0")
28
+ BOT_COUNT=$(ps aux | grep "node.*bot.js" | grep -v grep | wc -l | tr -d ' ' || echo "0")
29
+
30
+ echo -e "PM2 God Daemons: ${YELLOW}${PM2_COUNT}${NC}"
31
+ echo -e "Bot processes: ${YELLOW}${BOT_COUNT}${NC}"
32
+ echo ""
33
+
34
+ if [ "$PM2_COUNT" -lt 5 ] && [ "$BOT_COUNT" -lt 3 ]; then
35
+ echo -e "${GREEN}✓ System appears clean (no major issues detected)${NC}"
36
+ echo ""
37
+ read -p "Continue cleanup anyway? (y/N): " -n 1 -r
38
+ echo
39
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
40
+ echo "Cleanup cancelled."
41
+ exit 0
42
+ fi
43
+ fi
44
+
45
+ # Step 2: Stop all PM2 apps
46
+ echo "[2/7] Stopping all PM2 apps..."
47
+ echo "-----------------------------------"
48
+ if command -v pm2 &> /dev/null; then
49
+ pm2 stop all 2>/dev/null || echo " No apps to stop"
50
+ pm2 delete all 2>/dev/null || echo " No apps to delete"
51
+ echo -e "${GREEN}✓ PM2 apps stopped${NC}"
52
+ else
53
+ echo -e "${YELLOW}⚠ PM2 not found, skipping...${NC}"
54
+ fi
55
+ echo ""
56
+
57
+ # Step 3: Kill PM2 daemon
58
+ echo "[3/7] Killing PM2 daemon..."
59
+ echo "-----------------------------------"
60
+ if command -v pm2 &> /dev/null; then
61
+ pm2 kill 2>/dev/null || echo " Daemon already stopped"
62
+ echo -e "${GREEN}✓ PM2 daemon killed${NC}"
63
+ else
64
+ echo -e "${YELLOW}⚠ PM2 not found, skipping...${NC}"
65
+ fi
66
+ echo ""
67
+
68
+ # Step 4: Kill remaining PM2 God processes
69
+ echo "[4/7] Cleaning up PM2 God processes..."
70
+ echo "-----------------------------------"
71
+ PM2_PIDS=$(pgrep -f "PM2.*God Daemon" || true)
72
+ if [ -n "$PM2_PIDS" ]; then
73
+ echo "$PM2_PIDS" | xargs -I {} kill -9 {} 2>/dev/null || true
74
+ echo -e "${GREEN}✓ Killed PM2 God processes${NC}"
75
+ else
76
+ echo -e "${GREEN}✓ No PM2 God processes found${NC}"
77
+ fi
78
+ echo ""
79
+
80
+ # Step 5: Remove dump file
81
+ echo "[5/7] Removing PM2 dump file..."
82
+ echo "-----------------------------------"
83
+ DUMP_FILE="$HOME/.pm2/dump.pm2"
84
+ if [ -f "$DUMP_FILE" ]; then
85
+ rm -f "$DUMP_FILE"
86
+ echo -e "${GREEN}✓ Removed dump file${NC}"
87
+ else
88
+ echo -e "${GREEN}✓ No dump file found${NC}"
89
+ fi
90
+ echo ""
91
+
92
+ # Step 6: Kill orphaned bot processes
93
+ echo "[6/7] Cleaning up orphaned bot processes..."
94
+ echo "-----------------------------------"
95
+ BOT_PIDS=$(ps aux | grep "node.*bot.js" | grep -v grep | awk '{print $2}' || true)
96
+ if [ -n "$BOT_PIDS" ]; then
97
+ echo "$BOT_PIDS" | xargs -I {} kill -9 {} 2>/dev/null || true
98
+ echo -e "${GREEN}✓ Killed orphaned bot processes${NC}"
99
+ else
100
+ echo -e "${GREEN}✓ No orphaned bot processes found${NC}"
101
+ fi
102
+ echo ""
103
+
104
+ # Step 7: Verification
105
+ echo "[7/7] Verification..."
106
+ echo "-----------------------------------"
107
+ sleep 1
108
+
109
+ FINAL_PM2_COUNT=$(pgrep -f "PM2.*God Daemon" | wc -l | tr -d ' ' || echo "0")
110
+ FINAL_BOT_COUNT=$(ps aux | grep "node.*bot.js" | grep -v grep | wc -l | tr -d ' ' || echo "0")
111
+
112
+ echo -e "PM2 God Daemons: ${GREEN}${FINAL_PM2_COUNT}${NC} (was ${PM2_COUNT})"
113
+ echo -e "Bot processes: ${GREEN}${FINAL_BOT_COUNT}${NC} (was ${BOT_COUNT})"
114
+ echo ""
115
+
116
+ if [ "$FINAL_PM2_COUNT" -eq 0 ] && [ "$FINAL_BOT_COUNT" -eq 0 ]; then
117
+ echo -e "${GREEN}✅ Cleanup complete! System is clean.${NC}"
118
+ echo ""
119
+ echo "Next steps:"
120
+ echo " 1. Start your bot: pm2 start ecosystem.config.cjs"
121
+ echo " 2. Verify: pm2 list"
122
+ echo " 3. Check logs: pm2 logs --lines 20"
123
+ else
124
+ echo -e "${YELLOW}⚠️ Some processes still running. You may need to:${NC}"
125
+ echo " - Check manually: ps aux | grep bot.js"
126
+ echo " - Kill manually: kill -9 <PID>"
127
+ echo " - Restart terminal/daemon"
128
+ fi
129
+ echo ""
130
+ echo "======================================"
package/src/bot.js CHANGED
@@ -24,8 +24,6 @@ import { spawn, execSync } from 'child_process';
24
24
  import { readFileSync, writeFileSync, existsSync, readdirSync, unlinkSync, mkdirSync, chmodSync } from 'fs';
25
25
  import { join } from 'path';
26
26
  import { homedir } from 'os';
27
- import { https } from 'https';
28
- import { http } from 'http';
29
27
  import { createWriteStream } from 'fs';
30
28
 
31
29
  // Import performance monitoring utilities (local)
@@ -41,6 +39,33 @@ import {
41
39
  // Import centralized configuration (local, project-specific)
42
40
  import config from './core/config.js';
43
41
 
42
+ // ============================================================================
43
+ // CRITICAL: Check Node.js version compatibility
44
+ // ============================================================================
45
+ const NODE_VERSION = process.version;
46
+ const NODE_MAJOR = parseInt(NODE_VERSION.slice(1).split('.')[0]);
47
+
48
+ if (NODE_MAJOR >= 23) {
49
+ console.error('\n' + '='.repeat(70));
50
+ console.error('⚠️ CRITICAL: Node.js v23+ is not compatible with AgentWindow!');
51
+ console.error('='.repeat(70));
52
+ console.error(`Current version: ${NODE_VERSION}`);
53
+ console.error('Supported versions: Node.js v18 LTS or v20 LTS');
54
+ console.error('\n❌ Issues with Node.js v23:');
55
+ console.error(' - ES module import syntax incompatibility');
56
+ console.error(' - Potential runtime errors with Discord.js');
57
+ console.error(' - Breaking changes in core modules');
58
+ console.error('\n✅ Recommended actions:');
59
+ console.error(' 1. Install Node.js v20 LTS (recommended)');
60
+ console.error(' Using nvm: nvm install 20 && nvm use 20');
61
+ console.error(' Using Homebrew: brew install node@20');
62
+ console.error(' 2. Reinstall global packages: npm install -g agent-window');
63
+ console.error(' 3. Restart your bots');
64
+ console.error('\n📖 See: https://nodejs.org/en/download/releases');
65
+ console.error('='.repeat(70) + '\n');
66
+ process.exit(1);
67
+ }
68
+
44
69
  // Extract commonly used config values for convenience
45
70
  const BOT_TOKEN = config.discord.token;
46
71
  const PROJECT_DIR = config.workspace.projectDir;
@@ -1850,11 +1875,52 @@ client.on(Events.MessageCreate, async (message) => {
1850
1875
 
1851
1876
  // Ready event
1852
1877
  client.on(Events.ClientReady, async () => {
1878
+ // ========================================================================
1879
+ // CRITICAL: Check for duplicate bot instances
1880
+ // ========================================================================
1881
+ try {
1882
+ const { execSync } = await import('child_process');
1883
+ const psCommand = process.platform === 'win32'
1884
+ ? 'tasklist | findstr node.exe'
1885
+ : 'ps aux | grep "node.*bot.js" | grep -v grep';
1886
+
1887
+ const result = execSync(psCommand, { encoding: 'utf-8', timeout: 5000 });
1888
+ const botProcesses = result.split('\n').filter(line => line.trim() && line.includes('bot.js'));
1889
+
1890
+ if (botProcesses.length > 1) {
1891
+ console.error('\n' + '='.repeat(70));
1892
+ console.error('⚠️ CRITICAL WARNING: Multiple bot instances detected!');
1893
+ console.error('='.repeat(70));
1894
+ console.error(`Found ${botProcesses.length} bot instances running concurrently.`);
1895
+ console.error('This will cause duplicate responses to every message!');
1896
+ console.error('\n🔍 Running instances:');
1897
+ botProcesses.forEach((proc, i) => {
1898
+ console.error(` ${i + 1}. ${proc.trim()}`);
1899
+ });
1900
+ console.error('\n🔧 To fix this issue:');
1901
+ console.error(' 1. Check running PM2 processes: pm2 list');
1902
+ console.error(' 2. Stop all bots: pm2 stop all && pm2 delete all');
1903
+ console.error(' 3. Kill PM2 daemon: pm2 kill');
1904
+ console.error(' 4. Kill all bot processes: pkill -9 -f "node.*bot.js"');
1905
+ console.error(' 5. Clean dump file: rm -f ~/.pm2/dump.pm2');
1906
+ console.error(' 6. Restart single instance: pm2 start ecosystem.config.cjs');
1907
+ console.error('\n📖 Or use the cleanup script: npm run cleanup-pm2');
1908
+ console.error('='.repeat(70) + '\n');
1909
+ } else {
1910
+ console.log('✓ Instance check: Single bot instance (good)');
1911
+ }
1912
+ } catch (e) {
1913
+ // Command failed (likely no other instances or platform not supported)
1914
+ console.log('✓ Instance check: Passed');
1915
+ }
1916
+
1853
1917
  console.log(`AgentBridge logged in as ${client.user.tag}`);
1854
1918
  console.log(`Bot User ID: ${client.user.id}`);
1855
1919
  console.log(`Project: ${PROJECT_DIR}`);
1856
- console.log(`Mode: Docker Sandbox + Hooks Permission`);
1857
- console.log(`Container: ${CONTAINER_NAME}`);
1920
+ console.log(`Mode: ${USE_DOCKER ? 'Docker Sandbox' : 'Local Host'} + Hooks Permission`);
1921
+ if (USE_DOCKER) {
1922
+ console.log(`Container: ${CONTAINER_NAME}`);
1923
+ }
1858
1924
  console.log(`OAuth: ${OAUTH_TOKEN ? 'configured' : 'not set'}`);
1859
1925
 
1860
1926
  // Update PM2 and Discord health status