ai-cli-online 2.1.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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -0
  3. package/README.zh-CN.md +170 -0
  4. package/bin/ai-cli-online.mjs +89 -0
  5. package/install-service.sh +319 -0
  6. package/package.json +57 -0
  7. package/server/.env.example +18 -0
  8. package/server/dist/auth.d.ts +3 -0
  9. package/server/dist/auth.js +9 -0
  10. package/server/dist/claude.d.ts +16 -0
  11. package/server/dist/claude.js +141 -0
  12. package/server/dist/db.d.ts +7 -0
  13. package/server/dist/db.js +73 -0
  14. package/server/dist/files.d.ts +15 -0
  15. package/server/dist/files.js +56 -0
  16. package/server/dist/index.d.ts +1 -0
  17. package/server/dist/index.js +466 -0
  18. package/server/dist/plans.d.ts +7 -0
  19. package/server/dist/plans.js +120 -0
  20. package/server/dist/pty.d.ts +15 -0
  21. package/server/dist/pty.js +75 -0
  22. package/server/dist/storage.d.ts +22 -0
  23. package/server/dist/storage.js +149 -0
  24. package/server/dist/tmux.d.ts +40 -0
  25. package/server/dist/tmux.js +191 -0
  26. package/server/dist/types.d.ts +1 -0
  27. package/server/dist/types.js +1 -0
  28. package/server/dist/websocket.d.ts +4 -0
  29. package/server/dist/websocket.js +304 -0
  30. package/server/package.json +32 -0
  31. package/shared/dist/types.d.ts +40 -0
  32. package/shared/dist/types.js +1 -0
  33. package/shared/package.json +20 -0
  34. package/start.sh +39 -0
  35. package/web/dist/assets/index-79TY7o1G.css +32 -0
  36. package/web/dist/assets/index-mcWZLwbP.js +235 -0
  37. package/web/dist/assets/pdf-Tk4_4Bu3.js +12 -0
  38. package/web/dist/assets/pdf.worker-BA9kU3Pw.mjs +61080 -0
  39. package/web/dist/favicon.svg +5 -0
  40. package/web/dist/fonts/JetBrainsMono-Bold.woff2 +0 -0
  41. package/web/dist/fonts/JetBrainsMono-Regular.woff2 +0 -0
  42. package/web/dist/fonts/MapleMono-CN-Bold.woff2 +0 -0
  43. package/web/dist/fonts/MapleMono-CN-Regular.woff2 +0 -0
  44. package/web/dist/index.html +17 -0
  45. package/web/package.json +32 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 CLI-Online Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # AI-Cli Online
