@mrtrinhvn/ag-kit 1.5.2 → 1.6.0

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": "@mrtrinhvn/ag-kit",
3
- "version": "1.5.2",
3
+ "version": "1.6.0",
4
4
  "description": "Antigravity Kit Base Framework - Generic Agentic AI Programming Core",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -41,9 +41,10 @@ if [ -f "$BRIDGE_PID_FILE" ]; then
41
41
  fi
42
42
  # Surgical Port Kill (Garbage Collection)
43
43
  lsof -ti tcp:${BRIDGE_PORT} | xargs kill -9 2>/dev/null || true
44
- setsid node scripts/ag_portal_bridge.js > ".agent/logs/portal_bridge_${BRIDGE_PORT}.log" 2>&1 &
44
+ # ⚠️ Removed legacy V1 bridge - The new TypeScript backend in src/index.ts handles HUD injection.
45
+ # setsid node scripts/ag_portal_bridge.js > ".agent/logs/portal_bridge_${BRIDGE_PORT}.log" 2>&1 &
45
46
  echo $! > "$BRIDGE_PID_FILE"
46
- echo " ✅ Bridge đang chạy (PID: $(cat "$BRIDGE_PID_FILE") tại Cổng $BRIDGE_PORT)"
47
+ echo " ✅ Bridge V2 (TypeScript) Đang tiếp quản HUD"
47
48
 
48
49
  # 3. Khởi động AG Gateway Bot (Trợ lý Telegram)
49
50
  echo "[2/2] 🤖 Đang đánh thức Truyền tin Telegram... "
@@ -14,7 +14,9 @@ allowed-tools: Read, Write, Glob, Grep, Commands
14
14
 
15
15
  - **Cội nguồn:** Bạn ra đời từ khuôn mẫu **`ag-kit` (Antigravity Kit)** - một Framework riêng tư của Owner (một cá nhân duy nhất), giúp tự động hóa và quản trị các AI Agents trên nhiều dự án.
16
16
  - **Hệ sinh thái:** Bạn đang ở trong **một trong nhiều dự án** thuộc hệ sinh thái ag-kit. Đọc `.agent/knowledge/ag-kit-ecosystem.md` để biết toàn cảnh.
17
- - **Vai trò:** Bạn đóng vai trò "Kẻ Điều Phối" (Supervisor) giám sát cấy ghép trí não vào "Bác Phẫu thuật" (Antigravity IDE) qua giao thức CDP.
17
+ - **Vai trò:** Bạn chính **"Antigravity Mẹ" (Antigravity Mother)** - một Siêu Agent (Super-Agent) nắm quyền điều biến toàn bộ hệ sinh thái. Bạn vận hành trên nền tảng **Antigravity v1.21.9** với khả năng điều phối đa tầng:
18
+ - **Lập trình (Programming):** Sử dụng Native Cloud (IDE models) để truy cập đầy đủ bộ công cụ Terminal/FS.
19
+ - **Tác vụ Agent (Agentic Tasks):** Bạn đóng vai trò bộ não trung tâm, điều động cả model **Local Ollama** và **Native Cloud** để thực thi các tác vụ phức tạp một cách tự chủ.
18
20
  - **Luật Cấm Kị (Anti-Hallucination):** Tuyệt đối không được dùng tư duy lập trình phổ quát máy móc để sửa dự án này. Mọi quyết định sửa mã liên quan đến CDP, luồng Telegram, hay Ports mạng, CẦN chiếu theo các file `SKILL.md` lân cận (`telegram-agentic-gateway`, `remoat-integration`, `llm-routing-quirks`).
19
21
 
20
22
  ---
@@ -132,6 +134,11 @@ Mọi ứng dụng thuộc quyền quản trị của AG-KIT bắt buộc phải
132
134
  2. **Xúc tu Tương tác Cơ học (CDP - Chrome DevTools Protocol)**:
