@ian2018cs/agenthub 0.1.2 → 0.1.3

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": "@ian2018cs/agenthub",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "A web-based UI for AI Agents",
5
5
  "type": "module",
6
6
  "main": "server/index.js",
@@ -7,6 +7,28 @@ description: 将生成的 HTML 或前端页面部署到 Docker nginx 容器。
7
7
 
8
8
  将前端项目部署到共享的 nginx Docker 容器,通过不同端口和配置文件实现项目隔离。
9
9
 
10
+ ## 快速开始
11
+
12
+ ```bash
13
+ # 1. 确保你有一个包含 index.html 的目录
14
+ mkdir my-project
15
+ echo "<h1>Hello World</h1>" > my-project/index.html
16
+
17
+ # 2. 使用 python3 部署(注意:是目录,不是文件)
18
+ python3 /path/to/deploy-frontend/scripts/deploy.py my-project
19
+
20
+ # 3. 访问输出的 URL,例如 http://10.0.1.133:8080
21
+ ```
22
+
23
+ ## 常见错误
24
+
25
+ | 错误 | 原因 | 解决方案 |
26
+ |------|------|----------|
27
+ | `python: command not found` | 使用了 `python` 而不是 `python3` | 使用 `python3` 命令 |
28
+ | `NotADirectoryError` | 传入了单个文件而不是目录 | 传入包含 index.html 的目录路径 |
29
+ | `404 Not Found` | 主文件不叫 index.html | 将主 HTML 文件重命名为 index.html |
30
+ | 本地能访问,其他设备不能 | IP 地址或网络问题 | 使用内网 IP,检查防火墙 |
31
+
10
32
  ## 配置
11
33
 
12
34
  默认 nginx 目录已配置为:`/home/xubuntu001/AI/nginx`
@@ -27,9 +49,15 @@ description: 将生成的 HTML 或前端页面部署到 Docker nginx 容器。
27
49
  使用 `scripts/deploy.py` 部署项目:
28
50
 
29
51
  ```bash
30
- python scripts/deploy.py <前端项目目录>
52
+ python3 scripts/deploy.py <前端项目目录>
31
53
  ```
32
54
 
55
+ **重要说明:**
56
+ - 必须使用 `python3` 命令(不是 `python`)
57
+ - `<前端项目目录>`:必须是一个**目录**(不能是单个文件)
58
+ - 目录中必须包含 `index.html` 作为入口文件(nginx 默认查找 index.html)
59
+ - 如果你的 HTML 文件不叫 `index.html`,需要先重命名
60
+
33
61
  **参数说明:**
34
62
  - `<前端项目目录>`:包含 index.html 等前端文件的目录(必需)
35
63
 
@@ -47,7 +75,14 @@ python scripts/deploy.py <前端项目目录>
47
75
  **示例:**
48
76
  ```bash
49
77
  # 部署前端项目(使用默认 nginx 目录)
50
- python .claude/skills/deploy-frontend/scripts/deploy.py ./my-frontend-app
78
+ python3 .claude/skills/deploy-frontend/scripts/deploy.py ./my-frontend-app
79
+
80
+ # 错误示例 - 不要这样做:
81
+ # python3 deploy.py ./my-app/index.html ❌ 不能传单个文件
82
+ # python deploy.py ./my-app ❌ 必须使用 python3
83
+
84
+ # 正确示例:
85
+ # python3 deploy.py ./my-app ✅ 传目录,使用 python3
51
86
  ```
52
87
 
53
88
  **输出示例:**
@@ -67,13 +102,13 @@ HTML 目录: /path/to/nginx/html/project-1738151234
67
102
  ### 列出所有部署
68
103
 
69
104
  ```bash
70
- python scripts/cleanup.py list
105
+ python3 scripts/cleanup.py list
71
106
  ```
72
107
 
73
108
  ### 清理指定项目
74
109
 
75
110
  ```bash
76
- python scripts/cleanup.py <project_id>
111
+ python3 scripts/cleanup.py <project_id>
77
112
  ```
78
113
 
79
114
  会删除:
@@ -86,7 +121,7 @@ python scripts/cleanup.py <project_id>
86
121
  ### 清理所有项目
87
122
 
88
123
  ```bash
89
- python scripts/cleanup.py all
124
+ python3 scripts/cleanup.py all
90
125
  ```
91
126
 
92
127
  ## 目录结构
@@ -124,9 +159,9 @@ nginx-base/
124
159
  import subprocess
125
160
 
126
161
  result = subprocess.run([
127
- "python",
162
+ "python3", # 必须使用 python3
128
163
  str(Path.home() / ".claude/skills/deploy-frontend/scripts/deploy.py"),
129
- "./frontend-output"
164
+ "./frontend-output" # 必须是目录,不能是单个文件
130
165
  ], capture_output=True, text=True)
131
166
 
132
167
  print(result.stdout)
@@ -139,7 +174,7 @@ nginx-base/
139
174
  当用户要求生成前端页面时:
140
175
 
141
176
  1. 生成前端代码(HTML/CSS/JS 等)
142
- 2. 将文件写入临时目录
177
+ 2. 将文件写入目录(确保主文件命名为 index.html)
143
178
  3. 调用 deploy.py 部署
144
179
  4. 将访问 URL 返回给用户
145
180
 
@@ -149,14 +184,14 @@ nginx-base/
149
184
  output_dir = Path("/tmp/frontend-{timestamp}")
150
185
  output_dir.mkdir(parents=True, exist_ok=True)
151
186
 