2
+
3
+ [![npm version](https://img.shields.io/npm/v/ai-cli-online.svg)](https://www.npmjs.com/package/ai-cli-online)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-green.svg)](https://nodejs.org/)
6
+
7
+ A lightweight web terminal for accessing Claude Code (or any CLI) from your browser via xterm.js + tmux.
8
+
9
+ [**中文文档**](README.zh-CN.md)
10
+
11
+ ## Features
12
+
13
+ - **Full Web Terminal** — xterm.js with WebGL rendering, binary protocol for ultra-low latency
14
+ - **Session Persistence** — tmux keeps processes alive through disconnects; reconnect and resume instantly
15
+ - **Multi-Tab** — independent terminal groups with layout persistence across browser refreshes
16
+ - **Split Panes** — horizontal / vertical splits, arbitrarily nested
17
+ - **Document Browser** — view Markdown, HTML, and PDF files alongside your terminal
18
+ - **Editor Panel** — multi-line editing with server-side draft persistence (SQLite)
19
+ - **File Transfer** — upload files to CWD, browse and download via REST API
20
+ - **Scroll History** — capture-pane scrollback viewer with ANSI color preservation
21
+ - **Session Management** — sidebar to restore, delete, and rename sessions
22
+ - **Font Size Control** — adjustable terminal font size (A−/A+) with server-side persistence
23
+ - **Network Indicator** — real-time RTT latency display with signal bars
24
+ - **Auto Reconnect** — exponential backoff with jitter to prevent thundering herd
25
+ - **Secure Auth** — token authentication with timing-safe comparison
26
+
27
+ ## Comparison: AI-Cli Online vs OpenClaw
28
+
29
+ | Dimension | AI-Cli Online | OpenClaw |
30
+ |-----------|--------------|----------|
31
+ | **Positioning** | Lightweight web terminal | AI agent orchestration platform |
32
+ | **Core Use Case** | Browser-based remote terminal access | Multi-channel AI assistant |
33
+ | **Terminal Emulation** | xterm.js + WebGL | None |
34
+ | **Session Persistence** | tmux (survives disconnects) | Gateway in-memory state |
35
+ | **Multi-Tab / Split** | Tabs + arbitrarily nested panes | None |
36
+ | **Message Channels** | WebSocket (single channel) | 16+ (WhatsApp / Telegram / Slack / Discord...) |
37
+ | **Native Apps** | None (pure web) | macOS + iOS + Android |
38
+ | **Voice Interaction** | None | Voice Wake + Talk Mode |
39
+ | **AI Agent** | None built-in (run any CLI) | Pi Agent runtime + multi-agent routing |
40
+ | **Canvas / UI** | Document browser (MD / HTML / PDF) | A2UI real-time visual workspace |
41
+ | **File Transfer** | REST API upload / download | Channel-native media |
42
+ | **Security Model** | Token auth + timing-safe | Device pairing + DM policy + Docker sandbox |
43
+ | **Extensibility** | Shell scripts | 33 extensions + 60+ skills + ClawHub |
44
+ | **Transport** | Binary frames (ultra-low latency) | JSON WebSocket |
45
+ | **Deployment** | Single-node Node.js | Single-node + Tailscale Serve/Funnel |
46
+ | **Tech Stack** | React + Express + node-pty | Lit + Express + Pi Agent |
47
+ | **Package Size** | ~12 MB | ~300 MB+ |
48
+ | **Install** | `npx ai-cli-online` | `npm i -g openclaw && openclaw onboard` |
49
+
50
+ ## Quick Start
51
+
52
+ ### Option 1: npx (Recommended)
53
+
54
+ ```bash
55
+ npx ai-cli-online
56
+ ```
57
+
58
+ ### Option 2: Global Install
59
+
60
+ ```bash
61
+ npm install -g ai-cli-online
62
+ ai-cli-online
63
+ ```
64
+
65
+ ### Option 3: From Source
66
+
67
+ ```bash
68
+ git clone https://github.com/huacheng/ai-cli-online.git
69
+ cd ai-cli-online
70
+ npm install
71
+ npm run build
72
+ npm start
73
+ ```
74
+
75
+ ## Prerequisites
76
+
77
+ - Node.js >= 18
78
+ - tmux installed (`sudo apt install tmux` or `brew install tmux`)
79
+
80
+ ## Configuration
81
+
82
+ Create `server/.env`:
83
+
84
+ ```env
85
+ PORT=3001 # Server port
86
+ HOST=0.0.0.0 # Bind address
87
+ AUTH_TOKEN=your-secret-token # Auth token (required for production)
88
+ DEFAULT_WORKING_DIR=/home/user # Default working directory
89
+ HTTPS_ENABLED=true # Set to false behind nginx reverse proxy
90
+ TRUST_PROXY=1 # Set to 1 when behind nginx/reverse proxy
91
+ ```
92
+
93
+ See `server/.env.example` for all available options.
94
+
95
+ ## Architecture
96
+
97
+ ```
98
+ Browser (xterm.js + WebGL) <-- WebSocket binary/JSON --> Express (node-pty) <--> tmux session --> shell
99
+ ```
100
+
101
+ - **Frontend**: React + Zustand + xterm.js (WebGL renderer)
102
+ - **Backend**: Node.js + Express + node-pty + WebSocket + better-sqlite3
103
+ - **Session Manager**: tmux (persistent terminal sessions)
104
+ - **Layout System**: Tabs + recursive tree structure (LeafNode / SplitNode)
105
+ - **Transport**: Binary frames (hot path) + JSON (control messages)
106
+ - **Data Persistence**: SQLite (editor drafts)
107
+
108
+ ### Performance
109
+
110
+ - **Binary protocol** — 1-byte prefix frames for terminal I/O, eliminating JSON overhead
111
+ - **TCP Nagle disabled** — `setNoDelay(true)` removes up to 40 ms keystroke delay
112
+ - **WebSocket compression** — `perMessageDeflate` (level 1, threshold 128 B), 50-70% bandwidth reduction
113
+ - **WebGL renderer** — 3-10x rendering throughput vs canvas
114
+ - **Parallel initialization** — PTY creation, tmux config, and resize run concurrently
115
+
116
+ ## Project Structure
117
+
118
+ ```
119
+ ai-cli-online/
120
+ ├── shared/ # Shared type definitions (ClientMessage, ServerMessage)
121
+ ├── server/ # Backend (TypeScript)
122
+ │ └── src/
123
+ │ ├── index.ts # Main entry (HTTP + WebSocket + REST API)
124
+ │ ├── websocket.ts # WebSocket <-> PTY relay (binary + JSON)
125
+ │ ├── tmux.ts # tmux session management
126
+ │ ├── files.ts # File operations
127
+ │ ├── pty.ts # node-pty wrapper
128
+ │ ├── db.ts # SQLite database (draft persistence)
129
+ │ ├── auth.ts # Auth utilities
130
+ │ └── types.ts # Type definitions
131
+ ├── web/ # Frontend (React + Vite)
132
+ │ └── src/
133
+ │ ├── App.tsx # Main app component
134
+ │ ├── store.ts # Zustand state management
135
+ │ ├── components/ # UI components
136
+ │ ├── hooks/ # React hooks
137
+ │ └── api/ # API client
138
+ ├── start.sh # Production start script
139
+ └── package.json # Monorepo config
140
+ ```
141
+
142
+ ## Development
143
+
144
+ ```bash
145
+ # Dev mode (frontend + backend separately)
146
+ npm run dev
147
+
148
+ # Build
149
+ npm run build
150
+
151
+ # Production (build + start)
152
+ bash start.sh
153
+ ```
154
+
155
+ ### systemd Service + nginx Reverse Proxy
156
+
157
+ ```bash
158
+ sudo bash install-service.sh # Interactive install (systemd + optional nginx)
159
+ sudo systemctl start ai-cli-online # Start service
160
+ sudo journalctl -u ai-cli-online -f # View logs
161
+ ```
162
+
163
+ The install script will:
164
+ 1. Create a systemd service for auto-start and process management
165
+ 2. Detect nginx and optionally configure reverse proxy (WebSocket support, SSL, `client_max_body_size`)
166
+ 3. Auto-set `HTTPS_ENABLED=false` and `TRUST_PROXY=1` in `server/.env` when nginx is enabled
167
+
168
+ ## License
169
+
170
+ MIT
@@ -0,0 +1,170 @@
1
+ # AI-Cli Online
2
+
3
+ [![npm version](https://img.shields.io/npm/v/ai-cli-online.svg)](https://www.npmjs.com/package/ai-cli-online)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-green.svg)](https://nodejs.org/)
6
+
7
+ 轻量级 Web 终端,通过 xterm.js + tmux 在浏览器中访问 Claude Code(或任意 CLI)。
8
+
9
+ [**English**](README.md)
10
+
11
+ ## 功能特性
12
+
13
+ - **完整 Web 终端** — xterm.js + WebGL 渲染,二进制协议实现超低延迟
14
+ - **会话持久化** — tmux 保证断网后进程存活,重连即恢复
15
+ - **Tab 多标签页** — 独立终端分组,布局跨刷新持久化
16
+ - **分屏布局** — 水平/垂直任意嵌套分割
17
+ - **文档浏览器** — 终端旁查看 Markdown / HTML / PDF 文件
18
+ - **编辑器面板** — 多行编辑 + 草稿服务端持久化 (SQLite)
19
+ - **文件传输** — 上传文件到 CWD,浏览/下载通过 REST API
20
+ - **滚动历史** — capture-pane 回看,保留 ANSI 颜色
21
+ - **会话管理** — 侧边栏管理 session(恢复/删除/重命名)
22
+ - **字体大小控制** — 可调节终端字体大小 (A−/A+),设置服务端持久化
23
+ - **网络指示器** — 实时 RTT 延迟显示 + 信号条
24
+ - **自动重连** — 指数退避 + jitter 防雷群效应
25
+ - **安全认证** — Token 认证 + timing-safe 比较
26
+
27
+ ## 功能对比:AI-Cli Online vs OpenClaw
28
+
29
+ | 维度 | AI-Cli Online | OpenClaw |
30
+ |------|--------------|----------|
31
+ | **定位** | 轻量 Web 终端 | AI Agent 编排平台 |
32
+ | **核心用途** | 浏览器远程终端访问 | 多渠道 AI 助手 |
33
+ | **终端仿真** | xterm.js + WebGL | 无 |
34
+ | **会话持久化** | tmux(断网存活) | Gateway 内存状态 |
35
+ | **多标签/分屏** | Tab + 任意嵌套分屏 | 无 |
36
+ | **消息渠道** | WebSocket 单通道 | 16+(WhatsApp / Telegram / Slack / Discord...) |
37
+ | **原生应用** | 无(纯 Web) | macOS + iOS + Android |
38
+ | **语音交互** | 无 | Voice Wake + Talk Mode |
39
+ | **AI Agent** | 无内置(运行任意 CLI) | Pi Agent 运行时 + 多 Agent 路由 |
40
+ | **Canvas/UI** | 文档浏览器(MD / HTML / PDF) | A2UI 实时可视化工作区 |
41
+ | **文件传输** | REST API 上传/下载 | 渠道原生媒体 |
42
+ | **安全模型** | Token auth + timing-safe | 设备配对 + DM 策略 + Docker 沙箱 |
43
+ | **可扩展性** | Shell 脚本 | 33 扩展 + 60+ Skills + ClawHub |
44
+ | **传输协议** | 二进制帧(超低延迟) | JSON WebSocket |
45
+ | **部署** | 单机 Node.js | 单机 + Tailscale Serve/Funnel |
46
+ | **技术栈** | React + Express + node-pty | Lit + Express + Pi Agent |
47
+ | **包大小** | ~12 MB | ~300 MB+ |
48
+ | **安装** | `npx ai-cli-online` | `npm i -g openclaw && openclaw onboard` |
49
+
50
+ ## 快速开始
51
+
52
+ ### 方式一:npx 一键启动(推荐)
53
+
54
+ ```bash
55
+ npx ai-cli-online
56
+ ```
57
+
58
+ ### 方式二:全局安装
59
+
60
+ ```bash
61
+ npm install -g ai-cli-online
62
+ ai-cli-online
63
+ ```
64
+
65
+ ### 方式三:从源码运行
66
+
67
+ ```bash
68
+ git clone https://github.com/huacheng/ai-cli-online.git
69
+ cd ai-cli-online
70
+ npm install
71
+ npm run build
72
+ npm start
73
+ ```
74
+
75
+ ## 前提条件
76
+
77
+ - Node.js >= 18
78
+ - tmux 已安装(`sudo apt install tmux` 或 `brew install tmux`)
79
+
80
+ ## 配置
81
+
82
+ 创建 `server/.env`:
83
+
84
+ ```env
85
+ PORT=3001 # 服务端口
86
+ HOST=0.0.0.0 # 绑定地址
87
+ AUTH_TOKEN=your-secret-token # 认证 Token(生产环境必须设置)
88
+ DEFAULT_WORKING_DIR=/home/user # 默认工作目录
89
+ HTTPS_ENABLED=true # nginx 反代时设为 false
90
+ TRUST_PROXY=1 # nginx 反代时设为 1
91
+ ```
92
+
93
+ 完整选项参见 `server/.env.example`。
94
+
95
+ ## 架构
96
+
97
+ ```
98
+ 浏览器 (xterm.js + WebGL) <-- WebSocket binary/JSON --> Express (node-pty) <--> tmux session --> shell
99
+ ```
100
+
101
+ - **前端**: React + Zustand + xterm.js(WebGL 渲染)
102
+ - **后端**: Node.js + Express + node-pty + WebSocket + better-sqlite3
103
+ - **会话管理**: tmux(持久化终端会话)
104
+ - **布局系统**: Tab 标签页 + 递归树形结构(LeafNode / SplitNode)
105
+ - **传输协议**: 二进制帧(热路径)+ JSON(控制消息)
106
+ - **数据持久化**: SQLite(编辑器草稿)
107
+
108
+ ### 性能优化
109
+
110
+ - **二进制协议** — 1 字节前缀帧用于终端 I/O,消除 JSON 序列化开销
111
+ - **TCP Nagle 禁用** — `setNoDelay(true)` 消除最多 40 ms 按键延迟
112
+ - **WebSocket 压缩** — `perMessageDeflate`(level 1,threshold 128 B),带宽减少 50-70%
113
+ - **WebGL 渲染器** — 渲染吞吐量提升 3-10 倍
114
+ - **并行初始化** — PTY 创建、tmux 配置、resize 并行执行
115
+
116
+ ## 项目结构
117
+
118
+ ```
119
+ ai-cli-online/
120
+ ├── shared/ # 共享类型定义 (ClientMessage, ServerMessage)
121
+ ├── server/ # 后端服务 (TypeScript)
122
+ │ └── src/
123
+ │ ├── index.ts # 主入口 (HTTP + WebSocket + REST API)
124
+ │ ├── websocket.ts # WebSocket <-> PTY 双向 relay (二进制 + JSON)
125
+ │ ├── tmux.ts # tmux 会话管理
126
+ │ ├── files.ts # 文件操作
127
+ │ ├── pty.ts # node-pty 封装
128
+ │ ├── db.ts # SQLite 数据库 (草稿持久化)
129
+ │ ├── auth.ts # 认证工具
130
+ │ └── types.ts # 类型定义
131
+ ├── web/ # 前端应用 (React + Vite)
132
+ │ └── src/
133
+ │ ├── App.tsx # 主应用组件
134
+ │ ├── store.ts # Zustand 状态管理
135
+ │ ├── components/ # UI 组件
136
+ │ ├── hooks/ # React Hooks
137
+ │ └── api/ # API 客户端
138
+ ├── start.sh # 生产启动脚本
139
+ └── package.json # Monorepo 配置
140
+ ```
141
+
142
+ ## 开发
143
+
144
+ ```bash
145
+ # 开发模式(前后端分离)
146
+ npm run dev
147
+
148
+ # 构建
149
+ npm run build
150
+
151
+ # 生产模式(构建 + 启动)
152
+ bash start.sh
153
+ ```
154
+
155
+ ### systemd 服务 + nginx 反向代理
156
+
157
+ ```bash
158
+ sudo bash install-service.sh # 交互安装 (systemd + 可选 nginx 反代)
159
+ sudo systemctl start ai-cli-online # 启动服务
160
+ sudo journalctl -u ai-cli-online -f # 查看日志
161
+ ```
162
+
163
+ 安装脚本会:
164
+ 1. 创建 systemd 服务,支持开机自启和进程管理
165
+ 2. 检测 nginx 并可选配置反向代理(WebSocket 支持、SSL、`client_max_body_size`)
166
+ 3. nginx 启用时自动设置 `HTTPS_ENABLED=false` 和 `TRUST_PROXY=1`
167
+
168
+ ## License
169
+
170
+ MIT
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execFileSync } from 'node:child_process';
4
+ import { existsSync } from 'node:fs';
5
+ import { createRequire } from 'node:module';
6
+ import { dirname, join } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const rootDir = join(__dirname, '..');
11
+
12
+ // Read version from package.json
13
+ const require = createRequire(import.meta.url);
14
+ const pkg = require(join(rootDir, 'package.json'));
15
+
16
+ const args = process.argv.slice(2);
17
+
18
+ // --version
19
+ if (args.includes('--version') || args.includes('-v')) {
20
+ console.log(pkg.version);
21
+ process.exit(0);
22
+ }
23
+
24
+ // --help
25
+ if (args.includes('--help') || args.includes('-h')) {
26
+ console.log(`
27
+ ai-cli-online v${pkg.version} — Web Terminal for Claude Code
28
+
29
+ Usage:
30
+ ai-cli-online Start the server
31
+ ai-cli-online --help Show this help
32
+ ai-cli-online --version Show version
33
+
34
+ Environment variables (or server/.env):
35
+ PORT Server port (default: 3001)
36
+ HOST Bind address (default: 0.0.0.0)
37
+ AUTH_TOKEN Authentication token (required for production)
38
+ HTTPS_ENABLED Enable HTTPS (default: true)
39
+ DEFAULT_WORKING_DIR Default working directory
40
+
41
+ Prerequisites:
42
+ - Node.js >= 18
43
+ - tmux installed (sudo apt install tmux)
44
+
45
+ More info: ${pkg.homepage || 'https://github.com/huacheng/ai-cli-online'}
46
+ `.trim());
47
+ process.exit(0);
48
+ }
49
+
50
+ // Check Node.js version
51
+ const nodeVersion = parseInt(process.versions.node.split('.')[0], 10);
52
+ if (nodeVersion < 18) {
53
+ console.error(`Error: Node.js >= 18 is required (current: ${process.versions.node})`);
54
+ process.exit(1);
55
+ }
56
+
57
+ // Check tmux
58
+ try {
59
+ execFileSync('tmux', ['-V'], { stdio: 'pipe' });
60
+ } catch {
61
+ console.error('Error: tmux is not installed.');
62
+ console.error('Install it with: sudo apt install tmux (Debian/Ubuntu) or brew install tmux (macOS)');
63
+ process.exit(1);
64
+ }
65
+
66
+ // Check if built
67
+ const serverEntry = join(rootDir, 'server', 'dist', 'index.js');
68
+ if (!existsSync(serverEntry)) {
69
+ console.error('Error: Server not built. Run "npm run build" first.');
70
+ process.exit(1);
71
+ }
72
+
73
+ // Start server
74
+ const { fork } = await import('node:child_process');
75
+ const child = fork(serverEntry, [], {
76
+ cwd: join(rootDir, 'server'),
77
+ stdio: 'inherit',
78
+ });
79
+
80
+ child.on('exit', (code) => {
81
+ process.exit(code ?? 0);
82
+ });
83
+
84
+ // Forward signals
85
+ for (const signal of ['SIGINT', 'SIGTERM']) {
86
+ process.on(signal, () => {
87
+ child.kill(signal);
88
+ });
89
+ }