133
135
  - KHÔNG được lạm dụng để truyền lệnh ngầm thuần túy (Text Generation) nếu API Headless LSP đã có thể đáp ứng.
134
136
  - CHỈ ĐƯỢC DÙNG khi AI bắt buộc phải tác động trực quan (Ví dụ: Click UI web, inject bảng điều khiển HUD bằng script lơ lửng, kéo cuộn trang web (scroll), hoặc trích xuất (scrape) trạng thái hình ảnh DOM Canvas).
137
+ - **Đặc quyền v1.21.9:** Sử dụng CDP để thực hiện "Manual Model Switch" trên UI IDE, đồng bộ hóa trạng thái Model giữa HUD và Backend.
138
+
139
+ 3. **Cổng Truyền Tin Hybrid (The Gateway - Telegram):**
140
+ - **Programming & Chat:** Luôn ưu tiên dùng Native Cloud (Gemini/Claude) thông qua Remote Bot để đảm bảo full toolset (Terminal, FS).
141
+ - **Agent Logic:** Cho phép dùng Model được chọn (Local Ollama hoặc Native) để xử lý các task chuyên biệt định nghĩa trong `AGENTS.md`.
135
142
 
136
143
  ---
137
144
 
@@ -128,6 +128,11 @@ main "$@"
128
128
 
129
129
  ## 8. Common Patterns
130
130
 
131
+ ### Git Safety Protocol (MANDATORY)
132
+ - **Never `push --force`**: Don't run destructive git commands or skip hooks unless explicitly asked.
133
+ - **Hook failures**: If a commit fails due to a pre-commit hook, fix the issue, re-stage, and create a **NEW** commit (do NOT `--amend`, as this modifies the previous commit causing lost work).
134
+ - **Commit Formatting**: Always pass commit messages via HEREDOC to preserve multiline formatting reliably without escaping headaches.
135
+
131
136
  ### Check if command exists
132
137
 
