@agentunion/kite 1.3.1 → 1.4.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/CHANGELOG.md +287 -1
- package/cli.js +76 -0
- package/extensions/agents/assistant/entry.py +111 -1
- package/extensions/agents/assistant/server.py +263 -197
- package/extensions/channels/acp_channel/entry.py +111 -1
- package/extensions/channels/acp_channel/module.md +23 -22
- package/extensions/channels/acp_channel/server.py +263 -197
- package/extensions/event_hub_bench/entry.py +107 -1
- package/extensions/services/backup/entry.py +408 -72
- package/extensions/services/backup/module.md +24 -22
- package/extensions/services/model_service/entry.py +255 -71
- package/extensions/services/model_service/module.md +21 -22
- package/extensions/services/watchdog/entry.py +344 -90
- package/extensions/services/watchdog/monitor.py +237 -21
- package/extensions/services/web/WEBSOCKET_STATUS.md +143 -0
- package/extensions/services/web/config_example.py +35 -0
- package/extensions/services/web/config_loader.py +110 -0
- package/extensions/services/web/entry.py +114 -26
- package/extensions/services/web/module.md +35 -24
- package/extensions/services/web/pairing.py +250 -0
- package/extensions/services/web/pairing_codes.jsonl +16 -0
- package/extensions/services/web/relay.py +643 -0
- package/extensions/services/web/relay_config.json5 +67 -0
- package/extensions/services/web/routes/routes_management_ws.py +127 -0
- package/extensions/services/web/routes/routes_rpc.py +89 -0
- package/extensions/services/web/routes/routes_test.py +61 -0
- package/extensions/services/web/server.py +445 -99
- package/extensions/services/web/static/css/style.css +138 -2
- package/extensions/services/web/static/index.html +295 -2
- package/extensions/services/web/static/js/app.js +1579 -5
- package/extensions/services/web/static/js/kernel-client-example.js +161 -0
- package/extensions/services/web/static/js/kernel-client.js +383 -0
- package/extensions/services/web/static/js/registry-tests.js +558 -0
- package/extensions/services/web/static/js/token-manager.js +175 -0
- package/extensions/services/web/static/pairing.html +248 -0
- package/extensions/services/web/static/test_registry.html +262 -0
- package/extensions/services/web/web_config.json5 +29 -0
- package/kernel/entry.py +120 -32
- package/kernel/event_hub.py +159 -16
- package/kernel/module.md +36 -33
- package/kernel/registry_store.py +70 -20
- package/kernel/rpc_router.py +134 -57
- package/kernel/server.py +292 -15
- package/kite_cli/__init__.py +3 -0
- package/kite_cli/__main__.py +5 -0
- package/kite_cli/commands/__init__.py +1 -0
- package/kite_cli/commands/clean.py +101 -0
- package/kite_cli/commands/doctor.py +35 -0
- package/kite_cli/commands/history.py +111 -0
- package/kite_cli/commands/info.py +96 -0
- package/kite_cli/commands/install.py +313 -0
- package/kite_cli/commands/list.py +143 -0
- package/kite_cli/commands/log.py +81 -0
- package/kite_cli/commands/rollback.py +88 -0
- package/kite_cli/commands/search.py +73 -0
- package/kite_cli/commands/uninstall.py +85 -0
- package/kite_cli/commands/update.py +118 -0
- package/kite_cli/core/__init__.py +1 -0
- package/kite_cli/core/checker.py +142 -0
- package/kite_cli/core/dependency.py +229 -0
- package/kite_cli/core/downloader.py +209 -0
- package/kite_cli/core/install_info.py +40 -0
- package/kite_cli/core/tool_installer.py +397 -0
- package/kite_cli/core/validator.py +78 -0
- package/kite_cli/main.py +289 -0
- package/kite_cli/utils/__init__.py +1 -0
- package/kite_cli/utils/i18n.py +252 -0
- package/kite_cli/utils/interactive.py +63 -0
- package/kite_cli/utils/operation_log.py +77 -0
- package/kite_cli/utils/paths.py +34 -0
- package/kite_cli/utils/version.py +308 -0
- package/launcher/count_lines.py +34 -0
- package/launcher/entry.py +905 -166
- package/launcher/logging_setup.py +104 -0
- package/launcher/module.md +37 -37
- package/launcher/process_manager.py +12 -1
- package/package.json +2 -1
- package/scripts/plan_manager.py +315 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,223 @@
|
|
|
1
|
-
# v1.
|
|
1
|
+
# v1.4.0
|
|
2
|
+
|
|
3
|
+
**发布日期**:2026-03-07
|
|
4
|
+
**上一版本**:v1.3.2
|
|
5
|
+
**版本级别**:minor
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 核心变更
|
|
10
|
+
|
|
11
|
+
本次发布新增 **Kite CLI 模块管理工具**(`kite_cli/`),提供模块安装、卸载、更新、搜索等完整生命周期管理能力。同时 Web 模块新增**配对机制**和 **Kernel 中转服务**,支持前端通过配对码安全连接 Kernel,实现 WebSocket 双向通信和 RPC 权限控制。
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 变更统计
|
|
16
|
+
|
|
17
|
+
| 类型 | 数量 | 说明 |
|
|
18
|
+
|------|------|------|
|
|
19
|
+
| 新增 | 46 | kite_cli 模块(28 个)+ web 功能扩展(18 个) |
|
|
20
|
+
| 删除 | 1 | routes_modules.py(被 routes_management_ws.py 替代) |
|
|
21
|
+
| 修改 | 30 | launcher、kernel、extensions 核心模块适配 |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 关键变更
|
|
26
|
+
|
|
27
|
+
### 新增模块
|
|
28
|
+
|
|
29
|
+
**`kite_cli/`** (28 个文件)
|
|
30
|
+
- **命令模块**(11 个):install, uninstall, update, list, info, doctor, history, log, search, clean, rollback
|
|
31
|
+
- **核心模块**(7 个):checker, dependency, downloader, install_info, tool_installer, validator
|
|
32
|
+
- **工具模块**(6 个):i18n, interactive, operation_log, paths, version
|
|
33
|
+
- **入口文件**:`main.py` (CLI 主入口), `__main__.py` (模块化启动)
|
|
34
|
+
|
|
35
|
+
**`extensions/services/web/`** (18 个文件)
|
|
36
|
+
- **配对机制**:`pairing.py` (配对码管理), `pairing_codes.jsonl` (持久化存储), `pairing.html` (配对界面)
|
|
37
|
+
- **中转服务**:`relay.py` (Kernel WebSocket 中转), `relay_config.json5` (中转配置)
|
|
38
|
+
- **配置系统**:`config_example.py`, `config_loader.py`, `web_config.json5`
|
|
39
|
+
- **路由扩展**:`routes_management_ws.py` (WebSocket 管理), `routes_rpc.py` (RPC 转发), `routes_test.py` (测试接口)
|
|
40
|
+
- **前端工具**:`kernel-client.js` (Kernel 客户端), `kernel-client-example.js`, `registry-tests.js`, `token-manager.js`, `test_registry.html`
|
|
41
|
+
- **文档**:`WEBSOCKET_STATUS.md` (WebSocket 状态说明)
|
|
42
|
+
|
|
43
|
+
**`scripts/`** (1 个文件)
|
|
44
|
+
- `plan_manager.py` — 计划管理工具
|
|
45
|
+
|
|
46
|
+
### 删除内容
|
|
47
|
+
|
|
48
|
+
- **`routes_modules.py`** — 被 `routes_management_ws.py` 替代(HTTP → WebSocket)
|
|
49
|
+
|
|
50
|
+
### 核心功能
|
|
51
|
+
|
|
52
|
+
**Kite CLI 模块管理**
|
|
53
|
+
```bash
|
|
54
|
+
# 安装模块
|
|
55
|
+
kite install <source>
|
|
56
|
+
|
|
57
|
+
# 卸载模块
|
|
58
|
+
kite uninstall <name>
|
|
59
|
+
|
|
60
|
+
# 更新模块
|
|
61
|
+
kite update <name>
|
|
62
|
+
|
|
63
|
+
# 列出已安装模块
|
|
64
|
+
kite list
|
|
65
|
+
|
|
66
|
+
# 搜索可用模块
|
|
67
|
+
kite search <keyword>
|
|
68
|
+
|
|
69
|
+
# 查看模块信息
|
|
70
|
+
kite info <name>
|
|
71
|
+
|
|
72
|
+
# 查看操作日志
|
|
73
|
+
kite log
|
|
74
|
+
|
|
75
|
+
# 回滚最后一次操作
|
|
76
|
+
kite rollback
|
|
77
|
+
|
|
78
|
+
# 清理临时文件
|
|
79
|
+
kite clean
|
|
80
|
+
|
|
81
|
+
# 检查下载工具状态
|
|
82
|
+
kite doctor
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Web 配对机制**
|
|
86
|
+
- 生成 6 位配对码(临时,不持久化)
|
|
87
|
+
- 前端输入配对码获取 frontend_token(30 天有效期)
|
|
88
|
+
- 支持 admin/guest 角色权限控制
|
|
89
|
+
- 配对记录持久化到 `pairing_codes.jsonl`
|
|
90
|
+
|
|
91
|
+
**Kernel 中转服务**
|
|
92
|
+
- 前端通过 WebSocket 连接 Web 模块
|
|
93
|
+
- Web 模块为每个前端创建到 Kernel 的连接
|
|
94
|
+
- 双向转发 JSON-RPC 消息
|
|
95
|
+
- RPC 权限白名单控制(admin 全权限,guest 受限)
|
|
96
|
+
- 前端模块生命周期管理(注册、重连、优雅退出)
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 架构演进
|
|
101
|
+
|
|
102
|
+
| 版本 | 核心模块 | CLI 工具 | Web 功能 | 包文件数 |
|
|
103
|
+
|------|---------|---------|---------|---------|
|
|
104
|
+
| v1.2.0 | 3 (event_hub, registry, launcher) | 无 | 基础 API | 97 |
|
|
105
|
+
| v1.3.1 | 2 (kernel, launcher) | 无 | 模块管理 API | 87 |
|
|
106
|
+
| v1.3.2 | 2 (kernel, launcher) | 无 | 断线重连防抖 | 88 |
|
|
107
|
+
| v1.4.0 | 2 (kernel, launcher) | kite_cli | 配对 + 中转 | 134 |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 设计原则
|
|
112
|
+
|
|
113
|
+
- ✅ **零共享代码依赖** — `relay.py` 和 `pairing.py` 可独立拷贝使用
|
|
114
|
+
- ✅ **跨语言兼容** — WebSocket JSON-RPC 2.0 标准协议
|
|
115
|
+
- ✅ **安全性** — 配对码 + frontend_token 双重验证,RPC 权限白名单
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 包信息
|
|
120
|
+
|
|
121
|
+
- **文件数**:134(+46 vs v1.3.2)
|
|
122
|
+
- **打包大小**:311.5 kB(+103.5 kB)
|
|
123
|
+
- **解压大小**:1.4 MB
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 兼容性说明
|
|
128
|
+
|
|
129
|
+
本次发布为 minor 版本,向后兼容。新增功能不影响现有模块运行。
|
|
130
|
+
|
|
131
|
+
- ✅ CLI 接口保持兼容(`kite` 命令)
|
|
132
|
+
- ✅ Kernel WebSocket 协议保持兼容
|
|
133
|
+
- ✅ 现有模块无需修改即可运行
|
|
134
|
+
# v1.3.2
|
|
135
|
+
|
|
136
|
+
**发布日期**:2026-03-04
|
|
137
|
+
**上一版本**:v1.3.1
|
|
138
|
+
**版本级别**:patch
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## 核心变更
|
|
143
|
+
|
|
144
|
+
本次发布主要包含功能增强和稳定性改进。新增 Web 模块管理 API,支持通过 HTTP 接口扫描、查看和编辑模块元数据与配置。Kernel 模块增加断线重连防抖机制(5 秒窗口),避免短暂网络波动导致的模块状态误判。多个扩展模块和前端界面进行了优化更新。
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 变更统计
|
|
149
|
+
|
|
150
|
+
| 类型 | 数量 | 说明 |
|
|
151
|
+
|------|------|------|
|
|
152
|
+
| 新增 | 1 | `routes_modules.py` (249 行) |
|
|
153
|
+
| 修改 | 18 | kernel、launcher、扩展模块、web 前端 |
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 关键变更
|
|
158
|
+
|
|
159
|
+
### 新增功能
|
|
160
|
+
|
|
161
|
+
**`extensions/services/web/routes/routes_modules.py`** (249 行)
|
|
162
|
+
- 模块管理 API:扫描项目中的所有模块
|
|
163
|
+
- 元数据查看与编辑(`module.md` 前置元数据)
|
|
164
|
+
- 配置查看与编辑(`config.yaml`)
|
|
165
|
+
- 只读字段保护(`name`, `type`, `runtime`, `entry`)
|
|
166
|
+
|
|
167
|
+
### 核心改进
|
|
168
|
+
|
|
169
|
+
**`kernel/server.py`** — 断线重连防抖
|
|
170
|
+
```diff
|
|
171
|
+
+ # Debounce timers for disconnected modules (module_id -> asyncio.Task)
|
|
172
|
+
+ self._debounce_tasks: dict[str, asyncio.Task] = {}
|
|
173
|
+
+ # Cancel debounce timer if module is reconnecting within 5s window
|
|
174
|
+
+ old_debounce = server._debounce_tasks.pop(module_id, None)
|
|
175
|
+
+ if old_debounce:
|
|
176
|
+
+ old_debounce.cancel()
|
|
177
|
+
```
|
|
178
|
+
- 5 秒防抖窗口,避免短暂断线误判
|
|
179
|
+
- Launcher 离线 35 秒后触发全局重启
|
|
180
|
+
|
|
181
|
+
**`kernel/registry_store.py`** — 连接状态管理
|
|
182
|
+
- 新增 `set_connected()` / `set_disconnected()` 方法
|
|
183
|
+
- 模块注册表支持实时连接状态跟踪
|
|
184
|
+
|
|
185
|
+
**`launcher/entry.py`** — 进程管理优化
|
|
186
|
+
- 改进模块启动和停止逻辑
|
|
187
|
+
- 优化日志输出和错误处理
|
|
188
|
+
|
|
189
|
+
### 前端更新
|
|
190
|
+
|
|
191
|
+
**Web UI** (`static/index.html`, `static/js/app.js`, `static/css/style.css`)
|
|
192
|
+
- 界面样式优化
|
|
193
|
+
- 交互逻辑改进
|
|
194
|
+
- 新增模块管理相关 UI 组件
|
|
195
|
+
|
|
196
|
+
### 扩展模块适配
|
|
197
|
+
|
|
198
|
+
更新以下模块以适配 Kernel 连接状态管理:
|
|
199
|
+
- `extensions/agents/assistant/server.py`
|
|
200
|
+
- `extensions/channels/acp_channel/server.py`
|
|
201
|
+
- `extensions/services/backup/entry.py`
|
|
202
|
+
- `extensions/services/model_service/entry.py`
|
|
203
|
+
- `extensions/services/watchdog/entry.py`
|
|
204
|
+
- `extensions/services/watchdog/monitor.py`
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 包信息
|
|
209
|
+
|
|
210
|
+
- **文件数**:88(与 v1.3.1 相同)
|
|
211
|
+
- **打包大小**:~208 kB
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 稳定性改进
|
|
216
|
+
|
|
217
|
+
- ✅ **断线重连防抖** — 避免短暂网络波动导致模块误判为离线
|
|
218
|
+
- ✅ **连接状态跟踪** — Registry 实时记录模块连接状态
|
|
219
|
+
- ✅ **Launcher 保护** — 35 秒容错窗口,避免误触发全局重启
|
|
220
|
+
# v1.3.1
|
|
2
221
|
|
|
3
222
|
**发布日期**:2026-03-04
|
|
4
223
|
**上一版本**:v1.2.0
|
|
@@ -206,3 +425,70 @@
|
|
|
206
425
|
## 变更摘要
|
|
207
426
|
|
|
208
427
|
重大功能更新:新增三个扩展类型目录(agents、channels、services),引入统一日志工具 `kite_log.py`,新增 backup、model_service、web 三个服务模块。核心模块(launcher、registry、event_hub)进行了多项优化和增强,包括进程管理改进、事件路由优化、模块生命周期管理完善。打包文件数从 36 个增至 72 个,框架扩展性和功能完整度显著提升。
|
|
428
|
+
# v1.0.8
|
|
429
|
+
|
|
430
|
+
**发布日期**:2026-03-01
|
|
431
|
+
**上一版本**:v1.0.7
|
|
432
|
+
**版本级别**:patch
|
|
433
|
+
|
|
434
|
+
## 变更文件
|
|
435
|
+
|
|
436
|
+
### 修改
|
|
437
|
+
- `package.json` — `files` 字段新增 `!` 否定模式排除规则
|
|
438
|
+
|
|
439
|
+
## 变更摘要
|
|
440
|
+
|
|
441
|
+
修复 npm 打包时包含了不必要文件的问题。在 `package.json` 的 `files` 字段中添加排除规则(`!**/__pycache__`、`!**/*.pyc`、`!**/data`、`!**/bench_results`、`!core/event_hub_bench`),确保发布包不包含 Python 缓存、运行时数据和基准测试文件。包大小从 177.6 kB 降至 53.4 kB。
|
|
442
|
+
# v1.0.7
|
|
443
|
+
|
|
444
|
+
**发布日期**:2026-03-01
|
|
445
|
+
**上一版本**:无(首次发布)
|
|
446
|
+
**版本级别**:patch
|
|
447
|
+
|
|
448
|
+
## 变更文件
|
|
449
|
+
|
|
450
|
+
初始发布,包含所有文件:
|
|
451
|
+
|
|
452
|
+
### 根文件
|
|
453
|
+
- `cli.js`
|
|
454
|
+
- `main.py`
|
|
455
|
+
- `__main__.py`
|
|
456
|
+
- `__init__.py`
|
|
457
|
+
- `package.json`
|
|
458
|
+
|
|
459
|
+
### core/
|
|
460
|
+
- `core/__init__.py`
|
|
461
|
+
- `core/launcher/__init__.py`
|
|
462
|
+
- `core/launcher/entry.py`
|
|
463
|
+
- `core/launcher/process_manager.py`
|
|
464
|
+
- `core/launcher/module_scanner.py`
|
|
465
|
+
- `core/launcher/module.md`
|
|
466
|
+
- `core/registry/__init__.py`
|
|
467
|
+
- `core/registry/entry.py`
|
|
468
|
+
- `core/registry/server.py`
|
|
469
|
+
- `core/registry/store.py`
|
|
470
|
+
- `core/registry/module.md`
|
|
471
|
+
- `core/event_hub/__init__.py`
|
|
472
|
+
- `core/event_hub/entry.py`
|
|
473
|
+
- `core/event_hub/hub.py`
|
|
474
|
+
- `core/event_hub/router.py`
|
|
475
|
+
- `core/event_hub/dedup.py`
|
|
476
|
+
- `core/event_hub/server.py`
|
|
477
|
+
- `core/event_hub/bench.py`
|
|
478
|
+
- `core/event_hub/bench_extreme.py`
|
|
479
|
+
- `core/event_hub/bench_perf.py`
|
|
480
|
+
- `core/event_hub/module.md`
|
|
481
|
+
- `core/event_hub/BENCHMARK.md`
|
|
482
|
+
|
|
483
|
+
### extensions/
|
|
484
|
+
- `extensions/__init__.py`
|
|
485
|
+
- `extensions/services/__init__.py`
|
|
486
|
+
- `extensions/services/watchdog/__init__.py`
|
|
487
|
+
- `extensions/services/watchdog/entry.py`
|
|
488
|
+
- `extensions/services/watchdog/server.py`
|
|
489
|
+
- `extensions/services/watchdog/monitor.py`
|
|
490
|
+
- `extensions/services/watchdog/module.md`
|
|
491
|
+
|
|
492
|
+
## 变更摘要
|
|
493
|
+
|
|
494
|
+
Kite 框架首次发布到 npm。包含核心启动器(launcher)、模块注册中心(registry)、事件中心(event_hub)三个核心模块,以及 watchdog 服务扩展。提供 Node.js CLI 入口和 Python 主入口,支持 Windows、Linux、macOS 三平台。
|
package/cli.js
CHANGED
|
@@ -67,6 +67,82 @@ for (let i = 0; i < args.length; i++) {
|
|
|
67
67
|
|
|
68
68
|
const versionDir = path.join(kiteHome, 'versions', useVersion);
|
|
69
69
|
|
|
70
|
+
// Check if first arg is a CLI command or help/version flag
|
|
71
|
+
const cliCommands = ['install', 'uninstall', 'update', 'list', 'search', 'info', 'log', 'rollback', 'clean', 'doctor', 'history'];
|
|
72
|
+
const helpFlags = ['-h', '-H', '--help', 'help'];
|
|
73
|
+
const versionFlags = ['-v', '-V', '--version', 'version'];
|
|
74
|
+
|
|
75
|
+
// Handle no arguments - show brief help
|
|
76
|
+
if (args.length === 0) {
|
|
77
|
+
// Detect language from environment
|
|
78
|
+
const lang = (process.env.LANG || '').toLowerCase();
|
|
79
|
+
const isEnglish = lang.startsWith('en');
|
|
80
|
+
|
|
81
|
+
if (isEnglish) {
|
|
82
|
+
console.log('Kite CLI — Modular AI Framework');
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log('Usage:');
|
|
85
|
+
console.log(' kite start Start Kite framework');
|
|
86
|
+
console.log(' kite list List installed modules');
|
|
87
|
+
console.log(' kite install <module> Install a module');
|
|
88
|
+
console.log(' kite -h, --help Show full help');
|
|
89
|
+
console.log(' kite -v, --version Show version');
|
|
90
|
+
console.log('');
|
|
91
|
+
console.log('Run "kite -h" to see all available commands');
|
|
92
|
+
} else {
|
|
93
|
+
console.log('Kite CLI — 模块化 AI 框架');
|
|
94
|
+
console.log('');
|
|
95
|
+
console.log('用法:');
|
|
96
|
+
console.log(' kite start 启动 Kite 框架');
|
|
97
|
+
console.log(' kite list 列出已安装的模块');
|
|
98
|
+
console.log(' kite install <module> 安装模块');
|
|
99
|
+
console.log(' kite -h, --help 显示完整帮助信息');
|
|
100
|
+
console.log(' kite -v, --version 显示版本号');
|
|
101
|
+
console.log('');
|
|
102
|
+
console.log('运行 "kite -h" 查看所有可用命令');
|
|
103
|
+
}
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Handle 'start' command - launch Kite framework
|
|
108
|
+
if (args[0] === 'start') {
|
|
109
|
+
// Remove 'start' from args and continue to framework launch
|
|
110
|
+
pythonArgs.splice(pythonArgs.indexOf('start'), 1);
|
|
111
|
+
// Continue to framework launch below
|
|
112
|
+
} else if (args.length > 0 && (cliCommands.includes(args[0]) || helpFlags.includes(args[0]) || versionFlags.includes(args[0]))) {
|
|
113
|
+
// Determine working directory for kite_cli
|
|
114
|
+
let cliWorkDir = versionDir;
|
|
115
|
+
|
|
116
|
+
// If running from development directory (has kite_cli/), use current directory
|
|
117
|
+
if (fs.existsSync(path.join(packageDir, 'kite_cli', '__init__.py'))) {
|
|
118
|
+
cliWorkDir = packageDir;
|
|
119
|
+
} else if (!fs.existsSync(path.join(versionDir, 'main.py'))) {
|
|
120
|
+
// Version not installed yet
|
|
121
|
+
console.log('[kite] CLI 命令需要先安装 Kite 框架');
|
|
122
|
+
console.log('[kite] 正在安装...');
|
|
123
|
+
// Will be installed below
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Only execute if we have a valid working directory
|
|
127
|
+
if (fs.existsSync(path.join(cliWorkDir, 'kite_cli', '__init__.py'))) {
|
|
128
|
+
// Delegate to kite_cli
|
|
129
|
+
const python = process.platform === 'win32' ? 'python' : 'python3';
|
|
130
|
+
const cliArgs = ['-m', 'kite_cli', ...args];
|
|
131
|
+
const result = spawn(python, cliArgs, {
|
|
132
|
+
cwd: cliWorkDir,
|
|
133
|
+
stdio: 'inherit',
|
|
134
|
+
env: {
|
|
135
|
+
...process.env,
|
|
136
|
+
KITE_PROJECT: cliWorkDir,
|
|
137
|
+
KITE_MODULES: modulesDir,
|
|
138
|
+
KITE_DATA: dataDir
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
result.on('exit', code => process.exit(code ?? 0));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
70
146
|
// ── Install: copy framework to ~/.kite/versions/{ver}/ if needed ──
|
|
71
147
|
|
|
72
148
|
function copyDirSync(src, dest) {
|
|
@@ -19,7 +19,113 @@ from datetime import datetime, timezone
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
# ── Module configuration ──
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
def _load_module_config() -> dict:
|
|
24
|
+
"""Load module configuration from module.md frontmatter.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Dict with keys: name, preferred_port, advertise_ip
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
SystemExit: If module.md is invalid or name is non-compliant
|
|
31
|
+
"""
|
|
32
|
+
_this_dir = os.path.dirname(os.path.abspath(__file__))
|
|
33
|
+
module_md = os.path.join(_this_dir, "module.md")
|
|
34
|
+
|
|
35
|
+
# Calculate relative path for error messages
|
|
36
|
+
project_root = os.environ.get("KITE_PROJECT", "")
|
|
37
|
+
if project_root and _this_dir.startswith(project_root):
|
|
38
|
+
rel_path = os.path.relpath(_this_dir, project_root)
|
|
39
|
+
else:
|
|
40
|
+
rel_path = _this_dir
|
|
41
|
+
|
|
42
|
+
# Default values (will be overridden if valid config exists)
|
|
43
|
+
result = {
|
|
44
|
+
"name": "",
|
|
45
|
+
"preferred_port": 0,
|
|
46
|
+
"advertise_ip": "0.0.0.0"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Check if module.md exists
|
|
50
|
+
if not os.path.exists(module_md):
|
|
51
|
+
print(f"[{rel_path}] ERROR: Invalid module configuration in module.md")
|
|
52
|
+
print(f" Path: {rel_path}/module.md")
|
|
53
|
+
print(f" Reason: File not found")
|
|
54
|
+
sys.exit(1)
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
with open(module_md, encoding="utf-8") as f:
|
|
58
|
+
text = f.read()
|
|
59
|
+
|
|
60
|
+
# Extract YAML frontmatter (between --- markers)
|
|
61
|
+
import re
|
|
62
|
+
m = re.match(r'^---\s*\n(.*?)\n---', text, re.DOTALL)
|
|
63
|
+
if not m:
|
|
64
|
+
print(f"[{rel_path}] ERROR: Invalid module configuration in module.md")
|
|
65
|
+
print(f" Path: {rel_path}/module.md")
|
|
66
|
+
print(f" Reason: Missing YAML frontmatter")
|
|
67
|
+
sys.exit(1)
|
|
68
|
+
|
|
69
|
+
# Parse YAML frontmatter
|
|
70
|
+
try:
|
|
71
|
+
import yaml
|
|
72
|
+
fm = yaml.safe_load(m.group(1)) or {}
|
|
73
|
+
except ImportError:
|
|
74
|
+
print(f"[{rel_path}] ERROR: PyYAML not installed, cannot parse module.md")
|
|
75
|
+
sys.exit(1)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
print(f"[{rel_path}] ERROR: Invalid module configuration in module.md")
|
|
78
|
+
print(f" Path: {rel_path}/module.md")
|
|
79
|
+
print(f" Reason: YAML parse error: {e}")
|
|
80
|
+
sys.exit(1)
|
|
81
|
+
|
|
82
|
+
# Validate 'name' field (required)
|
|
83
|
+
if "name" not in fm:
|
|
84
|
+
print(f"[{rel_path}] ERROR: Invalid module configuration in module.md")
|
|
85
|
+
print(f" Path: {rel_path}/module.md")
|
|
86
|
+
print(f" Reason: Missing 'name' field")
|
|
87
|
+
sys.exit(1)
|
|
88
|
+
|
|
89
|
+
raw_name = str(fm["name"]).strip()
|
|
90
|
+
|
|
91
|
+
if not raw_name:
|
|
92
|
+
print(f"[{rel_path}] ERROR: Invalid module configuration in module.md")
|
|
93
|
+
print(f" Path: {rel_path}/module.md")
|
|
94
|
+
print(f" Reason: Empty module name")
|
|
95
|
+
sys.exit(1)
|
|
96
|
+
|
|
97
|
+
# Validate name characters
|
|
98
|
+
sanitized = re.sub(r'[^a-zA-Z0-9_\-]', '', raw_name)
|
|
99
|
+
|
|
100
|
+
if sanitized != raw_name:
|
|
101
|
+
invalid_chars = ''.join(sorted(set(c for c in raw_name if c not in sanitized)))
|
|
102
|
+
print(f"[{rel_path}] ERROR: Invalid module configuration in module.md")
|
|
103
|
+
print(f" Path: {rel_path}/module.md")
|
|
104
|
+
print(f" Reason: Invalid characters in name '{raw_name}': {repr(invalid_chars)}")
|
|
105
|
+
sys.exit(1)
|
|
106
|
+
|
|
107
|
+
result["name"] = sanitized
|
|
108
|
+
|
|
109
|
+
# Extract optional fields
|
|
110
|
+
if "preferred_port" in fm:
|
|
111
|
+
try:
|
|
112
|
+
result["preferred_port"] = int(fm["preferred_port"])
|
|
113
|
+
except (ValueError, TypeError):
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
if "advertise_ip" in fm:
|
|
117
|
+
result["advertise_ip"] = str(fm["advertise_ip"])
|
|
118
|
+
|
|
119
|
+
except SystemExit:
|
|
120
|
+
raise # Re-raise exit to prevent catching by outer except
|
|
121
|
+
except Exception as e:
|
|
122
|
+
print(f"[{rel_path}] ERROR: Failed to read module.md: {e}")
|
|
123
|
+
sys.exit(1)
|
|
124
|
+
|
|
125
|
+
return result
|
|
126
|
+
|
|
127
|
+
_module_config = _load_module_config()
|
|
128
|
+
MODULE_NAME = _module_config["name"]
|
|
23
129
|
|
|
24
130
|
|
|
25
131
|
class _SafeWriter:
|
|
@@ -324,6 +430,10 @@ def main():
|
|
|
324
430
|
_print_crash_summary(type(e), e.__traceback__)
|
|
325
431
|
sys.exit(1)
|
|
326
432
|
|
|
433
|
+
# Check if server requested exit with non-zero code
|
|
434
|
+
if server._exit_code != 0:
|
|
435
|
+
sys.exit(server._exit_code)
|
|
436
|
+
|
|
327
437
|
|
|
328
438
|
if __name__ == "__main__":
|
|
329
439
|
main()
|