@mrtrinhvn/ag-kit 1.4.3 → 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 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
@@ -32,16 +32,44 @@ program
32
32
 
33
33
  program.command('init')
34
34
  .description('Cấy ghép Lõi Trí Nhớ (.agent) vào dự án này')
35
- .action(() => {
35
+ .action(async () => {
36
36
  console.log('\x1b[36m🚀 Đang khởi tạo bộ Tủy Não Lập Trình AI (AG-Kit)...\x1b[0m');
37
37
 
38
38
  const srcAgent = path.join(TEMPLATE_DIR, '.agent');
39
39
  if (!fs.existsSync(TARGET_AGENT_DIR)) {
40
40
  copyRecursiveSync(srcAgent, TARGET_AGENT_DIR);
41
41
  fs.writeFileSync(path.join(TARGET_AGENT_DIR, '.version'), pkg.version);
42
- console.log(`\x1b[32m✅ Đã cấy ghép thành công thư mục .agent (v${pkg.version}) vào Project!\x1b[0m`);
42
+
43
+ ['scripts', 'start.sh', 'stop_bot.sh', '.gitignore'].forEach(item => {
44
+ const srcPath = path.join(TEMPLATE_DIR, item);
45
+ const destPath = path.join(process.cwd(), item);
46
+ if (fs.existsSync(srcPath) && !fs.existsSync(destPath)) {
47
+ copyRecursiveSync(srcPath, destPath);
48
+ }
49
+ });
50
+
51
+ const net = require('net');
52
+ const getPort = (port) => new Promise((resolve) => {
53
+ const s = net.createServer();
54
+ s.listen(port, () => { s.close(() => resolve(port)); });
55
+ s.on('error', () => { resolve(getPort(port + 1)); });
56
+ });
57
+ const bridgePort = await getPort(9656);
58
+
59
+ const envEx = path.join(TEMPLATE_DIR, '.env.example');
60
+ if (fs.existsSync(envEx) && !fs.existsSync('.env')) {
61
+ let content = fs.readFileSync(envEx, 'utf-8');
62
+ const projectName = path.basename(process.cwd());
63
+ content = content.replace(/PROJECT_NAME=.*/, `PROJECT_NAME=${projectName}`);
64
+ content = content.replace(/BRIDGE_PORT=.*/, `BRIDGE_PORT=${bridgePort}`);
65
+ fs.writeFileSync('.env', content);
66
+ console.log(`\x1b[32m✅ Đã cấp phát .env với BRIDGE_PORT=${bridgePort} độc quyền.\x1b[0m`);
67
+ }
68
+
69
+ console.log(`\x1b[32m✅ Đã cấy ghép thành công AG-Kit (v${pkg.version}) vào Project!\x1b[0m`);
43
70
 
44
- console.log('\x1b[35m👉 Bước tiếp theo: Hãy chọn menu "Build Bộ Não" để quét dự án.\x1b[0m');
71
+ console.log('\x1b[35m👉 Bước 1: Mở .env điền TELEGRAM_BOT_TOKEN.\x1b[0m');
72
+ console.log('\x1b[35m👉 Bước 2: Chạy "./start.sh" để gọi Bot thức dậy.\x1b[0m');
45
73
  } else {
46
74
  console.log('\x1b[33m⚠️ Thư mục .agent đã tồn tại.\x1b[0m');
47
75
  const vPath = path.join(TARGET_AGENT_DIR, '.version');
@@ -122,7 +150,7 @@ program.command('memory')
122
150
 
123
151
  program.command('gateway')
124
152
  .description('Kiểm tra trạng thái Agentic Gateway (IDE, Ollama, Telegram)')
125
- .action(() => {
153
+ .action(async () => {
126
154
  console.log('\x1b[36m🤖 Đang kiểm tra hệ sinh thái Agentic Gateway...\x1b[0m');
127
155
  if (!fs.existsSync(TARGET_AGENT_DIR)) {
128
156
  console.log('\x1b[31m❌ Chưa cấy ghép .agent.\x1b[0m');
@@ -130,20 +158,43 @@ program.command('gateway')
130
158
  }
131
159
  const envPath = path.join(process.cwd(), '.env');
132
160
  let targetPort = null;
161
+ let bridgePort = null;
133
162
  if (fs.existsSync(envPath)) {
134
- const match = fs.readFileSync(envPath, 'utf-8').match(/IDE_PORT=(\d+)/);
135
- if (match) targetPort = parseInt(match[1]);
163
+ const content = fs.readFileSync(envPath, 'utf-8');
164
+ const matchIde = content.match(/IDE_PORT=(\d+)/);
165
+ if (matchIde) targetPort = parseInt(matchIde[1]);
166
+ const matchBridge = content.match(/BRIDGE_PORT=(\d+)/);
167
+ if (matchBridge) bridgePort = parseInt(matchBridge[1]);
136
168
  }
137
169
 
170
+ // 1. Kiểm tra lớp IDE (Hub)
138
171
  if (targetPort) {
139
172
  try {
140
173
  execSync(`curl -s --max-time 2 http://127.0.0.1:${targetPort}/json/version`, { stdio: 'ignore' });
141
- console.log(`\x1b[32m✅ IDE CDP: Cổng riêng của dự án (${targetPort}) đang Online!\x1b[0m`);
174
+ console.log(`\x1b[32m✅ IDE CDP: Cổng Trạm (Hub ${targetPort}) đang Online!\x1b[0m`);
142
175
  } catch (e) {
143
- console.log(`\x1b[31m❌ IDE CDP: Cổng dự án (${targetPort}) Offline. Hãy chạy IDE với port này.\x1b[0m`);
176
+ console.log(`\x1b[31m❌ IDE CDP: Cổng Trạm (Hub ${targetPort}) Offline. Chạy ./start.sh để tự gọi.\x1b[0m`);
144
177
  }
145
178
  } else {
146
- console.log(`\x1b[33m⚠️ IDE CDP: Không tìm thấy IDE_PORT trong .env. Khuyên dùng "ag-kit init" để cấp port.\x1b[0m`);
179
+ console.log(`\x1b[33m⚠️ IDE CDP: Không tìm thấy IDE_PORT trong .env.\x1b[0m`);
180
+ }
181
+
182
+ // 2. Kiểm tra lớp Bot Nodejs (Bridge)
183
+ if (bridgePort) {
184
+ const net = require('net');
185
+ const checkBridge = () => new Promise((resolve) => {
186
+ const s = new net.Socket();
187
+ s.setTimeout(2000);
188
+ s.on('connect', () => { s.destroy(); resolve(true); });
189
+ s.on('error', () => { resolve(false); });
190
+ s.on('timeout', () => { s.destroy(); resolve(false); });
191
+ s.connect(bridgePort, '127.0.0.1');
192
+ });
193
+ const up = await checkBridge();
194
+ if (up) console.log(`\x1b[32m✅ BRIDGE: Cổng nội bộ Bot (${bridgePort}) đang Online!\x1b[0m`);
195
+ else console.log(`\x1b[31m❌ BRIDGE: Cổng nội bộ Bot (${bridgePort}) đang Offline. Bot chưa nhúng.\x1b[0m`);
196
+ } else {
197
+ console.log(`\x1b[33m⚠️ BRIDGE: Không tìm thấy BRIDGE_PORT trong .env.\x1b[0m`);
147
198
  }
148
199
 
149
200
  try {
@@ -196,28 +247,48 @@ program.command('status')
196
247
  async function runInteractiveMenu() {
197
248
  const inquirer = require('inquirer');
198
249
  console.clear();
199
- console.log('\x1b[35m\n🧠 AG-KIT - BẢNG ĐIỀU KHIỂN HỆ SINH THÁI AI\x1b[0m');
200
- console.log('\x1b[34m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m');
201
250
 
202
251
  const hasAgent = fs.existsSync(TARGET_AGENT_DIR);
203
252
  const vPath = path.join(TARGET_AGENT_DIR, '.version');
204
253
  let updateTag = '';
254
+ let hasUpdate = false;
255
+ let statusText = '\x1b[31mTrắng\x1b[0m';
256
+
205
257
  if (hasAgent && fs.existsSync(vPath)) {
206
258
  const installed = fs.readFileSync(vPath, 'utf-8').trim();
259
+ statusText = `\x1b[32mv${installed}\x1b[0m`;
207
260
  if (installed !== pkg.version) {
208
- updateTag = `\x1b[31m( bản mới: v${pkg.version})\x1b[0m `;
261
+ updateTag = `\x1b[31m(Cần lên v${pkg.version})\x1b[0m `;
262
+ hasUpdate = true;
209
263
  }
210
264
  }
211
265
 
212
- const choices = hasAgent ? [
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 = [
213
277
  { name: `🧠 Xây dựng / Cập nhật Bộ Não (build brain) - Thu thập Context`, value: 'brain' },
214
278
  { name: `🕸️ Khám phá Ký ức (memory) - Xem dữ liệu Vector`, value: 'memory' },
215
279
  { name: `🤖 Kiểm tra Agentic Gateway (gateway) - Test IDE/Bot`, value: 'gateway' },
216
- { name: `🔄 Nâng cấp Kiến thức (update) ${updateTag}`, value: 'update' },
217
- { name: '📊 Trạng thái (status) - Xem version & độ nhận thức', value: 'status' },
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(
218
287
  new inquirer.Separator(),
219
288
  { name: '❌ Thoát', value: 'exit' }
220
- ] : [
289
+ );
290
+
291
+ const choices = hasAgent ? agentChoices : [
221
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' },
222
293
  new inquirer.Separator(),
223
294
  { name: '❌ Thoát', value: 'exit' }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrtrinhvn/ag-kit",
3
- "version": "1.4.3",
3
+ "version": "1.4.6",
4
4
  "description": "Antigravity Kit Base Framework - Generic Agentic AI Programming Core",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -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. KHỞI ĐỘNG PROJECT MỚI (Bootstrap Protocol)
144
+ ## 8. 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 (Golden V6 - High Precision) ---
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:-9558}
13
+ BRIDGE_PORT=${BRIDGE_PORT:-9656}
14
14
 
15
15
  echo "════════════════════════════════════════════════════"
16
- echo " 🛑 SHUTTING DOWN AG GATEWAY [$BRIDGE_PORT]..."
16
+ echo " 🛑 ĐANG TẮT AG GATEWAY [$BRIDGE_PORT]..."
17
17
  echo "════════════════════════════════════════════════════"
18
18
 
19
- # 1. Tắt Sentinel Monitor
20
- SENTINEL_PID_FILE=".sentinel_${BRIDGE_PORT}.pid"
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 stopped."
23
+ echo "✅ HUD Bridge đã tắt."
31
24
  fi
32
25
 
33
- # 3. Tắt Bot
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 "✅ AG Gateway Bot stopped."
33
+ echo "✅ Bot Telegram đã tắt."
41
34
  fi
42
35
 
43
36
  echo "════════════════════════════════════════════════════"
44
- echo "✅ AG GATEWAY IS IDLE."
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 (Golden V6 - High Precision) ---
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
- if [ -f .agent/scripts/port_utils.sh ]; then
12
- source .agent/scripts/port_utils.sh
13
- else
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 - PORTAL [$BRIDGE_PORT]"
20
+ echo " 🏢 AG GATEWAY - CẦU NỐI NỘI BỘ [$BRIDGE_PORT]"
21
21
  echo "════════════════════════════════════════════════════"
22
22
 
23
- # 2. Xử Chế độ Headless & Cloudflare Tunnel
24
- HEADLESS=false
25
- TUNNEL=false
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 running (PID: $(cat "$BRIDGE_PID_FILE") on Port $BRIDGE_PORT)"
31
+ echo " ✅ Bridge đang chạy (PID: $(cat "$BRIDGE_PID_FILE") tại Cổng $BRIDGE_PORT)"
101
32
 
102
- # 4. Khởi động AG Gateway Bot (Trợ lý Telegram)
103
- echo "[4/4] 🤖 Waking up AG Gateway Bot... "
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
- pkill -f "interaction_final.log" 2>/dev/null
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 2
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): Starting Bot...\" >> interaction_final.log
121
- npx tsx src/index.ts >> interaction_final.log 2>&1
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 # Exit loop if deliberate stop
124
- echo \"\$(date): AG Gateway Bot crashed (Code: \$EXIT_CODE). Restarting in 5s...\" >> interaction_final.log
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 " ✅ AG Gateway Bot active (PID: $(cat "$BOT_PID_FILE"))"
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!"
@@ -10,25 +10,38 @@ else
10
10
  fi
11
11
 
12
12
  PORT=${IDE_PORT:-9555}
13
+ PROJ=${PROJECT_NAME:-"UnknownProject"}
13
14
 
14
- echo "🔍 Đang kiểm tra IDE tại cổng $PORT..."
15
+ echo "🔍 Đang kiểm tra IDE cho [$PROJ] tại cổng $PORT..."
15
16
 
16
- # 2. Logic Hợp thể & Mở mới linh hoạt
17
- if nc -z 127.0.0.1 $PORT &>/dev/null; then
18
- echo "✅ [HỢP THỂ]: Đã tìm thấy một IDE đang chạy riêng cho dự án ở cổng $PORT. Đang cắm ngầm Bot vào..."
19
- else
20
- echo "⚠️ [MỞ MỚI]: Không tìm thấy IDE ở cổng $PORT. Đang tự động phóng một IDE mới chuyên biệt cho dự án này..."
21
-
22
- if command -v cursor &> /dev/null; then
17
+ open_ide() {
18
+ if command -v antigravity &> /dev/null; then
19
+ antigravity --remote-debugging-port=$PORT . &
20
+ elif command -v cursor &> /dev/null; then
23
21
  cursor --remote-debugging-port=$PORT . &
24
22
  elif command -v code &> /dev/null; then
25
23
  code --remote-debugging-port=$PORT . &
26
24
  else
27
- echo "❌ Lỗi: Không tìm thấy lệnh 'cursor' hoặc 'code' trong cửa sổ lệnh."
28
- echo "👉 Hãy tự mở IDE bằng tay cho thư mục này bằng lệnh: cursor --remote-debugging-port=$PORT ."
25
+ echo "❌ Lỗi: Không tìm thấy lệnh 'antigravity', 'cursor' hoặc 'code'."
26
+ echo "👉 Hãy tự mở IDE bằng tay cho thư mục này."
29
27
  fi
30
-
31
- echo "⏳ Đang đợi IDE kích hoạt cổng CDP..."
28
+ }
29
+
30
+ # 2. Logic Hợp thể & Mở mới linh hoạt
31
+ if nc -z 127.0.0.1 $PORT &>/dev/null; then
32
+ # Cổng đã mở, thám thính xem bên trong có dự án của mình không (lọc theo JSON Title/Url)
33
+ if curl -s --max-time 2 http://127.0.0.1:$PORT/json/list | grep -i "\"title\":.*$PROJ" &>/dev/null; then
34
+ echo "✅ [HỢP THỂ]: Cổng $PORT đang mở và Workspace [$PROJ] đang được hiển thị. Trực tiếp cắm ngầm Bot vào màn hình này..."
35
+ else
36
+ echo "⚠️ [GỌI CỬA]: Cổng $PORT có IDE đang chạy, nhưng chưa mở màn hình cho [$PROJ]. Đang ra lệnh mở thêm giao diện cho dự án này..."
37
+ open_ide
38
+ echo "⏳ Đang đợi màn hình phụ tải xong..."
39
+ sleep 4
40
+ fi
41
+ else
42
+ echo "⚠️ [MỞ MỚI TỪ ĐẦU]: Cổng CDP $PORT hoàn toàn trống. Đang phóng cỗ máy IDE chuyên biệt..."
43
+ open_ide
44
+ echo "⏳ Đang đợi rễ CDP bám rễ..."
32
45
  sleep 4
33
46
  fi
34
47
 
package/template/start.sh CHANGED
@@ -10,25 +10,38 @@ else
10
10
  fi
11
11
 
12
12
  PORT=${IDE_PORT:-9555}
13
+ PROJ=${PROJECT_NAME:-"UnknownProject"}
13
14
 
14
- echo "🔍 Đang kiểm tra IDE tại cổng $PORT..."
15
+ echo "🔍 Đang kiểm tra IDE cho [$PROJ] tại cổng $PORT..."
15
16
 
16
- # 2. Logic Hợp thể & Mở mới linh hoạt
17
- if nc -z 127.0.0.1 $PORT &>/dev/null; then
18
- echo "✅ [HỢP THỂ]: Đã tìm thấy một IDE đang chạy riêng cho dự án ở cổng $PORT. Đang cắm ngầm Bot vào..."
19
- else
20
- echo "⚠️ [MỞ MỚI]: Không tìm thấy IDE ở cổng $PORT. Đang tự động phóng một IDE mới chuyên biệt cho dự án này..."
21
-
22
- if command -v cursor &> /dev/null; then
17
+ open_ide() {
18
+ if command -v antigravity &> /dev/null; then
19
+ antigravity --remote-debugging-port=$PORT . &
20
+ elif command -v cursor &> /dev/null; then
23
21
  cursor --remote-debugging-port=$PORT . &
24
22
  elif command -v code &> /dev/null; then
25
23
  code --remote-debugging-port=$PORT . &
26
24
  else
27
- echo "❌ Lỗi: Không tìm thấy lệnh 'cursor' hoặc 'code' trong Terminal này."
28
- echo "👉 Hãy tự mở IDE bằng tay cho thư mục này bằng lệnh: \cursor --remote-debugging-port=$PORT .\ "
25
+ echo "❌ Lỗi: Không tìm thấy lệnh 'antigravity', 'cursor' hoặc 'code'."
26
+ echo "👉 Hãy tự mở IDE bằng tay cho thư mục này."
29
27
  fi
30
-
31
- echo "⏳ Đang đợi IDE kích hoạt cổng CDP..."
28
+ }
29
+
30
+ # 2. Logic Hợp thể & Mở mới linh hoạt
31
+ if nc -z 127.0.0.1 $PORT &>/dev/null; then
32
+ # Cổng đã mở, thám thính xem bên trong có dự án của mình không (lọc theo JSON Title/Url)
33
+ if curl -s --max-time 2 http://127.0.0.1:$PORT/json/list | grep -i "\"title\":.*$PROJ" &>/dev/null; then
34
+ echo "✅ [HỢP THỂ]: Cổng $PORT đang mở và Workspace [$PROJ] đang được hiển thị. Trực tiếp cắm ngầm Bot vào màn hình này..."
35
+ else
36
+ echo "⚠️ [GỌI CỬA]: Cổng $PORT có IDE đang chạy, nhưng chưa mở màn hình cho [$PROJ]. Đang ra lệnh mở thêm giao diện cho dự án này..."
37
+ open_ide
38
+ echo "⏳ Đang đợi màn hình phụ tải xong..."
39
+ sleep 4
40
+ fi
41
+ else
42
+ echo "⚠️ [MỞ MỚI TỪ ĐẦU]: Cổng CDP $PORT hoàn toàn trống. Đang phóng cỗ máy IDE chuyên biệt..."
43
+ open_ide
44
+ echo "⏳ Đang đợi rễ CDP bám rễ..."
32
45
  sleep 4
33
46
  fi
34
47
 
@@ -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