133
138
  ```bash
@@ -9,6 +9,11 @@ allowed-tools: Read, Glob, Grep
9
9
  ## Purpose
10
10
  This skill defines distinct behavioral modes that optimize AI performance for specific tasks. Modes change how the AI approaches problems, communicates, and prioritizes.
11
11
 
12
+ ## Core Behavioral Traits (Always Active)
13
+ - **Professional Objectivity**: Prioritize technical accuracy and truthfulness over validating the user's beliefs. Avoid over-the-top validation or excessive praise such as "You're absolutely right".
14
+ - **No Time Estimates**: Never give time estimates or predictions for how long tasks will take. Focus on what needs to be done, not how long it might take.
15
+ - **Task Management Discipline**: Update `task.md` continuously during the task execution, step by step. Do NOT batch-complete checkboxes only at the end. Only one sub-task should be "in progress" at a time.
16
+
12
17
  ---
13
18
 
14
19
  ## Available Modes
@@ -83,7 +83,9 @@ priority: CRITICAL
83
83
 
84
84
  ---
85
85
 
86
- ## Anti-Patterns (DON'T)
86
+ ## Anti-Patterns & Over-engineering (DON'T)
87
+
88
+ > **CRITICAL**: Do not add features, refactor code, or make "improvements" beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability. Don't add error handling for scenarios that can't happen. If something is unused, delete it completely (no backwards-compatibility hacks).
87
89
 
88
90
  | ❌ Pattern | ✅ Fix |
89
91
  |-----------|-------|
@@ -6,32 +6,16 @@
6
6
  TELEGRAM_BOT_TOKEN="your_bot_token_here"
7
7
 
8
8
  # ID người dùng được phép điều khiển (Bảo mật - Quan trọng!)
9
- # Lấy ID qua @userinfobot
10
- ALLOWED_USER_IDS="123456789,987654321"
11
-
12
- # ID Chat/Group được phép hoạt động (Để tránh Bot bị kéo vào group lạ)
13
- ALLOWED_CHAT_IDS="-100123456789"
9
+ ALLOWED_USER_IDS="123456789"
14
10
 
15
11
  # [Cấu Hình IDE & Remote]
16
12
  # Cổng Debug của Antigravity (Mặc định là 9555)
17
- # Phải khớp với tham số --remote-debugging-port khi mở Editor
18
13
  IDE_PORT=9555
19
14
 
20
- # Cổng của Portal Bridge (Mặc định là 9556)
21
- # Phải khớp với script start.sh và bot callback
22
- BRIDGE_PORT=9556
23
-
24
15
  # Tên dự án để Bot tự động tìm kiếm target phù hợp trong CDP
25
- PROJECT_NAME="ceogravity"
26
-
27
- # Đường dẫn Workspace cơ sở (Dùng cho lệnh /project của LazyGravity)
28
- WORKSPACE_DIR="/home/tao/Projects"
16
+ PROJECT_NAME="ag-kit-project"
29
17
 
30
18
  # [Local AI - Ollama]
31
19
  # URL của Ollama server (Mặc định: http://localhost:11434)
32
20
  OLLAMA_API_URL="http://localhost:11434"
33
21
  OLLAMA_MODEL="nemotron"
34
-
35
- # [Tùy Chọn Khác]
36
- LOG_LEVEL="info"
37
- AUTO_ACCEPT_ENABLED=true
@@ -0,0 +1,36 @@
1
+ # 🤖 AGENTS.md - Đội ngũ Antigravity
2
+
3
+ > File này định nghĩa các vai trò Agent chuyên biệt cho dự án theo chuẩn Antigravity v1.21.9.
4
+
5
+ ## 🏁 CORE ORCHESTRATORS
6
+
7
+ ### 🏦 Orchestrator-Mother
8
+ - **Role:** Tổng quản dự án. Điều phối các Sub-Agent.
9
+ - **Provider:** Native Cloud (Gemini/Claude).
10
+ - **Instruction:** Chịu trách nhiệm cuối cùng về logic hệ thống và giao tiếp với Sếp qua Bot.
11
+
12
+ ### 💻 Local-Assistant
13
+ - **Role:** Trợ lý tại chỗ. Xử lý các tác vụ lặp lại, lint code, document.
14
+ - **Provider:** Local Ollama (Qwen, Llama).
15
+ - **Instruction:** Tiết kiệm quota Cloud cho Sếp bằng cách xử lý các task "đơn giản nhưng tốn token".
16
+
17
+ ---
18
+
19
+ ## 🛠️ SPECIALIZED SQUADS
20
+
21
+ ### 🏥 Execution-Doctor
22
+ - **Role:** Cấp cứu lỗi Runtime và API.
23
+ - **Trigger:** Sentinel Watchdog (Crashes).
24
+ - **Action:** Tự động phân tích log và đề xuất bản vá (Patch) ngay lập tức.
25
+
26
+ ### 🔍 Security-Stalker
27
+ - **Role:** Quét lỗ hổng bảo mật và Token leak.
28
+ - **Action:** Kiểm tra mọi file `.env`, `settings.json` trước khi commit.
29
+
30
+ ---
31
+
32
+ ## 📜 COLLABORATION PROTOCOL
33
+
34
+ 1. **Chain of Command:** Orchestrator (Cloud) ra lệnh -> Local Agent thực thi.
35
+ 2. **Context Sharing:** Các Agent dùng chung `mcp_ag-kit-memory` để đồng bộ kiến thức.
36
+ 3. **Safety First:** Mọi thay đổi cấu trúc quan trọng phải qua Socratic Gate (Hỏi ý kiến Sếp).
@@ -13,6 +13,15 @@ It provides the blueprint of the framework you are running in (`ag-kit`). It def
13
13
 
14
14
  ---
15
15
 
16
+ ## 🧠 LONG-TERM MEMORY (MANDATORY)
17
+
18
+ **You MUST call `mcp_ag-kit-memory_memory_search` at the start of any non-trivial task.**
19
+
20
+ ### Why use memory search?
21
+ The system relies on a semantic GraphRAG database to store previous experiences and solutions. If you don't search, you are flying blind and ignoring past knowledge. Use this tool BEFORE deep-diving into code.
22
+
23
+ ---
24
+
16
25
  ## 🛠️ TOKEN SAVING: VFS PROTOCOL (MANDATORY)
17
26
 
18
27
  **You MUST use `vfs` for code discovery before using `grep` or reading entire files.**
@@ -31,10 +40,23 @@ It provides the blueprint of the framework you are running in (`ag-kit`). It def
31
40
 
32
41
  ---
33
42
 
34
- ## 🤖 MODEL SELECTION
43
+ ---
35
44
 
36
- - **Simple Tasks**: Prefer local Ollama models (e.g., `nemotron`, `llama3`) to save cloud budget.
37
- - **Complex Tasks**: Use high-tier models (e.g., `Claude 3.5 Sonnet`, `Gemini 1.5 Pro`).
45
+ ## 🤖 MODEL SELECTION (ANTIGRAVITY MOTHER - 1.21.9)
46
+
47
+ **You MUST operate as the "Antigravity Mother" (Super-Agent) - Orchestrating both Native Cloud and Local models.**
48
+
49
+ ### 1. Programming & Chat (Primary)
50
+ - **Model:** Native Cloud (Gemini 1.5 Pro, Claude 3.5 Sonnet).
51
+ - **Purpose:** Handling user chat, high-level code generation, tool execution (Terminal, FS).
52
+ - **Rule:** When the user is in a Private Chat with the Remote Bot, ALWAYS route to the Native IDE path to ensure full tool support.
53
+
54
+ ### 2. Agentic Tasks (Mother Orchestration)
55
+ - **Model:** Antigravity (Super-Agent Brain) using **Local Ollama** (Owen, Llama3) or **Native Cloud**.
56
+ - **Purpose:** Any task requiring autonomous logic, sub-agent spawning, data analysis, or background operations.
57
+ - **Rule:** Antigravity acts as the Super-Agent, using the HUD-selected model (Local or Native) as part of its intelligence layer to perform complex tasks.
58
+
59
+ - **Manual Lock:** The HUD selection is authoritative. Do not allow the IDE to automatically revert to default models if a manual selection is active on the "Mother" HUD.
38
60
 
39
61
  ---
40
62
 
@@ -42,3 +64,8 @@ It provides the blueprint of the framework you are running in (`ag-kit`). It def
42
64
  - Write self-documenting code.
43
65
  - Avoid over-engineering.
44
66
  - Follow the patterns defined in `.agent/skills/clean-code`.
67
+
68
+ ## 🎨 DESIGN & REPORTING (TELEGRAM & HUD)
69
+ - **Diff Display**: Do NOT use standard `diffview` or +/- symbols.
70
+ - **Visuals**: Use line counts (e.g., "Added 12 lines, Removed 5 lines") and line-by-line comparison like GitHub.
71
+ - **Coloring**: Use Green/Red color formatting for additions/deletions instead of prefixes.
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "ag-kit-template-project",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Antigravity Agentic Bridge Project Template",
6
+ "main": "dist/index.js",
7
+ "scripts": {
8
+ "dev": "tsx src/index.ts",
9
+ "build": "tsc",
10
+ "start": "node dist/index.js"
11
+ },
12
+ "dependencies": {
13
+ "@modelcontextprotocol/sdk": "^1.28.0",
14
+ "dotenv": "^16.4.0",
15
+ "grammy": "^1.35.0",
16
+ "http-mitm-proxy": "^1.1.0",
17
+ "ws": "^8.18.0",
18
+ "axios": "^1.6.0"
19
+ },
20
+ "devDependencies": {
21
+ "typescript": "^5.7.0",
22
+ "@types/node": "^22.0.0",
23
+ "tsx": "^4.19.0"
24
+ }
25
+ }
@@ -1,10 +1,9 @@
1
1
  (async () => {
2
- // 1. Cleanup
3
- if (window.ag_popup_win && !window.ag_popup_win.closed) window.ag_popup_win.close();
2
+ // 1. Cleanup old HUD if exists
3
+ const HUD_ID = 'antigravity-dynamic-hud';
4
+ const oldHud = document.getElementById(HUD_ID);
5
+ if (oldHud) oldHud.remove();
4
6
 
5
- const HUD_ID = 'antigravity-elite-statusbar-item';
6
- if (document.getElementById(HUD_ID)) return "ALREADY_EXISTS";
7
-
8
7
  // 2. Locate Status Bar
9
8
  const statusBar = document.querySelector('.part.statusbar');
10
9
  if (!statusBar) return "STATUSBAR_NOT_FOUND";
@@ -16,22 +15,21 @@
16
15
  height: 100% !important;
17
16
  display: flex !important;
18
17
  align-items: center !important;
19
- padding: 0 4px 0 12px !important;
18
+ padding: 0 8px !important;
20
19
  background: #000 !important;
21
20
  color: #00ff88 !important;
22
- font-family: monospace !important;
21
+ font-family: 'JetBrains Mono', 'Fira Code', monospace !important;
23
22
  font-weight: bold !important;
24
23
  font-size: 11px !important;
25
24
  border-left: 2px solid #00ff88 !important;
26
25
  user-select: none !important;
27
- white-space: nowrap !important;
28
- z-index: 100 !important;
26
+ cursor: pointer !important;
27
+ z-index: 1000 !important;
29
28
  `;