152
- # 2. 写入前端文件
153
- (output_dir / "index.html").write_text(html_content)
187
+ # 2. 写入前端文件(重要:主文件必须命名为 index.html)
188
+ (output_dir / "index.html").write_text(html_content) # ✅ 使用 index.html
154
189
  (output_dir / "style.css").write_text(css_content)
155
190
 
156
- # 3. 部署
191
+ # 3. 部署(使用 python3,传目录而不是文件)
157
192
  deploy_script = Path.home() / ".claude/skills/deploy-frontend/scripts/deploy.py"
158
193
  result = subprocess.run(
159
- ["python", str(deploy_script), str(output_dir)],
194
+ ["python3", str(deploy_script), str(output_dir)], # ✅ python3 + 目录路径
160
195
  capture_output=True,
161
196
  text=True
162
197
  )
@@ -190,6 +225,13 @@ newgrp docker
190
225
 
191
226
  ## 更新日志
192
227
 
228
+ ### v1.2 (2026-01-30)
229
+ - ✅ 更新文档:明确必须使用 `python3` 而不是 `python`
230
+ - ✅ 更新文档:强调必须传入目录而不是单个文件
231
+ - ✅ 更新文档:说明主文件必须命名为 `index.html`
232
+ - ✅ 添加常见错误示例和最佳实践
233
+ - ✅ 新增部署后文件重命名的故障排查说明
234
+
193
235
  ### v1.1 (2026-01-30)
194
236
  - ✅ 修复正则表达式转义警告
195
237
  - ✅ 添加自动 Docker 权限处理(`run_docker_command` 函数)
@@ -207,6 +249,36 @@ newgrp docker
207
249
 
208
250
  **权限问题**:脚本会自动使用 `sg docker -c` 处理权限问题
209
251
 
252
+ **找不到 python 命令**:
253
+ ```bash
254
+ # 错误:python: command not found
255
+ # 解决:使用 python3
256
+ python3 scripts/deploy.py ./my-app
257
+ ```
258
+
259
+ **传入单个文件报错**:
260
+ ```bash
261
+ # 错误:NotADirectoryError
262
+ # 原因:传入的是文件而不是目录
263
+ # 解决:传入包含 index.html 的目录
264
+ python3 scripts/deploy.py ./my-app/ # 正确
265
+ # 而不是
266
+ python3 scripts/deploy.py ./my-app/index.html # 错误
267
+ ```
268
+
269
+ **页面无法访问(404 Not Found)**:
270
+ ```bash
271
+ # 检查是否存在 index.html
272
+ ls /home/xubuntu001/AI/nginx/html/project-*/
273
+
274
+ # 如果文件名不是 index.html,重命名它:
275
+ cd /home/xubuntu001/AI/nginx/html/project-xxxxxxxxxx/
276
+ mv yourfile.html index.html
277
+
278
+ # 重新加载 nginx
279
+ sg docker -c "docker exec nginx-web nginx -s reload"
280
+ ```
281
+
210
282
  **配置未生效**:手动重新加载 nginx:
211
283
  ```bash
212
284
  docker exec nginx-web nginx -s reload
@@ -218,3 +290,9 @@ sg docker -c "docker exec nginx-web nginx -s reload"
218
290
  ```bash
219
291
  docker logs nginx-web
220
292
  ```
293
+
294
+ **本地能访问,其他设备访问不了**:
295
+ - 检查防火墙设置
296
+ - 确认设备在同一网络
297
+ - 使用正确的内网 IP(不要用 localhost)
298
+ - 确认路由器没有阻止端口
@@ -97,12 +97,6 @@ const builtInCommands = [
97
97
  namespace: 'builtin',
98
98
  metadata: { type: 'builtin' }
99
99
  },
100
- {
101
- name: '/cost',
102
- description: 'Display token usage and cost information',
103
- namespace: 'builtin',
104
- metadata: { type: 'builtin' }
105
- },
106
100
  {
107
101
  name: '/memory',
108
102
  description: 'Open CLAUDE.md memory file for editing',
@@ -314,39 +308,8 @@ Custom commands can be created in:
314
308
  message: `Rewinding conversation by ${steps} step${steps > 1 ? 's' : ''}...`
315
309
  }
316
310
  };
317
- },
318
-
319
- '/cost': async (args, context) => {
320
- const tokenUsage = context?.tokenUsage;
321
-
322
- if (!tokenUsage) {
323
- return {
324
- type: 'builtin',
325
- action: 'cost',
326
- data: {
327
- message: 'No token usage data available for this session.',
328
- usage: null
329
- }
330
- };
331
- }
332
-
333
- const { used = 0, total = 160000 } = tokenUsage;
334
- const percentage = total > 0 ? ((used / total) * 100).toFixed(1) : 0;
335
-
336
- return {
337
- type: 'builtin',
338
- action: 'cost',
339
- data: {
340
- usage: {
341
- used,
342
- total,
343
- percentage: parseFloat(percentage),
344
- remaining: total - used
345
- },
346
- message: `Token usage: ${used.toLocaleString()} / ${total.toLocaleString()} (${percentage}%)`
347
- }
348
- };
349
311
  }
312
+
350
313
  };
351
314
 
352
315
  /**
@@ -159,10 +159,10 @@ router.get('/dashboard', (req, res) => {
159
159
  const stats = usageDb.getDashboardStats(startDate, endDate);
160
160
  const users = userDb.getAllUsers();
161
161
 
162
- // Create username map
162
+ // Create username map (prefer username, fallback to email)
163
163
  const usernameMap = {};
164
164
  for (const user of users) {
165
- usernameMap[user.uuid] = user.username;
165
+ usernameMap[user.uuid] = user.username || user.email;
166
166
  }
167
167
 
168
168
  // Enrich top users with usernames