@mrtrinhvn/ag-kit 1.4.4 → 1.4.6
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/README.md +13 -0
- package/bin/cli.js +27 -7
- package/package.json +1 -1
- package/template/.agent/knowledge/ag-kit-ecosystem.md +15 -1
- package/template/.agent/scripts/receptionist_down.sh +11 -18
- package/template/.agent/scripts/receptionist_up.sh +26 -128
- package/template/.agent/scripts/port_utils.sh +0 -106
package/README.md
CHANGED
|
@@ -58,6 +58,19 @@ Gói `ag-kit` khuyến khích nguyên lý kết hợp 2 AI:
|
|
|
58
58
|
|
|
59
59
|
> Vui lòng tải model: `ollama pull nomic-embed-text` để kích hoạt tính năng Semantic Search của `ag-kit`.
|
|
60
60
|
|
|
61
|
+
## 🚀 Agentic Port Fusion (Cơ chế Hợp Thể Cổng)
|
|
62
|
+
|
|
63
|
+
AG-Kit sử dụng kỹ thuật **JSON Introspection** và **Chromium Multiplexing** để giải quyết vĩnh viễn bài toán đụng độ Cổng (Port) khi chạy nhiều Agent/IDE cùng lúc trên một máy:
|
|
64
|
+
|
|
65
|
+
1. **Lớp IDE (Cổng Trạm - `IDE_PORT`):**
|
|
66
|
+
- Mọi dự án có thể **dùng chung một cổng duy nhất (VD: 9555)**.
|
|
67
|
+
- `start.sh` sẽ tự động ping cổng 9555, dùng `curl` quét danh sách JSON (`/json/list`) xem dự án của mình đã mở chưa.
|
|
68
|
+
- Nếu chưa, nó ra lệnh cho Chrome tự động rẽ nhánh thêm một cửa sổ (Workspace) ngay trên cổng 9555 đó. Bot của dự án nào sẽ tự động bắt đúng UUID WebSocket của dự án đó! Chấm dứt cảnh spam Port làm rác cấu hình.
|
|
69
|
+
|
|
70
|
+
2. **Lớp Bot (Cổng Nội Bộ - `BRIDGE_PORT`):**
|
|
71
|
+
- Không thể xài chung do giới hạn của Node.js.
|
|
72
|
+
- Khi chạy lệnh `ag-kit init`, AG-Kit sẽ tự động săn tìm một cổng Bridge đang trống (từ 9656 trở lên) và cấp phát **độc quyền** cho dự án thông qua file `.env`.
|
|
73
|
+
|
|
61
74
|
---
|
|
62
75
|
|
|
63
76
|
## 🔄 Cập nhật & Bảo trì
|
package/bin/cli.js
CHANGED
|
@@ -247,28 +247,48 @@ program.command('status')
|
|
|
247
247
|
async function runInteractiveMenu() {
|
|
248
248
|
const inquirer = require('inquirer');
|
|
249
249
|
console.clear();
|
|
250
|
-
console.log('\x1b[35m\n🧠 AG-KIT - BẢNG ĐIỀU KHIỂN HỆ SINH THÁI AI\x1b[0m');
|
|
251
|
-
console.log('\x1b[34m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m');
|
|
252
250
|
|
|
253
251
|
const hasAgent = fs.existsSync(TARGET_AGENT_DIR);
|
|
254
252
|
const vPath = path.join(TARGET_AGENT_DIR, '.version');
|
|
255
253
|
let updateTag = '';
|
|
254
|
+
let hasUpdate = false;
|
|
255
|
+
let statusText = '\x1b[31mTrắng\x1b[0m';
|
|
256
|
+
|
|
256
257
|
if (hasAgent && fs.existsSync(vPath)) {
|
|
257
258
|
const installed = fs.readFileSync(vPath, 'utf-8').trim();
|
|
259
|
+
statusText = `\x1b[32mv${installed}\x1b[0m`;
|
|
258
260
|
if (installed !== pkg.version) {
|
|
259
|
-
updateTag = `\x1b[31m(
|
|
261
|
+
updateTag = `\x1b[31m(Cần lên v${pkg.version})\x1b[0m `;
|
|
262
|
+
hasUpdate = true;
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
|
|
263
|
-
|
|
266
|
+
let brainStatus = '\x1b[33mChưa quét\x1b[0m';
|
|
267
|
+
const brainPath = path.join(TARGET_AGENT_DIR, 'brain', 'summary.md');
|
|
268
|
+
if (hasAgent && fs.existsSync(brainPath)) {
|
|
269
|
+
brainStatus = '\x1b[32mĐã có não\x1b[0m';
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
console.log('\x1b[35m\n🧠 AG-KIT - BẢNG ĐIỀU KHIỂN HỆ SINH THÁI AI\x1b[0m');
|
|
273
|
+
console.log(` Lõi: ${statusText} | Nhận thức: ${brainStatus}`);
|
|
274
|
+
console.log('\x1b[34m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m');
|
|
275
|
+
|
|
276
|
+
const agentChoices = [
|
|
264
277
|
{ name: `🧠 Xây dựng / Cập nhật Bộ Não (build brain) - Thu thập Context`, value: 'brain' },
|
|
265
278
|
{ name: `🕸️ Khám phá Ký ức (memory) - Xem dữ liệu Vector`, value: 'memory' },
|
|
266
279
|
{ name: `🤖 Kiểm tra Agentic Gateway (gateway) - Test IDE/Bot`, value: 'gateway' },
|
|
267
|
-
|
|
268
|
-
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
if (hasUpdate) {
|
|
283
|
+
agentChoices.push({ name: `🔄 Nâng Cấp Kiến Thức (update) ${updateTag}`, value: 'update' });
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
agentChoices.push(
|
|
269
287
|
new inquirer.Separator(),
|
|
270
288
|
{ name: '❌ Thoát', value: 'exit' }
|
|
271
|
-
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
const choices = hasAgent ? agentChoices : [
|
|
272
292
|
{ name: '🚀 Khởi tạo (init) - Cấy ghép Tủy Não .agent vào thư mục này', value: 'init' },
|
|
273
293
|
new inquirer.Separator(),
|
|
274
294
|
{ name: '❌ Thoát', value: 'exit' }
|
package/package.json
CHANGED
|
@@ -141,7 +141,21 @@ Khi đang làm việc ở Project A và cần hiểu Project B:
|
|
|
141
141
|
|
|
142
142
|
---
|
|
143
143
|
|
|
144
|
-
## 8.
|
|
144
|
+
## 8. CƠ CHẾ PORT FUSION (Cấp phát động và Hợp thể)
|
|
145
|
+
|
|
146
|
+
Để giúp Agentic Server (Cầu nối) và Lõi Trí Tuệ (IDE Chromium) không dẫm chân lên nhau khi Owner chạy nhiềuvproject cùng lúc, hệ sinh thái sử dụng kiến trúc phân tầng Port:
|
|
147
|
+
|
|
148
|
+
- **`IDE_PORT` (Khuyến nghị dùng chung 9555)**:
|
|
149
|
+
Lớp hệ điều hành Chromium hỗ trợ **Multiplexing - Dùng chung Hub**, cho phép hàng chục dự án dùng chung 1 cổng mạng duy nhất. Script `start.sh` tích hợp "JSON X-Ray", tự động ping vào cổng 9555 để kiểm tra JSON API `/json/list` xem project của mình đã nạp chưa.
|
|
150
|
+
- Nếu có: Hệ thống tự trích xuất UUID (mấu WebSocket) và hợp thể.
|
|
151
|
+
- Nếu không: Nó ép tiến trình Chromium đang chạy rẽ thêm Workspace, tuyệt đối không spam port ảo.
|
|
152
|
+
|
|
153
|
+
- **`BRIDGE_PORT` (Cấp phát động từ 9656)**:
|
|
154
|
+
Lớp kết nối mạng nội bộ Node.js (phục vụ Gateway/Telegram) đòi hỏi giao thức **độc quyền**. Lệnh `ag-kit init` sẽ tự động săn một cổng rỗng trên hệ điều hành vật lý (9656++) và khắc tử vào trong file `.env` của project mới.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 9. KHỞI ĐỘNG PROJECT MỚI (Bootstrap Protocol)
|
|
145
159
|
|
|
146
160
|
Khi anh muốn thêm một project mới vào hệ sinh thái:
|
|
147
161
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
# --- Antigravity Unified Shutdown (
|
|
3
|
+
# --- Antigravity Unified Shutdown (Port Fusion Edition) ---
|
|
4
4
|
# Dọn dẹp trạm gác Agentic Gateway.
|
|
5
5
|
|
|
6
6
|
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
@@ -10,36 +10,29 @@ if [ -f .env ]; then
|
|
|
10
10
|
source .env
|
|
11
11
|
fi
|
|
12
12
|
|
|
13
|
-
BRIDGE_PORT=${BRIDGE_PORT:-
|
|
13
|
+
BRIDGE_PORT=${BRIDGE_PORT:-9656}
|
|
14
14
|
|
|
15
15
|
echo "════════════════════════════════════════════════════"
|
|
16
|
-
echo " 🛑
|
|
16
|
+
echo " 🛑 ĐANG TẮT AG GATEWAY [$BRIDGE_PORT]..."
|
|
17
17
|
echo "════════════════════════════════════════════════════"
|
|
18
18
|
|
|
19
|
-
# 1. Tắt
|
|
20
|
-
|
|
21
|
-
if [ -f "$SENTINEL_PID_FILE" ]; then
|
|
22
|
-
kill $(cat "$SENTINEL_PID_FILE") 2>/dev/null && rm "$SENTINEL_PID_FILE"
|
|
23
|
-
echo "✅ Sentinel stopped."
|
|
24
|
-
fi
|
|
25
|
-
|
|
26
|
-
# 2. Tắt Portal Bridge
|
|
27
|
-
BRIDGE_PID_FILE=".portal_bridge_${BRIDGE_PORT}.pid"
|
|
19
|
+
# 1. Tắt Portal Bridge
|
|
20
|
+
BRIDGE_PID_FILE=".agent/logs/.portal_bridge_${BRIDGE_PORT}.pid"
|
|
28
21
|
if [ -f "$BRIDGE_PID_FILE" ]; then
|
|
29
22
|
kill $(cat "$BRIDGE_PID_FILE") 2>/dev/null && rm "$BRIDGE_PID_FILE"
|
|
30
|
-
echo "✅ HUD Bridge
|
|
23
|
+
echo "✅ HUD Bridge đã tắt."
|
|
31
24
|
fi
|
|
32
25
|
|
|
33
|
-
#
|
|
34
|
-
BOT_PID_FILE=".ag_gateway_bot.pid"
|
|
26
|
+
# 2. Tắt Bot
|
|
27
|
+
BOT_PID_FILE=".agent/logs/.ag_gateway_bot.pid"
|
|
35
28
|
if [ -f "$BOT_PID_FILE" ]; then
|
|
36
29
|
PID=$(cat "$BOT_PID_FILE")
|
|
37
30
|
# Kill the whole process group for the bash loop
|
|
38
|
-
pkill -P $PID
|
|
31
|
+
pkill -P $PID 2>/dev/null
|
|
39
32
|
kill $PID 2>/dev/null && rm "$BOT_PID_FILE"
|
|
40
|
-
echo "✅
|
|
33
|
+
echo "✅ Bot Telegram đã tắt."
|
|
41
34
|
fi
|
|
42
35
|
|
|
43
36
|
echo "════════════════════════════════════════════════════"
|
|
44
|
-
echo "✅ AG GATEWAY
|
|
37
|
+
echo "✅ HỆ THỐNG AG GATEWAY ĐĐA NGỦ."
|
|
45
38
|
echo "════════════════════════════════════════════════════"
|
|
@@ -1,159 +1,57 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
# --- Antigravity Unified Receptionist (
|
|
3
|
+
# --- Antigravity Unified Receptionist (Port Fusion Edition) ---
|
|
4
4
|
# Trạm gác hợp nhất: AG Gateway Bot + Portal Bridge (HUD)
|
|
5
|
-
# Dự án: Template Agentic Orchestrator
|
|
6
5
|
|
|
7
|
-
# 1. Load Cấu hình & Xử lý Cổng Thông minh
|
|
8
6
|
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
9
7
|
cd "$PROJECT_DIR"
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
mkdir -p .agent/logs
|
|
10
|
+
|
|
11
|
+
# 1. Load Cấu hình Tĩnh từ .env
|
|
12
|
+
if [ -f .env ]; then
|
|
14
13
|
source .env
|
|
15
|
-
export IDE_PORT=${IDE_PORT:-9557}
|
|
16
|
-
export BRIDGE_PORT=${BRIDGE_PORT:-9658}
|
|
17
14
|
fi
|
|
18
15
|
|
|
16
|
+
export IDE_PORT=${IDE_PORT:-9555}
|
|
17
|
+
export BRIDGE_PORT=${BRIDGE_PORT:-9656}
|
|
18
|
+
|
|
19
19
|
echo "════════════════════════════════════════════════════"
|
|
20
|
-
echo " 🏢 AG GATEWAY -
|
|
20
|
+
echo " 🏢 AG GATEWAY - CẦU NỐI NỘI BỘ [$BRIDGE_PORT]"
|
|
21
21
|
echo "════════════════════════════════════════════════════"
|
|
22
22
|
|
|
23
|
-
# 2.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
for arg in "$@"; do
|
|
27
|
-
if [ "$arg" == "--headless" ]; then HEADLESS=true; fi
|
|
28
|
-
if [ "$arg" == "--tunnel" ]; then TUNNEL=true; fi
|
|
29
|
-
done
|
|
30
|
-
|
|
31
|
-
# 3. Kiểm tra/Khởi động IDE
|
|
32
|
-
echo -n "[2/4] 🛰️ Checking IDE Portal (Port $IDE_PORT)... "
|
|
33
|
-
if curl -s http://127.0.0.1:$IDE_PORT/json/version > /dev/null; then
|
|
34
|
-
echo "✅ READY."
|
|
35
|
-
if [ "$HEADLESS" != true ]; then
|
|
36
|
-
echo " 🔄 Attempting to wake/focus UI..."
|
|
37
|
-
# Cố gắng push UI lên (nếu đang ngầm)
|
|
38
|
-
antigravity "$PROJECT_DIR" > /dev/null 2>&1 &
|
|
39
|
-
|
|
40
|
-
if [ -t 0 ]; then
|
|
41
|
-
echo -n " 🤔 Did the IDE window appear? [Y/n] (Auto-yes in 5s): "
|
|
42
|
-
read -t 5 -n 1 user_input
|
|
43
|
-
echo ""
|
|
44
|
-
user_input=${user_input:-Y}
|
|
45
|
-
else
|
|
46
|
-
user_input="Y"
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
if [[ "$user_input" =~ ^[Nn]$ ]]; then
|
|
50
|
-
echo " 💀 UI Failed. Killing specific phantom instance for this project..."
|
|
51
|
-
# Chỉ kill những process chứa flag remote và project hiện tại
|
|
52
|
-
pkill -f "antigravity.*--remote-debugging-port=$IDE_PORT"
|
|
53
|
-
pkill -f "antigravity.*$PROJECT_DIR"
|
|
54
|
-
sleep 2
|
|
55
|
-
echo " 🚀 Launching fresh Antigravity with UI on port $IDE_PORT..."
|
|
56
|
-
nohup antigravity --remote-debugging-port=$IDE_PORT "$PROJECT_DIR" > /dev/null 2>&1 &
|
|
57
|
-
sleep 5
|
|
58
|
-
fi
|
|
59
|
-
fi
|
|
60
|
-
else
|
|
61
|
-
echo "❌ NOT FOUND."
|
|
62
|
-
if [ "$HEADLESS" = true ]; then
|
|
63
|
-
echo " 🚀 Launching Antigravity in HEADLESS mode on port $IDE_PORT..."
|
|
64
|
-
nohup antigravity --server --remote-debugging-port=$IDE_PORT "$PROJECT_DIR" > /dev/null 2>&1 &
|
|
65
|
-
else
|
|
66
|
-
echo " 🚀 Launching Antigravity with UI on port $IDE_PORT..."
|
|
67
|
-
nohup antigravity --remote-debugging-port=$IDE_PORT "$PROJECT_DIR" > /dev/null 2>&1 &
|
|
68
|
-
fi
|
|
69
|
-
sleep 5
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
# 4. Cloudflare Tunnel & QR Code (If requested)
|
|
73
|
-
if [ "$TUNNEL" = true ]; then
|
|
74
|
-
echo "[T] 🌐 Starting Cloudflare Tunnel..."
|
|
75
|
-
if ! command -v cloudflared &> /dev/null; then
|
|
76
|
-
echo " ❌ Error: cloudflared not installed."
|
|
77
|
-
else
|
|
78
|
-
nohup cloudflared tunnel --url http://127.0.0.1:$BRIDGE_PORT > .tunnel.log 2>&1 &
|
|
79
|
-
sleep 5
|
|
80
|
-
TUNNEL_URL=$(grep -o 'https://.*\.trycloudflare\.com' .tunnel.log | head -n 1)
|
|
81
|
-
if [ -n "$TUNNEL_URL" ]; then
|
|
82
|
-
echo " ✅ Tunnel Active: $TUNNEL_URL"
|
|
83
|
-
echo " 📱 Generating QR Code..."
|
|
84
|
-
python3 -c "import qrcode; qr = qrcode.QRCode(); qr.add_data('$TUNNEL_URL'); qr.print_ascii()"
|
|
85
|
-
else
|
|
86
|
-
echo " ⚠️ Could not extract tunnel URL. Check .tunnel.log"
|
|
87
|
-
fi
|
|
88
|
-
fi
|
|
89
|
-
fi
|
|
90
|
-
echo "✅ READY."
|
|
91
|
-
|
|
92
|
-
# 3. Khởi động Portal Bridge (HUD Injector)
|
|
93
|
-
echo "[3/4] 🧪 Injected Golden HUD Bridge... "
|
|
94
|
-
BRIDGE_PID_FILE=".portal_bridge_${BRIDGE_PORT}.pid"
|
|
23
|
+
# 2. Khởi động Portal Bridge (HUD Injector)
|
|
24
|
+
echo "[1/2] 🧪 Đang gắn kết Golden HUD Bridge... "
|
|
25
|
+
BRIDGE_PID_FILE=".agent/logs/.portal_bridge_${BRIDGE_PORT}.pid"
|
|
95
26
|
if [ -f "$BRIDGE_PID_FILE" ]; then
|
|
96
27
|
kill $(cat "$BRIDGE_PID_FILE") 2>/dev/null
|
|
97
28
|
fi
|
|
98
|
-
nohup node scripts/ag_portal_bridge.js > ".portal_bridge_${BRIDGE_PORT}.log" 2>&1 &
|
|
29
|
+
nohup node scripts/ag_portal_bridge.js > ".agent/logs/portal_bridge_${BRIDGE_PORT}.log" 2>&1 &
|
|
99
30
|
echo $! > "$BRIDGE_PID_FILE"
|
|
100
|
-
echo " ✅ Bridge
|
|
31
|
+
echo " ✅ Bridge đang chạy (PID: $(cat "$BRIDGE_PID_FILE") tại Cổng $BRIDGE_PORT)"
|
|
101
32
|
|
|
102
|
-
#
|
|
103
|
-
echo "[
|
|
104
|
-
BOT_PID_FILE=".ag_gateway_bot.pid"
|
|
33
|
+
# 3. Khởi động AG Gateway Bot (Trợ lý Telegram)
|
|
34
|
+
echo "[2/2] 🤖 Đang đánh thức Truyền tin Telegram... "
|
|
35
|
+
BOT_PID_FILE=".agent/logs/.ag_gateway_bot.pid"
|
|
105
36
|
|
|
106
|
-
# Kill loop AND all tsx/node processes belonging to this token/project
|
|
107
|
-
# Chỉ kill nếu dự án có thư mục src/index.ts (tránh kill nhầm project khác chạy chung server)
|
|
108
37
|
if [ -f "src/index.ts" ] || [ -f "bot/index.ts" ]; then
|
|
109
38
|
pkill -f "tsx src/index.ts" 2>/dev/null
|
|
110
39
|
pkill -f "node src/index.ts" 2>/dev/null
|
|
111
40
|
fi
|
|
112
|
-
|
|
41
|
+
|
|
113
42
|
if [ -f "$BOT_PID_FILE" ]; then
|
|
114
43
|
kill -9 $(cat "$BOT_PID_FILE") 2>/dev/null
|
|
115
44
|
fi
|
|
116
|
-
sleep
|
|
45
|
+
sleep 1
|
|
117
46
|
|
|
118
|
-
# Start the bot with a more robust monitor
|
|
119
47
|
nohup bash -c "while true; do
|
|
120
|
-
echo \"\$(date):
|
|
121
|
-
npx tsx src/index.ts >>
|
|
48
|
+
echo \"\$(date): Khởi động Bot...\" >> .agent/logs/bot_interaction.log
|
|
49
|
+
npx tsx src/index.ts >> .agent/logs/bot_interaction.log 2>&1
|
|
122
50
|
EXIT_CODE=\$?
|
|
123
|
-
if [ \$EXIT_CODE -eq 0 ]; then break; fi
|
|
124
|
-
echo \"\$(date):
|
|
51
|
+
if [ \$EXIT_CODE -eq 0 ]; then break; fi
|
|
52
|
+
echo \"\$(date): Bot sụp đổ (Code: \$EXIT_CODE). Khởi động lại sau 5s...\" >> .agent/logs/bot_interaction.log
|
|
125
53
|
sleep 5
|
|
126
|
-
done" &
|
|
54
|
+
done" > /dev/null 2>&1 &
|
|
127
55
|
echo $! > "$BOT_PID_FILE"
|
|
128
|
-
echo " ✅
|
|
129
|
-
|
|
130
|
-
# 5. Sentinel Monitor (Giám sát Trí não)
|
|
131
|
-
echo "🛡️ Sentinel Active: Auto-shutdown if IDE connection lost."
|
|
132
|
-
SENTINEL_PID_FILE=".sentinel_${BRIDGE_PORT}.pid"
|
|
133
|
-
|
|
134
|
-
function start_sentinel() {
|
|
135
|
-
(
|
|
136
|
-
local fail_count=0
|
|
137
|
-
local PROJ_NAME=$(basename "$PROJECT_DIR")
|
|
138
|
-
# Give more time for the first check
|
|
139
|
-
sleep 60
|
|
140
|
-
while true; do
|
|
141
|
-
if ! curl -s "http://127.0.0.1:$IDE_PORT/json" | grep -q "$PROJ_NAME" > /dev/null 2>&1; then
|
|
142
|
-
fail_count=$((fail_count + 1))
|
|
143
|
-
if [ $fail_count -ge 3 ]; then
|
|
144
|
-
echo "$(date): ⚠️ IDE Lost. Auto-shutting down project..." >> .sentinel_crash.log
|
|
145
|
-
bash .agent/scripts/receptionist_down.sh
|
|
146
|
-
exit 0
|
|
147
|
-
fi
|
|
148
|
-
else
|
|
149
|
-
fail_count=0
|
|
150
|
-
fi
|
|
151
|
-
done
|
|
152
|
-
) &
|
|
153
|
-
echo $! > "$SENTINEL_PID_FILE"
|
|
154
|
-
}
|
|
155
|
-
start_sentinel
|
|
156
|
-
|
|
157
|
-
# Monitor
|
|
158
|
-
echo "----------------------------------------------------"
|
|
159
|
-
tail -f interaction_final.log
|
|
56
|
+
echo " ✅ Truyền tin Telegram đã lên sóng (PID: $(cat "$BOT_PID_FILE"))"
|
|
57
|
+
echo "✅ HOÀN TẤT. Hệ thống chạy ngầm, bạn có thể tắt Terminal này!"
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# --- Port Management Utility (Golden V6 - High Precision) ---
|
|
4
|
-
# Tự động quét và thu nạp cổng IDE theo từng dự án.
|
|
5
|
-
# Đảm bảo "Chính chủ" mới dùng, "Người lạ" thì né.
|
|
6
|
-
|
|
7
|
-
ENV_FILE=".env"
|
|
8
|
-
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
9
|
-
|
|
10
|
-
# 1. Tìm cổng trống dựa trên netstat
|
|
11
|
-
function find_free_port() {
|
|
12
|
-
local port=$1
|
|
13
|
-
while netstat -atn | grep -q ":$port "; do
|
|
14
|
-
port=$((port + 1))
|
|
15
|
-
done
|
|
16
|
-
echo $port
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
# 2. Cập nhật .env (Dùng sed tương thích đa hệ điều hành)
|
|
20
|
-
function update_env_port() {
|
|
21
|
-
local key=$1
|
|
22
|
-
local value=$2
|
|
23
|
-
if grep -q "^${key}=" "$ENV_FILE"; then
|
|
24
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
25
|
-
sed -i '' "s/^${key}=.*/${key}=${value}/" "$ENV_FILE"
|
|
26
|
-
else
|
|
27
|
-
sed -i "s/^${key}=.*/${key}=${value}/" "$ENV_FILE"
|
|
28
|
-
fi
|
|
29
|
-
else
|
|
30
|
-
echo "${key}=${value}" >> "$ENV_FILE"
|
|
31
|
-
fi
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
# 3. Quét dải cổng để tìm IDE của chính dự án này
|
|
35
|
-
function scan_project_ide() {
|
|
36
|
-
local start_p=$1
|
|
37
|
-
local end_p=$2
|
|
38
|
-
for ((p=start_p; p<=end_p; p++)); do
|
|
39
|
-
if netstat -atn | grep -q ":$p "; then
|
|
40
|
-
# Kiểm tra xem có đúng là IDE của dự án này đang ở cổng p không
|
|
41
|
-
PROJECT_NAME=$(basename "$PROJECT_DIR")
|
|
42
|
-
if curl -s "http://127.0.0.1:$p/json" | grep -q "$PROJECT_NAME" > /dev/null 2>&1; then
|
|
43
|
-
echo $p
|
|
44
|
-
return 0
|
|
45
|
-
fi
|
|
46
|
-
fi
|
|
47
|
-
done
|
|
48
|
-
echo ""
|
|
49
|
-
return 1
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
# --- Main Logic ---
|
|
53
|
-
|
|
54
|
-
# Nạp config cũ
|
|
55
|
-
if [ -f "$ENV_FILE" ]; then
|
|
56
|
-
source "$ENV_FILE"
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
DEFAULT_IDE_START=9555
|
|
60
|
-
IDE_RANGE_END=9655
|
|
61
|
-
BRIDGE_OFFSET=101 # IDE 9555 -> Bridge 9656
|
|
62
|
-
|
|
63
|
-
CURRENT_CONFIG_IDE=${IDE_PORT:-$DEFAULT_IDE_START}
|
|
64
|
-
|
|
65
|
-
echo "🔍 Đang rà soát "Brain Portal" (Dải 100 cổng) cho dự án: $(basename "$PROJECT_DIR")..."
|
|
66
|
-
|
|
67
|
-
# Bước 1: Quét xem có IDE nào đang mở dự án này không (Dải 9555 - 9655)
|
|
68
|
-
FOUND_PORT=$(scan_project_ide $DEFAULT_IDE_START $IDE_RANGE_END)
|
|
69
|
-
|
|
70
|
-
if [ ! -z "$FOUND_PORT" ]; then
|
|
71
|
-
echo "✅ Phát hiện IDE đang chạy tại cổng: $FOUND_PORT"
|
|
72
|
-
export IDE_PORT=$FOUND_PORT
|
|
73
|
-
export BRIDGE_PORT=$((FOUND_PORT + BRIDGE_OFFSET))
|
|
74
|
-
|
|
75
|
-
# Cập nhật .env nếu có thay đổi
|
|
76
|
-
if [ "$FOUND_PORT" != "$CURRENT_CONFIG_IDE" ]; then
|
|
77
|
-
echo "📝 Cập nhật cổng mới vào .env..."
|
|
78
|
-
update_env_port "IDE_PORT" "$FOUND_PORT"
|
|
79
|
-
update_env_port "BRIDGE_PORT" "$BRIDGE_PORT"
|
|
80
|
-
fi
|
|
81
|
-
else
|
|
82
|
-
# Bước 2: Không thấy IDE cũ, kiểm tra cổng trong .env có bị "người lạ" chiếm không
|
|
83
|
-
echo "❓ Không tìm thấy IDE đang chạy. Tiến hành rà soát cổng khả dụng..."
|
|
84
|
-
|
|
85
|
-
# Nếu cổng hiện tại bị "người lạ" chiếm
|
|
86
|
-
if netstat -atn | grep -q ":$CURRENT_CONFIG_IDE "; then
|
|
87
|
-
echo "⚠️ Cổng mặc định $CURRENT_CONFIG_IDE đã bị dự án khác chiếm."
|
|
88
|
-
# Tìm IDE trống trong dải
|
|
89
|
-
FREE_IDE=$(find_free_port $DEFAULT_IDE_START)
|
|
90
|
-
FREE_BRIDGE=$(find_free_port $((FREE_IDE + BRIDGE_OFFSET)))
|
|
91
|
-
|
|
92
|
-
echo "🚀 Đã phân bổ cặp cổng trống mới: IDE=$FREE_IDE, BRIDGE=$FREE_BRIDGE"
|
|
93
|
-
update_env_port "IDE_PORT" "$FREE_IDE"
|
|
94
|
-
update_env_port "BRIDGE_PORT" "$FREE_BRIDGE"
|
|
95
|
-
|
|
96
|
-
export IDE_PORT=$FREE_IDE
|
|
97
|
-
export BRIDGE_PORT=$FREE_BRIDGE
|
|
98
|
-
else
|
|
99
|
-
# Cổng trong .env vẫn trống, dùng luôn
|
|
100
|
-
export IDE_PORT=$CURRENT_CONFIG_IDE
|
|
101
|
-
# Đảm bảo BRIDGE_PORT tương ứng
|
|
102
|
-
export BRIDGE_PORT=$((CURRENT_CONFIG_IDE + BRIDGE_OFFSET))
|
|
103
|
-
update_env_port "BRIDGE_PORT" "$BRIDGE_PORT"
|
|
104
|
-
echo "✅ Sử dụng cổng cấu hình: $IDE_PORT (Bridge: $BRIDGE_PORT)"
|
|
105
|
-
fi
|
|
106
|
-
fi
|