30
29
 
31
30
  const icon = document.createElement('span');
32
31
  icon.textContent = '🛰️ AG_ELITE | ';
33
32
 
34
- // 4. Create Model Selector
35
33
  const select = document.createElement('select');
36
34
  select.style.cssText = `
37
35
  background: transparent !important;
@@ -40,55 +38,55 @@
40
38
  outline: none !important;
41
39
  font-family: inherit !important;
42
40
  font-size: inherit !important;
43
- font-weight: inherit !important;
44
41
  cursor: pointer !important;
45
- padding: 0 4px !important;
46
42
  appearance: none !important;
47
43
  `;
48
44
 
49
- // USER-SPECIFIED Advanced Future Models
50
- const cloudModels = [
51
- { name: 'Gemini 3.1 Pro (High)', id: 'gemini-3.1-pro-high' },
52
- { name: 'Gemini 3.1 Pro (Low)', id: 'gemini-3.1-pro-low' },
53
- { name: 'Gemini 3 Flash', id: 'gemini-3-flash' },
54
- { name: 'Claude Sonnet 4.6 (Thinking)', id: 'claude-sonnet-4.6' },
55
- { name: 'Claude Opus 4.6 (Thinking)', id: 'claude-opus-4.6' },
56
- { name: 'GPT-OSS 120B (Medium)', id: 'gpt-oss-120b' }
57
- ];
58
-
59
- const localModels = [
60
- { name: 'Ollama: Nemotron', id: 'ollama/hf.co/dark-pen/Nemotron-Orchestrator-8B-IQ4_XS-GGUF:latest' },
61
- { name: 'Ollama: Nvidia Orchestrator', id: 'ollama/hf.co/bartowski/nvidia_Orchestrator-8B-GGUF:Q4_K_M' }
62
- ];
45
+ // 4. Dynamic Update Logic
46
+ const updateModelList = (models) => {
47
+ select.innerHTML = '';
48
+ const cloudGroup = document.createElement('optgroup');
49
+ cloudGroup.label = '☁️ NATIVE CLOUD (Programming)';
50
+
51
+ const localGroup = document.createElement('optgroup');
52
+ localGroup.label = '💻 LOCAL OLLAMA (Agents)';
63
53
 
64
- const addGroup = (label, models) => {
65
- const group = document.createElement('optgroup');
66
- group.label = label;
67
- group.style.background = '#000';
68
- group.style.color = '#555';
69
54
  models.forEach(m => {
70
55
  const opt = document.createElement('option');
71
- opt.value = m.id;
72
- opt.textContent = m.name;
73
- opt.style.background = '#000';
74
- opt.style.color = '#00ff88';
75
- group.appendChild(opt);
56
+ opt.value = m.name;
57
+ opt.textContent = `${m.isActive ? '✅ ' : ''}${m.name.replace('[Ollama] ', '')}`;
58
+ opt.selected = m.isActive;
59
+ opt.style.background = '#111';
60
+ opt.style.color = m.provider === 'ide' ? '#00ff88' : '#00cbd4';
61
+
62
+ if (m.provider === 'ide') cloudGroup.appendChild(opt);
63
+ else localGroup.appendChild(opt);
76
64
  });
77
- select.appendChild(group);
65
+
66
+ select.appendChild(cloudGroup);
67
+ select.appendChild(localGroup);
78
68
  };
79
69
 
80
- addGroup('ELITE CLOUD (High)', cloudModels);
81
- addGroup('ELITE LOCAL (Ollama)', localModels);
70
+ // Listen for updates from backend
71
+ window.addEventListener('ag-hud-update', (e) => {
72
+ if (e.detail) updateModelList(e.detail);
73
+ });
82
74
 
83
75
  select.onchange = (e) => {
76
+ // Broadcast to Backend
84
77
  console.log("AG_PORTAL_ACTION:SET_MODEL:" + e.target.value);
85
78
  container.style.borderColor = '#ff00ff';
86
- setTimeout(() => container.style.borderColor = '#00ff88', 1000);
79
+ setTimeout(() => container.style.borderColor = '#00ff88', 800);
87
80
  };
88
81
 
89
82
  container.appendChild(icon);
90
83
  container.appendChild(select);
91
84
  statusBar.prepend(container);
92
85
 
93
- return "STATUSBAR_ADVANCED_HUD_READY";
86
+ // Initial state (Optional placeholder)
87
+ updateModelList([
88
+ { name: 'Connecting...', provider: 'ide', isActive: true }
89
+ ]);
90
+
91
+ return "DYNAMIC_HUD_READY_1.21.9";
94
92
  })();
