UNPKG

aura-ai

Version:

AI-powered marketing strategist CLI tool for developers

88 lines (73 loc) 2.08 kB
import express from 'express' import expressWs from 'express-ws' import pty from 'node-pty' import { fileURLToPath } from 'url' import { dirname, join } from 'path' import fs from 'fs' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) const app = express() const wsInstance = expressWs(app) // 提供靜態檔案 app.use(express.static(join(__dirname, 'public'))) // 儲存所有的終端實例 const terminals = {} let terminalId = 0 // WebSocket 端點 app.ws('/terminal', (ws, req) => { const id = terminalId++ console.log(`Terminal ${id} connected`) // 啟動 Ink 應用 const shell = process.platform === 'win32' ? 'powershell.exe' : 'bash' const term = pty.spawn('node', ['--no-warnings', join(__dirname, '../../dist/rina.js')], { name: 'xterm-color', cols: 80, rows: 30, cwd: process.cwd(), env: process.env }) terminals[id] = term // 將終端輸出發送到前端 term.onData((data) => { try { ws.send(JSON.stringify({ type: 'output', data })) } catch (ex) { // 客戶端可能已斷線 } }) // 處理前端輸入 ws.on('message', (msg) => { try { const message = JSON.parse(msg) if (message.type === 'input') { term.write(message.data) } else if (message.type === 'resize') { term.resize(message.cols, message.rows) } } catch (ex) { console.error('Error handling message:', ex) } }) // 清理 ws.on('close', () => { console.log(`Terminal ${id} disconnected`) term.kill() delete terminals[id] }) }) // 健康檢查端點 app.get('/health', (req, res) => { res.json({ status: 'ok', terminals: Object.keys(terminals).length }) }) // 主頁面 app.get('/', (req, res) => { res.sendFile(join(__dirname, 'public', 'index.html')) }) const PORT = process.env.PORT || 3001 app.listen(PORT, () => { console.log(`🌐 Aura Web Terminal running at http://localhost:${PORT}`) console.log(`📡 WebSocket endpoint: ws://localhost:${PORT}/terminal`) })