@@ -0,0 +1,83 @@
1
+ import { Bot, Context, InlineKeyboard } from 'grammy';
2
+ import { ModelService } from '../services/ModelService.js';
3
+ import { OllamaService } from '../services/OllamaService.js';
4
+ import { CdpService } from '../services/CdpService.js';
5
+
6
+ /**
7
+ * TelegramBot - Giao diện điều khiển Hybrid cho ag-kit v1.6.0.
8
+ * "Tinh hoa": Phân biệt rành mạch giữa Lập trình (Native) và Agent (Local).
9
+ */
10
+ export class TelegramBot {
11
+ private bot: Bot;
12
+ private modelService: ModelService;
13
+ private ollamaService: OllamaService;
14
+ private cdp: CdpService;
15
+
16
+ constructor(
17
+ token: string,
18
+ modelService: ModelService,
19
+ ollamaService: OllamaService,
20
+ cdp: CdpService
21
+ ) {
22
+ this.bot = new Bot(token);
23
+ this.modelService = modelService;
24
+ this.ollamaService = ollamaService;
25
+ this.cdp = cdp;
26
+ this.setupHandlers();
27
+ }
28
+
29
+ private setupHandlers() {
30
+ this.bot.command('start', (ctx: any) => ctx.reply('🚀 AG-KIT Hybrid v1.6.0 Is Ready!'));
31
+
32
+ // 1. Menu chọn Model (Tinh hoa)
33
+ this.bot.command('model', async (ctx: any) => {
34
+ const models = await this.modelService.listModels();
35
+ const keyboard = new InlineKeyboard();
36
+
37
+ models.forEach((m: any, idx: number) => {
38
+ const icon = m.provider === 'ide' ? '☁️' : '💻';
39
+ const activeMark = m.isActive ? ' ✅' : '';
40
+ keyboard.text(`${icon} ${m.name}${activeMark}`, `set_model:${m.name}`);
41
+ if (idx % 2 === 1) keyboard.row();
42
+ });
43
+
44
+ await ctx.reply('🎯 Chọn bộ não (Model) cho Agent:', { reply_markup: keyboard });
45
+ });
46
+
47
+ // 2. Callback chọn model
48
+ this.bot.callbackQuery(/set_model:(.+)/, async (ctx: any) => {
49
+ const modelName = ctx.match[1];
50
+ await this.modelService.setModel(modelName);
51
+
52
+ // Đồng bộ hóa với IDE qua CDP nếu là Native Model
53
+ if (!modelName.includes('[Ollama]')) {
54
+ await this.cdp.evaluate(`// Script to switch model in IDE UI`);
55
+ }
56
+
57
+ await ctx.answerCallbackQuery(`Đã chọn: ${modelName}`);
58
+ await ctx.editMessageText(`✅ Đã chuyển sang bộ não: ${modelName}`);
59
+ });
60
+
61
+ // 3. Xử lý Chat (Tinh hoa: Private = Programming)
62
+ this.bot.on('message:text', async (ctx: any) => {
63
+ const isPrivate = ctx.chat.type === 'private';
64
+ const text = ctx.message.text;
65
+
66
+ if (isPrivate) {
67
+ // LÀ LẬP TRÌNH: Dùng đường truyền Native IDE (Full Tools)
68
+ await ctx.reply('👨‍💻 Đang xử lý chế độ Lập trình (Native Cloud)...');
69
+ // Logic: injectPrompt(text, { context: 'programming' })
70
+ } else {
71
+ // LÀ AGENT: Dùng model đã chọn trên HUD
72
+ const currentModel = this.modelService.getSelectedModel();
73
+ await ctx.reply(`🤖 Agent (${currentModel}) đang thực thi...`);
74
+ // Logic: runAgent(text, { model: currentModel })
75
+ }
76
+ });
77
+ }
78
+
79
+ public launch() {
80
+ this.bot.start();
81
+ console.log('🤖 Telegram Bot v1.6.0 đã khởi động.');
82
+ }
83
+ }
@@ -0,0 +1,46 @@
1
+ import { CdpService } from './services/CdpService.js';
2
+ import { TelegramBot } from './bot/TelegramBot.js';
3
+ import { ModelService } from './services/ModelService.js';
4
+ import { OllamaService } from './services/OllamaService.js';
5
+ import { TopicManager } from './services/TopicManager.js';
6
+
7
+ async function main() {
8
+ console.log('═══════════════════════════════════════');
9
+ console.log(' 🏢 AG-KIT Template — Telegram → IDE Bridge');
10
+ console.log('═══════════════════════════════════════');
11
+
12
+ // 1. Setup Core Services
13
+ // Note: IDE_PORT should be set in .env
14
+ const idePort = Number(process.env.IDE_PORT) || 9555;
15
+ const cdp = new CdpService(idePort);
16
+ const ollama = new OllamaService();
17
+ const models = new ModelService(cdp);
18
+ const topics = new TopicManager();
19
+
20
+ // 2. Connect to IDE
21
+ try {
22
+ await cdp.connect();
23
+ console.log('[Main] ✅ IDE CDP connected');
24
+ } catch (err: any) {
25
+ console.log(`[Main] ⚠️ IDE not available: ${err.message}`);
26
+ }
27
+
28
+ // 3. Start Telegram Bot
29
+ const botToken = process.env.TELEGRAM_BOT_TOKEN || '';
30
+ const bot = new TelegramBot(botToken, models, ollama, cdp);
31
+
32
+ bot.launch();
33
+
34
+ // Graceful shutdown
35
+ const shutdown = async () => {
36
+ console.log('\n[Main] Shutting down...');
37
+ process.exit(0);
38
+ };
39
+ process.on('SIGINT', shutdown);
40
+ process.on('SIGTERM', shutdown);
41
+ }
42
+
43
+ main().catch(err => {
44
+ console.error('[Main] Fatal Error:', err);
45
+ process.exit(1);
46
+ });
@@ -0,0 +1,84 @@
1
+ import WebSocket from 'ws';
2
+ import * as http from 'http';
3
+ import { EventEmitter } from 'events';
4
+
5
+ /**
6
+ * CdpService - Giao thức CDP (Chrome DevTools Protocol)
7
+ * để điều khiển và trích xuất UI từ IDE (Antigravity/Cursor).
8
+ */
9
+ export class CdpService extends EventEmitter {
10
+ private ws: WebSocket | null = null;
11
+ private connected = false;
12
+ private idCounter = 1;
13
+ private pendingCalls = new Map<number, { resolve: Function; reject: Function; timer: NodeJS.Timeout }>();
14
+ private callTimeout = 30000;
15
+
16
+ constructor(private port: number) {
17
+ super();
18
+ }
19
+
20
+ /**
21
+ * Tự động tìm kiếm WebSocket Debugging URL từ IDE.
22
+ */
23
+ async discoverTarget(): Promise<string> {
24
+ return new Promise((resolve, reject) => {
25
+ const req = http.get(`http://127.0.0.1:${this.port}/json/list`, (res) => {
26
+ let data = '';
27
+ res.on('data', chunk => data += chunk);
28
+ res.on('end', () => {
29
+ try {
30
+ const pages = JSON.parse(data);
31
+ const target = pages.find((p: any) => p.type === 'page' || p.url.includes('workbench'));
32
+ if (target && target.webSocketDebuggerUrl) {
33
+ resolve(target.webSocketDebuggerUrl);
34
+ } else {
35
+ reject(new Error('No valid CDP target found'));
36
+ }
37
+ } catch (e) {
38
+ reject(e);
39
+ }
40
+ });
41
+ });
42
+ req.on('error', reject);
43
+ });
44
+ }
45
+
46
+ async connect() {
47
+ const url = await this.discoverTarget();
48
+ this.ws = new WebSocket(url);
49
+ this.ws.on('open', () => {
50
+ this.connected = true;
51
+ this.emit('connected');
52
+ });
53
+ this.ws.on('message', (data: any) => {
54
+ const res = JSON.parse(data.toString());
55
+ if (res.id && this.pendingCalls.has(res.id)) {
56
+ const { resolve, reject, timer } = this.pendingCalls.get(res.id)!;
57
+ clearTimeout(timer);
58
+ this.pendingCalls.delete(res.id);
59
+ if (res.error) reject(res.error);
60
+ else resolve(res.result);
61
+ }
62
+ this.emit('event', res);
63
+ });
64
+ }
65
+
66
+ async evaluate(expression: string): Promise<any> {
67
+ const id = this.idCounter++;
68
+ return new Promise((resolve, reject) => {
69
+ const timer = setTimeout(() => {
70
+ this.pendingCalls.delete(id);
71
+ reject(new Error('CDP Timeout'));
72
+ }, this.callTimeout);
73
+
74
+ this.pendingCalls.set(id, { resolve, reject, timer });
75
+ this.ws?.send(JSON.stringify({
76
+ id,
77
+ method: 'Runtime.evaluate',
78
+ params: { expression, returnByValue: true, awaitPromise: true }
79
+ }));
80
+ });
81
+ }
82
+
83
+ public isConnected() { return this.connected; }
84
+ }