@agentunion/kite 1.4.0 → 1.5.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 (235) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/cli.js +44 -5
  3. package/core/dependency_checker.py +250 -0
  4. package/core/env_checker.py +490 -0
  5. package/dependencies_lock.json +128 -0
  6. package/extensions/agents/assistant/server.py +33 -17
  7. package/extensions/channels/acp_channel/server.py +33 -17
  8. package/extensions/services/backup/entry.py +23 -16
  9. package/extensions/services/evol/auth_manager.py +443 -0
  10. package/extensions/services/evol/config.yaml +149 -0
  11. package/extensions/services/evol/config_loader.py +117 -0
  12. package/extensions/services/evol/entry.py +406 -0
  13. package/extensions/services/evol/evol_api.py +173 -0
  14. package/extensions/services/evol/evol_config.json5 +29 -0
  15. package/extensions/services/evol/migrate_tokens.py +122 -0
  16. package/extensions/services/evol/module.md +32 -0
  17. package/extensions/services/evol/pairing.py +250 -0
  18. package/extensions/services/evol/pairing_codes.jsonl +1 -0
  19. package/extensions/services/evol/relay.py +682 -0
  20. package/extensions/services/evol/relay_config.json5 +67 -0
  21. package/extensions/services/evol/routes/__init__.py +1 -0
  22. package/extensions/services/evol/routes/routes_management_ws.py +127 -0
  23. package/extensions/services/evol/routes/routes_rpc.py +89 -0
  24. package/extensions/services/evol/routes/routes_test.py +61 -0
  25. package/extensions/services/evol/server.py +875 -0
  26. package/extensions/services/evol/static/css/style.css +1200 -0
  27. package/extensions/services/evol/static/index.html +781 -0
  28. package/extensions/services/evol/static/index_evol.html +14 -0
  29. package/extensions/services/evol/static/js/app.js +6304 -0
  30. package/extensions/services/evol/static/js/auth.js +326 -0
  31. package/extensions/services/evol/static/js/dialog.js +285 -0
  32. package/extensions/services/evol/static/js/evol-app-fixed.js +50 -0
  33. package/extensions/services/evol/static/js/evol-app.js +1949 -0
  34. package/extensions/services/evol/static/js/evol-app.js.bak +1800 -0
  35. package/extensions/services/evol/static/js/kernel-client-example.js +228 -0
  36. package/extensions/services/evol/static/js/kernel-client.js +396 -0
  37. package/extensions/services/evol/static/js/main.js +141 -0
  38. package/extensions/services/evol/static/js/registry-tests.js +585 -0
  39. package/extensions/services/evol/static/js/stats.js +217 -0
  40. package/extensions/services/evol/static/js/token-manager.js +175 -0
  41. package/extensions/services/evol/static/pairing.html +248 -0
  42. package/extensions/services/evol/static/test_registry.html +262 -0
  43. package/extensions/services/evol/static/test_relay.html +462 -0
  44. package/extensions/services/evol/stats_manager.py +240 -0
  45. package/extensions/services/model_service/entry.py +23 -1
  46. package/extensions/services/proxy/.claude/settings.local.json +13 -0
  47. package/extensions/services/proxy/CHANGELOG_20260308.md +258 -0
  48. package/extensions/services/proxy/_fix_prints.py +133 -0
  49. package/extensions/services/proxy/_fix_prints2.py +87 -0
  50. package/extensions/services/proxy/agentcp/LICENCE +178 -0
  51. package/extensions/services/proxy/agentcp/README copy.md +85 -0
  52. package/extensions/services/proxy/agentcp/README.md +260 -0
  53. package/extensions/services/proxy/agentcp/__init__.py +16 -0
  54. package/extensions/services/proxy/agentcp/agent.py +4 -0
  55. package/extensions/services/proxy/agentcp/agentcp.py +2494 -0
  56. package/extensions/services/proxy/agentcp/agentprofile.json +89 -0
  57. package/extensions/services/proxy/agentcp/ap/__init__.py +16 -0
  58. package/extensions/services/proxy/agentcp/ap/ap_client.py +316 -0
  59. package/extensions/services/proxy/agentcp/assets/images/wechat_qr.png +0 -0
  60. package/extensions/services/proxy/agentcp/backup/metrics.json +31 -0
  61. package/extensions/services/proxy/agentcp/base/__init__.py +20 -0
  62. package/extensions/services/proxy/agentcp/base/auth_client.py +257 -0
  63. package/extensions/services/proxy/agentcp/base/client.py +112 -0
  64. package/extensions/services/proxy/agentcp/base/env.py +34 -0
  65. package/extensions/services/proxy/agentcp/base/html_util.py +336 -0
  66. package/extensions/services/proxy/agentcp/base/log.py +98 -0
  67. package/extensions/services/proxy/agentcp/ca/__init__.py +17 -0
  68. package/extensions/services/proxy/agentcp/ca/ca_client.py +414 -0
  69. package/extensions/services/proxy/agentcp/ca/ca_root.py +74 -0
  70. package/extensions/services/proxy/agentcp/context/__init__.py +20 -0
  71. package/extensions/services/proxy/agentcp/context/context.py +73 -0
  72. package/extensions/services/proxy/agentcp/context/exceptions.py +114 -0
  73. package/extensions/services/proxy/agentcp/create_profile.py +125 -0
  74. package/extensions/services/proxy/agentcp/create_profile_weather.py +125 -0
  75. package/extensions/services/proxy/agentcp/db/__init__.py +15 -0
  76. package/extensions/services/proxy/agentcp/db/db_mananger.py +550 -0
  77. package/extensions/services/proxy/agentcp/docs/UDP_HEARTBEAT_FIX_REPORT.md +265 -0
  78. package/extensions/services/proxy/agentcp/docs/heartbeat_issue_analysis.md +291 -0
  79. package/extensions/services/proxy/agentcp/file/__init__.py +16 -0
  80. package/extensions/services/proxy/agentcp/file/file_client.py +141 -0
  81. package/extensions/services/proxy/agentcp/file/wss_binary_message.py +137 -0
  82. package/extensions/services/proxy/agentcp/hcp.py +299 -0
  83. package/extensions/services/proxy/agentcp/heartbeat/__init__.py +16 -0
  84. package/extensions/services/proxy/agentcp/heartbeat/heartbeat_client.py +360 -0
  85. package/extensions/services/proxy/agentcp/improved_scheduler.py +498 -0
  86. package/extensions/services/proxy/agentcp/llm_agent_utils.py +249 -0
  87. package/extensions/services/proxy/agentcp/llm_server.py +172 -0
  88. package/extensions/services/proxy/agentcp/mermaid.py +210 -0
  89. package/extensions/services/proxy/agentcp/message.py +149 -0
  90. package/extensions/services/proxy/agentcp/metrics.py +256 -0
  91. package/extensions/services/proxy/agentcp/monitoring/__init__.py +20 -0
  92. package/extensions/services/proxy/agentcp/monitoring/global_monitor.py +27 -0
  93. package/extensions/services/proxy/agentcp/monitoring/metrics_store.py +325 -0
  94. package/extensions/services/proxy/agentcp/monitoring/monitoring_service.py +269 -0
  95. package/extensions/services/proxy/agentcp/monitoring/sliding_window.py +222 -0
  96. package/extensions/services/proxy/agentcp/monitoring/standalone_reader.py +224 -0
  97. package/extensions/services/proxy/agentcp/msg/__init__.py +21 -0
  98. package/extensions/services/proxy/agentcp/msg/connection_manager.py +456 -0
  99. package/extensions/services/proxy/agentcp/msg/message_client.py +2058 -0
  100. package/extensions/services/proxy/agentcp/msg/message_serialize.py +263 -0
  101. package/extensions/services/proxy/agentcp/msg/open_ai_message.py +88 -0
  102. package/extensions/services/proxy/agentcp/msg/session_manager.py +1062 -0
  103. package/extensions/services/proxy/agentcp/msg/stream_client.py +267 -0
  104. package/extensions/services/proxy/agentcp/msg/websocket_file_receiver.py +89 -0
  105. package/extensions/services/proxy/agentcp/msg/ws_logger.py +685 -0
  106. package/extensions/services/proxy/agentcp/msg/wss_binary_message.py +137 -0
  107. package/extensions/services/proxy/agentcp/requirements.txt +7 -0
  108. package/extensions/services/proxy/agentcp/samples/agent_graph/README.md +37 -0
  109. package/extensions/services/proxy/agentcp/samples/agent_graph/agentprofile.json +89 -0
  110. package/extensions/services/proxy/agentcp/samples/agent_graph/create_profile.py +138 -0
  111. package/extensions/services/proxy/agentcp/samples/agent_graph/main.py +164 -0
  112. package/extensions/services/proxy/agentcp/samples/agent_use/create_profile.py +123 -0
  113. package/extensions/services/proxy/agentcp/samples/agent_use/llm/create_profile.py +129 -0
  114. package/extensions/services/proxy/agentcp/samples/agent_use/llm/env.json +5 -0
  115. package/extensions/services/proxy/agentcp/samples/agent_use/llm/main.py +146 -0
  116. package/extensions/services/proxy/agentcp/samples/agent_use/main.py +123 -0
  117. package/extensions/services/proxy/agentcp/samples/agent_use/readme.md +379 -0
  118. package/extensions/services/proxy/agentcp/samples/agent_use/search/create_profile.py +129 -0
  119. package/extensions/services/proxy/agentcp/samples/agent_use/search/main.py +28 -0
  120. package/extensions/services/proxy/agentcp/samples/agent_use/tool/create_profile.py +129 -0
  121. package/extensions/services/proxy/agentcp/samples/agent_use/tool/main.py +20 -0
  122. package/extensions/services/proxy/agentcp/samples/ali_amap/README.md +97 -0
  123. package/extensions/services/proxy/agentcp/samples/ali_amap/amap_agent.py +88 -0
  124. package/extensions/services/proxy/agentcp/samples/ali_amap/create_profile.py +125 -0
  125. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/powershell.py +228 -0
  126. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/software.py +63 -0
  127. package/extensions/services/proxy/agentcp/samples/compute_agent/agent/tools.py +36 -0
  128. package/extensions/services/proxy/agentcp/samples/compute_agent/browser_user.py +41 -0
  129. package/extensions/services/proxy/agentcp/samples/deepseek/README.md +79 -0
  130. package/extensions/services/proxy/agentcp/samples/deepseek/create_profile.py +126 -0
  131. package/extensions/services/proxy/agentcp/samples/deepseek/deepseek.py +42 -0
  132. package/extensions/services/proxy/agentcp/samples/dify_chat/README.md +78 -0
  133. package/extensions/services/proxy/agentcp/samples/dify_chat/create_profile.py +126 -0
  134. package/extensions/services/proxy/agentcp/samples/dify_chat/dify_chat.py +47 -0
  135. package/extensions/services/proxy/agentcp/samples/dify_workflow/README.md +78 -0
  136. package/extensions/services/proxy/agentcp/samples/dify_workflow/create_profile.py +126 -0
  137. package/extensions/services/proxy/agentcp/samples/dify_workflow/dify_workflow.py +46 -0
  138. package/extensions/services/proxy/agentcp/samples/executor/README.md +44 -0
  139. package/extensions/services/proxy/agentcp/samples/executor/agentprofile.json +89 -0
  140. package/extensions/services/proxy/agentcp/samples/executor/create_profile.py +139 -0
  141. package/extensions/services/proxy/agentcp/samples/executor/main.py +160 -0
  142. package/extensions/services/proxy/agentcp/samples/filereader/README.md +45 -0
  143. package/extensions/services/proxy/agentcp/samples/filereader/agentprofile.json +90 -0
  144. package/extensions/services/proxy/agentcp/samples/filereader/create_profile.py +137 -0
  145. package/extensions/services/proxy/agentcp/samples/filereader/main.py +253 -0
  146. package/extensions/services/proxy/agentcp/samples/filewriter/README.md +38 -0
  147. package/extensions/services/proxy/agentcp/samples/filewriter/agentprofile.json +91 -0
  148. package/extensions/services/proxy/agentcp/samples/filewriter/create_profile.py +138 -0
  149. package/extensions/services/proxy/agentcp/samples/filewriter/main.py +289 -0
  150. package/extensions/services/proxy/agentcp/samples/hcp/README.md +85 -0
  151. package/extensions/services/proxy/agentcp/samples/hcp/acp_weather_agent.zip +0 -0
  152. package/extensions/services/proxy/agentcp/samples/hcp/create_profile.py +125 -0
  153. package/extensions/services/proxy/agentcp/samples/hcp/hcp.py +237 -0
  154. package/extensions/services/proxy/agentcp/samples/helloworld/README.md +68 -0
  155. package/extensions/services/proxy/agentcp/samples/helloworld/hello_world.py +40 -0
  156. package/extensions/services/proxy/agentcp/samples/llm_agent/MEADME.md +117 -0
  157. package/extensions/services/proxy/agentcp/samples/llm_agent/create_profile.py +125 -0
  158. package/extensions/services/proxy/agentcp/samples/llm_agent/qwen_agent.py +136 -0
  159. package/extensions/services/proxy/agentcp/samples/local_llm_agent/README.md +90 -0
  160. package/extensions/services/proxy/agentcp/samples/local_llm_agent/create_profile.py +125 -0
  161. package/extensions/services/proxy/agentcp/samples/local_llm_agent/main.py +49 -0
  162. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/README.md +55 -0
  163. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/create_profile.py +125 -0
  164. package/extensions/services/proxy/agentcp/samples/query_llm_from_agent/main.py +23 -0
  165. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/README.md +103 -0
  166. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/create_profile.py +125 -0
  167. package/extensions/services/proxy/agentcp/samples/query_weather_api_agent/main.py +69 -0
  168. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/README.md +58 -0
  169. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/create_profile.py +125 -0
  170. package/extensions/services/proxy/agentcp/samples/query_weather_from_agent/main.py +25 -0
  171. package/extensions/services/proxy/agentcp/samples/qwen3/README.md +71 -0
  172. package/extensions/services/proxy/agentcp/samples/qwen3/create_profile.py +126 -0
  173. package/extensions/services/proxy/agentcp/samples/qwen3/qwen3.py +37 -0
  174. package/extensions/services/proxy/agentcp/samples/qwen3_tools/README.md +133 -0
  175. package/extensions/services/proxy/agentcp/samples/qwen3_tools/create_profile.py +126 -0
  176. package/extensions/services/proxy/agentcp/samples/qwen3_tools/qwen3_tools.py +98 -0
  177. package/extensions/services/proxy/agentcp/samples/search/create_profile_qwen.py +125 -0
  178. package/extensions/services/proxy/agentcp/samples/search/create_profile_search.py +125 -0
  179. package/extensions/services/proxy/agentcp/samples/search/qwen_agent.py +136 -0
  180. package/extensions/services/proxy/agentcp/samples/search/search_agent.py +170 -0
  181. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/README.md +89 -0
  182. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/create_profile.py +125 -0
  183. package/extensions/services/proxy/agentcp/samples/wrapper_agently_to_agent/main.py +44 -0
  184. package/extensions/services/proxy/agentcp/utils/__init__.py +15 -0
  185. package/extensions/services/proxy/agentcp/utils/file_util.py +117 -0
  186. package/extensions/services/proxy/agentcp/utils/proxy_bypass.py +99 -0
  187. package/extensions/services/proxy/agentcp/workflow.py +203 -0
  188. package/extensions/services/proxy/console_auth.py +109 -0
  189. package/extensions/services/proxy/evol/__init__.py +1 -0
  190. package/extensions/services/proxy/evol/config.py +37 -0
  191. package/extensions/services/proxy/evol/http/__init__.py +1 -0
  192. package/extensions/services/proxy/evol/http/async_http.py +551 -0
  193. package/extensions/services/proxy/evol/log.py +28 -0
  194. package/extensions/services/proxy/evol/presenter/__init__.py +2 -0
  195. package/extensions/services/proxy/evol/presenter/agentIdPresenter.py +1031 -0
  196. package/extensions/services/proxy/evol/presenter/apikeyPresenter.py +106 -0
  197. package/extensions/services/proxy/evol/presenter/configPresenter.py +1281 -0
  198. package/extensions/services/proxy/evol/presenter/userPresenter.py +477 -0
  199. package/extensions/services/proxy/evol/server/__init__.py +1 -0
  200. package/extensions/services/proxy/evol/server/claude_proxy_async.py +3430 -0
  201. package/extensions/services/proxy/evol/server/openclaw_proxy.py +1861 -0
  202. package/extensions/services/proxy/evol/server/proxy_config.py +15 -0
  203. package/extensions/services/proxy/evol/server/proxy_engine.py +501 -0
  204. package/extensions/services/proxy/evol/version.py +24 -0
  205. package/extensions/services/proxy/logs/websocket.log +260 -0
  206. package/extensions/services/proxy/main.py +240 -0
  207. package/extensions/services/proxy/requirements.txt +13 -0
  208. package/extensions/services/proxy/server.py +271 -0
  209. package/extensions/services/watchdog/entry.py +42 -16
  210. package/extensions/services/watchdog/module.md +1 -0
  211. package/extensions/services/watchdog/monitor.py +34 -4
  212. package/extensions/services/web/module.md +1 -1
  213. package/extensions/services/web/server.py +30 -18
  214. package/extensions/services/web/static/js/token-manager.js +10 -10
  215. package/kernel/entry.py +1 -1
  216. package/kernel/module.md +25 -1
  217. package/kernel/registry_store.py +2 -26
  218. package/kernel/rpc_router.py +36 -10
  219. package/kernel/server.py +106 -17
  220. package/kite_cli/commands/deps_install.py +67 -0
  221. package/kite_cli/commands/env_check.py +45 -0
  222. package/kite_cli/commands/prepare.py +49 -0
  223. package/kite_cli/commands/venv_setup.py +56 -0
  224. package/kite_cli/main.py +29 -1
  225. package/launcher/entry.py +306 -21
  226. package/launcher/module.md +9 -0
  227. package/launcher/module_scanner.py +11 -1
  228. package/main.py +4 -1
  229. package/package.json +8 -1
  230. package/python_version.json +4 -0
  231. package/requirements.txt +38 -0
  232. package/scripts/env-manager.js +328 -0
  233. package/scripts/python-env.js +79 -0
  234. package/scripts/scan_dependencies.py +461 -0
  235. package/scripts/setup-python-env.js +191 -0
@@ -0,0 +1,781 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Evol 账户管理</title>
7
+ <link rel="stylesheet" href="css/style.css">
8
+ <script>
9
+ // 在 DOM 加载前判断 token,避免闪烁
10
+ (function() {
11
+ function getCookie(name) {
12
+ const value = `; ${document.cookie}`;
13
+ const parts = value.split(`; ${name}=`);
14
+ if (parts.length === 2) return parts.pop().split(';').shift();
15
+ return null;
16
+ }
17
+
18
+ const hasToken = localStorage.getItem('kiteToken') || getCookie('kiteToken');
19
+ if (hasToken) {
20
+ // 有 token,默认显示主页面
21
+ document.documentElement.classList.add('has-token');
22
+ }
23
+ })();
24
+ </script>
25
+ <style>
26
+ /* 页面显示控制 */
27
+ html.has-token #login-page { display: none !important; }
28
+ html.has-token #main-app { display: block !important; }
29
+ html:not(.has-token) #login-page { display: flex !important; }
30
+ html:not(.has-token) #main-app { display: none !important; }
31
+
32
+ /* 登录页面样式方案切换 - 在 body 添加 data-login-theme 属性 */
33
+ /* 方案 1: 极简商务风 - theme-minimal */
34
+ /* 方案 2: 现代扁平风 - theme-flat */
35
+ /* 方案 3: 传统表单风 - theme-classic */
36
+
37
+ /* === 方案 1: 极简商务风 === */
38
+ body[data-login-theme="theme-minimal"] .login-container {
39
+ display: flex;
40
+ justify-content: center;
41
+ align-items: center;
42
+ min-height: 100vh;
43
+ background: #f5f5f5;
44
+ }
45
+ body[data-login-theme="theme-minimal"] .login-box {
46
+ background: white;
47
+ padding: 48px 40px;
48
+ border-radius: 2px;
49
+ box-shadow: 0 2px 8px rgba(0,0,0,0.08);
50
+ width: 100%;
51
+ max-width: 360px;
52
+ border-top: 3px solid #333;
53
+ }
54
+ body[data-login-theme="theme-minimal"] .login-title {
55
+ font-size: 24px;
56
+ font-weight: 400;
57
+ margin-bottom: 32px;
58
+ color: #333;
59
+ letter-spacing: 0.5px;
60
+ }
61
+ body[data-login-theme="theme-minimal"] .form-label {
62
+ display: block;
63
+ margin-bottom: 8px;
64
+ font-weight: 400;
65
+ color: #666;
66
+ font-size: 13px;
67
+ }
68
+ body[data-login-theme="theme-minimal"] .form-input {
69
+ width: 100%;
70
+ padding: 10px 12px;
71
+ border: 1px solid #ddd;
72
+ border-radius: 2px;
73
+ font-size: 14px;
74
+ box-sizing: border-box;
75
+ transition: border-color 0.2s;
76
+ }
77
+ body[data-login-theme="theme-minimal"] .form-input:focus {
78
+ outline: none;
79
+ border-color: #333;
80
+ }
81
+ body[data-login-theme="theme-minimal"] .btn-primary {
82
+ width: 100%;
83
+ padding: 11px;
84
+ background: #333;
85
+ color: white;
86
+ border: none;
87
+ border-radius: 2px;
88
+ font-size: 14px;
89
+ font-weight: 400;
90
+ cursor: pointer;
91
+ transition: background 0.2s;
92
+ }
93
+ body[data-login-theme="theme-minimal"] .btn-primary:hover {
94
+ background: #000;
95
+ }
96
+ body[data-login-theme="theme-minimal"] .btn-primary:disabled {
97
+ background: #ccc;
98
+ cursor: not-allowed;
99
+ }
100
+
101
+ /* === 方案 2: 现代扁平风 === */
102
+ body[data-login-theme="theme-flat"] .login-container {
103
+ display: flex;
104
+ justify-content: center;
105
+ align-items: center;
106
+ min-height: 100vh;
107
+ background: #fafafa;
108
+ }
109
+ body[data-login-theme="theme-flat"] .login-box {
110
+ background: white;
111
+ padding: 40px;
112
+ border-radius: 8px;
113
+ box-shadow: 0 1px 3px rgba(0,0,0,0.06);
114
+ width: 100%;
115
+ max-width: 380px;
116
+ border: 1px solid #e8e8e8;
117
+ }
118
+ body[data-login-theme="theme-flat"] .login-title {
119
+ font-size: 22px;
120
+ font-weight: 500;
121
+ margin-bottom: 28px;
122
+ color: #1a1a1a;
123
+ }
124
+ body[data-login-theme="theme-flat"] .form-label {
125
+ display: block;
126
+ margin-bottom: 6px;
127
+ font-weight: 500;
128
+ color: #4a4a4a;
129
+ font-size: 13px;
130
+ }
131
+ body[data-login-theme="theme-flat"] .form-input {
132
+ width: 100%;
133
+ padding: 11px 14px;
134
+ border: 1px solid #e0e0e0;
135
+ border-radius: 4px;
136
+ font-size: 14px;
137
+ box-sizing: border-box;
138
+ background: #fafafa;
139
+ transition: all 0.2s;
140
+ }
141
+ body[data-login-theme="theme-flat"] .form-input:focus {
142
+ outline: none;
143
+ border-color: #4a90e2;
144
+ background: white;
145
+ }
146
+ body[data-login-theme="theme-flat"] .btn-primary {
147
+ width: 100%;
148
+ padding: 12px;
149
+ background: #4a90e2;
150
+ color: white;
151
+ border: none;
152
+ border-radius: 4px;
153
+ font-size: 14px;
154
+ font-weight: 500;
155
+ cursor: pointer;
156
+ transition: background 0.2s;
157
+ }
158
+ body[data-login-theme="theme-flat"] .btn-primary:hover {
159
+ background: #357abd;
160
+ }
161
+ body[data-login-theme="theme-flat"] .btn-primary:disabled {
162
+ background: #d0d0d0;
163
+ cursor: not-allowed;
164
+ }
165
+
166
+ /* === 方案 3: 传统表单风 === */
167
+ body[data-login-theme="theme-classic"] .login-container {
168
+ display: flex;
169
+ justify-content: center;
170
+ align-items: center;
171
+ min-height: 100vh;
172
+ background: #e9ecef;
173
+ }
174
+ body[data-login-theme="theme-classic"] .login-box {
175
+ background: white;
176
+ padding: 36px 32px;
177
+ border-radius: 4px;
178
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
179
+ width: 100%;
180
+ max-width: 400px;
181
+ }
182
+ body[data-login-theme="theme-classic"] .login-title {
183
+ font-size: 20px;
184
+ font-weight: 600;
185
+ margin-bottom: 24px;
186
+ color: #212529;
187
+ text-align: center;
188
+ border-bottom: 2px solid #dee2e6;
189
+ padding-bottom: 12px;
190
+ }
191
+ body[data-login-theme="theme-classic"] .form-label {
192
+ display: block;
193
+ margin-bottom: 6px;
194
+ font-weight: 600;
195
+ color: #495057;
196
+ font-size: 13px;
197
+ }
198
+ body[data-login-theme="theme-classic"] .form-input {
199
+ width: 100%;
200
+ padding: 10px 12px;
201
+ border: 1px solid #ced4da;
202
+ border-radius: 3px;
203
+ font-size: 14px;
204
+ box-sizing: border-box;
205
+ transition: border-color 0.15s;
206
+ }
207
+ body[data-login-theme="theme-classic"] .form-input:focus {
208
+ outline: none;
209
+ border-color: #80bdff;
210
+ box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
211
+ }
212
+ body[data-login-theme="theme-classic"] .btn-primary {
213
+ width: 100%;
214
+ padding: 10px;
215
+ background: #007bff;
216
+ color: white;
217
+ border: none;
218
+ border-radius: 3px;
219
+ font-size: 14px;
220
+ font-weight: 600;
221
+ cursor: pointer;
222
+ transition: background 0.15s;
223
+ }
224
+ body[data-login-theme="theme-classic"] .btn-primary:hover {
225
+ background: #0056b3;
226
+ }
227
+ body[data-login-theme="theme-classic"] .btn-primary:disabled {
228
+ background: #6c757d;
229
+ cursor: not-allowed;
230
+ }
231
+
232
+ /* 通用样式 */
233
+ .form-group {
234
+ margin-bottom: 20px;
235
+ }
236
+ .error-msg {
237
+ color: #e74c3c;
238
+ font-size: 14px;
239
+ margin-top: 10px;
240
+ text-align: center;
241
+ }
242
+ .success-msg {
243
+ color: #27ae60;
244
+ font-size: 14px;
245
+ margin-top: 10px;
246
+ text-align: center;
247
+ }
248
+ .hidden {
249
+ display: none !important;
250
+ }
251
+
252
+ /* 标签页样式 */
253
+ .tabs {
254
+ display: flex;
255
+ gap: 2px;
256
+ margin-bottom: 20px;
257
+ border-bottom: 2px solid #e0e0e0;
258
+ }
259
+ .tab {
260
+ padding: 10px 20px;
261
+ background: transparent;
262
+ border: none;
263
+ border-bottom: 2px solid transparent;
264
+ margin-bottom: -2px;
265
+ cursor: pointer;
266
+ font-size: 14px;
267
+ color: #666;
268
+ transition: all 0.2s;
269
+ }
270
+ .tab:hover {
271
+ color: #333;
272
+ background: #f5f5f5;
273
+ }
274
+ .tab.active {
275
+ color: #007bff;
276
+ border-bottom-color: #007bff;
277
+ font-weight: 600;
278
+ }
279
+ .tab-content {
280
+ display: none;
281
+ }
282
+ .tab-content.active {
283
+ display: block;
284
+ }
285
+
286
+
287
+ /* 默认使用方案 1 */
288
+ body:not([data-login-theme]) {
289
+ --login-theme: theme-minimal;
290
+ }
291
+ body:not([data-login-theme]) .login-container {
292
+ display: flex;
293
+ justify-content: center;
294
+ align-items: center;
295
+ min-height: 100vh;
296
+ background: #f5f5f5;
297
+ }
298
+ body:not([data-login-theme]) .login-box {
299
+ background: white;
300
+ padding: 48px 40px;
301
+ border-radius: 2px;
302
+ box-shadow: 0 2px 8px rgba(0,0,0,0.08);
303
+ width: 100%;
304
+ max-width: 360px;
305
+ border-top: 3px solid #333;
306
+ }
307
+ body:not([data-login-theme]) .login-title {
308
+ font-size: 24px;
309
+ font-weight: 400;
310
+ margin-bottom: 32px;
311
+ color: #333;
312
+ letter-spacing: 0.5px;
313
+ }
314
+ body:not([data-login-theme]) .form-label {
315
+ display: block;
316
+ margin-bottom: 8px;
317
+ font-weight: 400;
318
+ color: #666;
319
+ font-size: 13px;
320
+ }
321
+ body:not([data-login-theme]) .form-input {
322
+ width: 100%;
323
+ padding: 10px 12px;
324
+ border: 1px solid #ddd;
325
+ border-radius: 2px;
326
+ font-size: 14px;
327
+ box-sizing: border-box;
328
+ transition: border-color 0.2s;
329
+ }
330
+ body:not([data-login-theme]) .form-input:focus {
331
+ outline: none;
332
+ border-color: #333;
333
+ }
334
+ body:not([data-login-theme]) .btn-primary {
335
+ width: 100%;
336
+ padding: 11px;
337
+ background: #333;
338
+ color: white;
339
+ border: none;
340
+ border-radius: 2px;
341
+ font-size: 14px;
342
+ font-weight: 400;
343
+ cursor: pointer;
344
+ transition: background 0.2s;
345
+ }
346
+ body:not([data-login-theme]) .btn-primary:hover {
347
+ background: #000;
348
+ }
349
+ body:not([data-login-theme]) .btn-primary:disabled {
350
+ background: #ccc;
351
+ cursor: not-allowed;
352
+ }
353
+ </style>
354
+ </head>
355
+ <body>
356
+ <!--
357
+ 登录页面样式方案切换:
358
+ 方案 1(默认): 极简商务风 - 不设置或 data-login-theme="theme-minimal"
359
+ 方案 2: 现代扁平风 - data-login-theme="theme-flat"
360
+ 方案 3: 传统表单风 - data-login-theme="theme-classic"
361
+
362
+ 切换方法:在 <body> 标签添加 data-login-theme 属性
363
+ 例如:<body data-login-theme="theme-flat">
364
+ -->
365
+
366
+ <!-- Login Page -->
367
+ <div id="login-page" class="login-container">
368
+ <!-- 样式切换按钮 -->
369
+ <div style="position:absolute;top:20px;right:20px;display:flex;gap:8px;z-index:10;">
370
+ <button onclick="document.body.removeAttribute('data-login-theme')" style="padding:8px 16px;border:1px solid #ddd;background:white;border-radius:4px;cursor:pointer;font-size:13px;transition:all 0.2s;" onmouseover="this.style.background='#f5f5f5'" onmouseout="this.style.background='white'">极简商务</button>
371
+ <button onclick="document.body.setAttribute('data-login-theme','theme-flat')" style="padding:8px 16px;border:1px solid #ddd;background:white;border-radius:4px;cursor:pointer;font-size:13px;transition:all 0.2s;" onmouseover="this.style.background='#f5f5f5'" onmouseout="this.style.background='white'">现代扁平</button>
372
+ <button onclick="document.body.setAttribute('data-login-theme','theme-classic')" style="padding:8px 16px;border:1px solid #ddd;background:white;border-radius:4px;cursor:pointer;font-size:13px;transition:all 0.2s;" onmouseover="this.style.background='#f5f5f5'" onmouseout="this.style.background='white'">传统表单</button>
373
+ </div>
374
+
375
+ <div class="login-box">
376
+ <h1 class="login-title">Evol 账户登录</h1>
377
+ <div class="form-group">
378
+ <label class="form-label">手机号</label>
379
+ <input type="tel" id="login-phone" class="form-input" placeholder="请输入手机号" maxlength="11">
380
+ </div>
381
+ <div class="form-group">
382
+ <label class="form-label">验证码</label>
383
+ <div style="display: flex; gap: 10px;">
384
+ <input type="text" id="login-code" class="form-input" placeholder="请输入验证码" maxlength="6" style="flex: 1;" onkeypress="if(event.key==='Enter' && this.value.length===6) document.getElementById('btn-login').click()">
385
+ <button id="btn-send-code" class="btn-primary" style="width: auto; padding: 12px 20px;">发送验证码</button>
386
+ </div>
387
+ </div>
388
+ <button id="btn-login" class="btn-primary">登录</button>
389
+ <div id="login-message"></div>
390
+ </div>
391
+ </div>
392
+
393
+ <!-- Main App -->
394
+ <div id="main-app">
395
+ <header id="app-header">
396
+ <div class="header-left">
397
+ <button id="sidebar-toggle" class="icon-btn">&#9776;</button>
398
+ <h1 class="header-title">Evol 控制台</h1>
399
+ </div>
400
+ <div class="header-right">
401
+ <span id="ws-indicator" style="font-size:13px;color:#999;margin-right:16px;">○ 未连接</span>
402
+
403
+ <!-- 未登录状态 -->
404
+ <a id="login-btn" href="javascript:void(0)" class="hidden" style="color:#667eea;text-decoration:none;font-size:14px;">登录 Evol</a>
405
+
406
+ <!-- 已登录状态 -->
407
+ <div id="user-info-area" class="hidden" style="align-items:center;gap:12px;font-size:14px;">
408
+ <span class="user-name" style="color:#333;font-weight:500;"></span>
409
+ <span class="user-credits" style="color:#666;font-size:13px;"></span>
410
+ <span style="color:#ddd;">|</span>
411
+ <a id="btn-logout" href="javascript:void(0)" style="color:#999;text-decoration:none;" onmouseover="this.style.color='#667eea'" onmouseout="this.style.color='#999'">退出</a>
412
+ </div>
413
+ </div>
414
+ </header>
415
+
416
+ <div id="app-layout">
417
+ <nav id="sidebar">
418
+ <ul class="nav-list">
419
+ <li class="nav-item active" data-page="account">
420
+ <span class="nav-label">账户信息</span>
421
+ <span class="nav-sublabel">Account</span>
422
+ </li>
423
+ <li class="nav-item" data-page="credits">
424
+ <span class="nav-label">积分统计</span>
425
+ <span class="nav-sublabel">Credits</span>
426
+ </li>
427
+ <li class="nav-item" data-page="modules">
428
+ <span class="nav-label">模块管理</span>
429
+ <span class="nav-sublabel">Modules</span>
430
+ </li>
431
+ <li class="nav-item" data-page="tokens">
432
+ <span class="nav-label">Token管理</span>
433
+ <span class="nav-sublabel">Tokens</span>
434
+ </li>
435
+ </ul>
436
+ </nav>
437
+
438
+ <main id="main-content">
439
+ <!-- Account Info -->
440
+ <section id="page-account" class="page active">
441
+ <h2 class="page-title">账户信息</h2>
442
+ <div class="panel">
443
+ <div id="account-info">加载中...</div>
444
+ </div>
445
+ </section>
446
+
447
+ <!-- Credits Stats -->
448
+ <section id="page-credits" class="page">
449
+ <h2 class="page-title">积分统计</h2>
450
+ <div class="panel">
451
+ <div id="credits-stats">加载中...</div>
452
+ </div>
453
+ </section>
454
+
455
+ <!-- Modules Management -->
456
+ <section id="page-modules" class="page">
457
+ <div id="modules-list-header" style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;">
458
+ <div style="display:flex;align-items:center;gap:12px;">
459
+ <h2 class="page-title" style="margin-bottom:0;">模块管理</h2>
460
+ <span id="module-save-status" class="config-save-status"></span>
461
+ </div>
462
+ <div style="display:flex;align-items:center;gap:16px;">
463
+ <button class="btn btn-sm btn-secondary" id="btn-toggle-console">
464
+ <span id="console-toggle-text">展开控制台</span>
465
+ </button>
466
+ <button class="btn btn-warning" id="btn-restart-kite" style="display:flex;align-items:center;gap:6px;">
467
+ <span>重启 Kite</span>
468
+ </button>
469
+ </div>
470
+ </div>
471
+
472
+ <!-- Real-time Console (collapsible) -->
473
+ <div id="realtime-console" class="panel" style="display:none;margin-bottom:20px;">
474
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;">
475
+ <h3 style="margin:0;font-size:14px;font-weight:600;">实时事件日志</h3>
476
+ <button class="btn btn-sm btn-secondary" id="btn-clear-console">清空</button>
477
+ </div>
478
+
479
+ <!-- 筛选器 -->
480
+ <div style="display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:10px;margin-bottom:10px;padding:12px;background:#f5f5f5;border-radius:4px;">
481
+ <div>
482
+ <label style="display:block;margin-bottom:4px;font-size:12px;color:#666;">模块</label>
483
+ <select id="filter-module" style="width:100%;padding:6px;border:1px solid #ddd;border-radius:3px;font-size:12px;">
484
+ <option value="">全部模块</option>
485
+ </select>
486
+ </div>
487
+ <div>
488
+ <label style="display:block;margin-bottom:4px;font-size:12px;color:#666;">事件类型</label>
489
+ <select id="filter-event" style="width:100%;padding:6px;border:1px solid #ddd;border-radius:3px;font-size:12px;">
490
+ <option value="">全部事件</option>
491
+ </select>
492
+ </div>
493
+ <div>
494
+ <label style="display:block;margin-bottom:4px;font-size:12px;color:#666;">关键词 (glob)</label>
495
+ <input type="text" id="filter-keyword" placeholder="例: *error*" style="width:100%;padding:6px;border:1px solid #ddd;border-radius:3px;font-size:12px;">
496
+ </div>
497
+ <div>
498
+ <label style="display:block;margin-bottom:4px;font-size:12px;color:#666;">时间范围</label>
499
+ <select id="filter-time" style="width:100%;padding:6px;border:1px solid #ddd;border-radius:3px;font-size:12px;">
500
+ <option value="0">全部时间</option>
501
+ <option value="300">最近5分钟</option>
502
+ <option value="1800">最近30分钟</option>
503
+ <option value="3600">最近1小时</option>
504
+ <option value="21600">最近6小时</option>
505
+ <option value="86400" selected>最近24小时</option>
506
+ </select>
507
+ </div>
508
+ </div>
509
+
510
+ <div id="console-output" style="background:#1e1e1e;color:#d4d4d4;padding:12px;border-radius:4px;font-family:monospace;font-size:12px;height:300px;overflow-y:auto;white-space:pre-wrap;line-height:1.4;"></div>
511
+ </div>
512
+
513
+ <!-- Statistics Panel -->
514
+ <div class="panel" style="margin-bottom:20px;" id="statistics-panel">
515
+ <div class="stats-grid">
516
+ <div class="stat-item" data-stat-type="uptime">
517
+ <div class="stat-label">运行时长</div>
518
+ <div class="stat-value" id="stat-uptime">--</div>
519
+ </div>
520
+ <div class="stat-item" data-stat-type="modules">
521
+ <div class="stat-label">模块数量</div>
522
+ <div class="stat-value" id="stat-modules">--</div>
523
+ </div>
524
+ <div class="stat-item" data-stat-type="registry">
525
+ <div class="stat-label">注册记录</div>
526
+ <div class="stat-value" id="stat-registry">--</div>
527
+ </div>
528
+ <div class="stat-item" data-stat-type="rpc">
529
+ <div class="stat-label">RPC 方法</div>
530
+ <div class="stat-value" id="stat-rpc">--</div>
531
+ </div>
532
+ <div class="stat-item" data-stat-type="hooks">
533
+ <div class="stat-label">Hook 数量</div>
534
+ <div class="stat-value" id="stat-hooks">--</div>
535
+ </div>
536
+ <div class="stat-item" data-stat-type="api">
537
+ <div class="stat-label">API 端点</div>
538
+ <div class="stat-value" id="stat-api">--</div>
539
+ </div>
540
+ <div class="stat-item" data-stat-type="events">
541
+ <div class="stat-label">事件处理</div>
542
+ <div class="stat-value" id="stat-events">--</div>
543
+ </div>
544
+ <div class="stat-item" data-stat-type="rpc-calls">
545
+ <div class="stat-label">RPC 调用</div>
546
+ <div class="stat-value" id="stat-rpc-calls">--</div>
547
+ </div>
548
+ </div>
549
+ </div>
550
+
551
+ <!-- Tooltip for statistics -->
552
+ <div id="stat-tooltip" class="stat-tooltip"></div>
553
+
554
+ <!-- Module List Table -->
555
+ <div class="panel">
556
+ <div class="table-wrapper">
557
+ <table class="data-table" id="modules-table">
558
+ <thead>
559
+ <tr>
560
+ <th style="width:40px;"></th>
561
+ <th>模块</th>
562
+ <th>类型</th>
563
+ <th>版本</th>
564
+ <th>端口</th>
565
+ <th>进程ID</th>
566
+ <th>启动耗时</th>
567
+ <th>运行时长</th>
568
+ <th>Ping</th>
569
+ <th>运行状态</th>
570
+ <th>默认状态</th>
571
+ <th style="width:100px;">操作</th>
572
+ </tr>
573
+ </thead>
574
+ <tbody id="modules-tbody">
575
+ <tr><td colspan="12" class="text-muted" style="text-align:center;padding:40px;">加载中...</td></tr>
576
+ </tbody>
577
+ </table>
578
+ </div>
579
+ </div>
580
+
581
+ <!-- Registry Test Section -->
582
+ <div id="registry-test-section" style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;margin-top:40px;">
583
+ <div style="display:flex;align-items:center;gap:12px;">
584
+ <h2 class="page-title" style="margin-bottom:0;">注册中心测试</h2>
585
+ </div>
586
+ <div style="display:flex;align-items:center;gap:16px;">
587
+ <button class="btn btn-sm btn-primary" id="btn-test-registry">运行测试</button>
588
+ <button class="btn btn-sm btn-secondary" id="btn-clear-test-output">清空输出</button>
589
+ </div>
590
+ </div>
591
+
592
+ <div class="panel" id="registry-test-output">
593
+ <div id="test-output" style="background:#1e1e1e;color:#d4d4d4;padding:15px;border-radius:4px;font-family:monospace;font-size:13px;max-height:400px;overflow-y:auto;white-space:pre-wrap;"></div>
594
+ </div>
595
+
596
+ <!-- Module Detail Panel (hidden by default) -->
597
+ <div id="module-detail" class="hidden">
598
+ <!-- 头部 -->
599
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;width:100%;">
600
+ <!-- 左侧:返回 + 标题 -->
601
+ <div style="display:flex;align-items:center;">
602
+ <button id="btn-module-back" style="background:none;border:none;cursor:pointer;padding:4px 0;font-size:14px;color:var(--primary);">&lt; 返回</button>
603
+ <h3 id="module-detail-name" style="font-size:18px;font-weight:600;color:#333;margin:0 0 0 20px;"></h3>
604
+ </div>
605
+ <!-- 右侧:运行状态 + 操作按钮 -->
606
+ <div style="display:flex;align-items:center;gap:12px;">
607
+ <div style="display:flex;align-items:center;gap:6px;">
608
+ <span id="module-detail-status-dot" class="module-state-dot" style="width:8px;height:8px;border-radius:50%;display:inline-block;"></span>
609
+ <span id="module-detail-run-status" style="font-size:13px;"></span>
610
+ </div>
611
+ <button class="btn btn-sm btn-secondary" id="btn-reset-defaults">恢复默认值</button>
612
+ <button class="btn btn-sm" id="btn-detail-action" style="min-width:72px;"></button>
613
+ </div>
614
+ </div>
615
+
616
+ <!-- 【区块1:模块标识】 -->
617
+ <div class="form-section" style="background:#f9f9f9;padding:16px;border-radius:6px;margin-bottom:16px;">
618
+ <h4 style="margin:0 0 12px 0;font-size:14px;font-weight:600;color:#666;">模块标识</h4>
619
+
620
+ <!-- 模块路径 -->
621
+ <div style="margin-bottom:12px;">
622
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">模块路径 <span style="font-size:11px;color:#999;">(source_path)</span></label>
623
+ <input type="text" id="mod-source-path" disabled style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;background:#e9ecef;cursor:not-allowed;font-size:12px;font-family:monospace;box-sizing:border-box;">
624
+ </div>
625
+
626
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px;">
627
+ <div>
628
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">模块名 <span style="font-size:11px;color:#999;">(name)</span></label>
629
+ <input type="text" id="mod-meta-name" disabled style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;background:#e9ecef;cursor:not-allowed;box-sizing:border-box;">
630
+ </div>
631
+ <div>
632
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">模块类型 <span style="font-size:11px;color:#999;">(type)</span></label>
633
+ <input type="text" id="mod-meta-type" disabled style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;background:#e9ecef;cursor:not-allowed;box-sizing:border-box;">
634
+ </div>
635
+ </div>
636
+
637
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px;">
638
+ <div>
639
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">运行时 <span style="font-size:11px;color:#999;">(runtime)</span></label>
640
+ <input type="text" id="mod-meta-runtime" disabled style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;background:#e9ecef;cursor:not-allowed;box-sizing:border-box;">
641
+ </div>
642
+ <div>
643
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">入口文件 <span style="font-size:11px;color:#999;">(entry)</span></label>
644
+ <input type="text" id="mod-meta-entry" disabled style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;background:#e9ecef;cursor:not-allowed;box-sizing:border-box;">
645
+ </div>
646
+ </div>
647
+
648
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
649
+ <div>
650
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">版本 <span style="font-size:11px;color:#999;">(version)</span></label>
651
+ <input type="text" id="mod-meta-version" disabled style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;background:#e9ecef;cursor:not-allowed;box-sizing:border-box;">
652
+ </div>
653
+ <div>
654
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">显示名称 <span style="font-size:11px;color:#999;">(display_name)</span></label>
655
+ <input type="text" id="mod-meta-display-name" data-field="display_name" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;">
656
+ </div>
657
+ </div>
658
+ </div>
659
+
660
+ <!-- 【区块2:启动配置】 -->
661
+ <div class="form-section" style="background:#f9f9f9;padding:16px;border-radius:6px;margin-bottom:16px;">
662
+ <h4 style="margin:0 0 12px 0;font-size:14px;font-weight:600;color:#666;">启动配置</h4>
663
+
664
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
665
+ <div>
666
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">默认状态 <span style="font-size:11px;color:#999;">(state - 需重启生效)</span></label>
667
+ <select id="mod-meta-state" data-field="state" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;">
668
+ <option value="enabled">enabled - 自动启动</option>
669
+ <option value="manual">manual - 手动启动</option>
670
+ <option value="disabled">disabled - 禁用</option>
671
+ </select>
672
+ </div>
673
+ <div>
674
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">监控 <span style="font-size:11px;color:#999;">(monitor - Watchdog是否监控此模块)</span></label>
675
+ <select id="mod-meta-monitor" data-field="monitor" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;">
676
+ <option value="true">启用监控 (默认)</option>
677
+ <option value="false">禁用监控</option>
678
+ </select>
679
+ </div>
680
+ </div>
681
+ </div>
682
+
683
+ <!-- 【区块3:网络配置】 -->
684
+ <div class="form-section" style="background:#f9f9f9;padding:16px;border-radius:6px;margin-bottom:16px;">
685
+ <h4 style="margin:0 0 12px 0;font-size:14px;font-weight:600;color:#666;">网络配置</h4>
686
+
687
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
688
+ <div>
689
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">首选端口 <span style="font-size:11px;color:#999;">(preferred_port)</span></label>
690
+ <input type="number" id="mod-meta-port" data-field="preferred_port" placeholder="(无)" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;">
691
+ </div>
692
+ <div>
693
+ <label style="display:block;margin-bottom:4px;font-size:13px;color:#666;">监听地址 <span style="font-size:11px;color:#999;">(advertise_ip)</span></label>
694
+ <select id="mod-meta-ip" data-field="advertise_ip" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;">
695
+ <option value="127.0.0.1">127.0.0.1 - 仅本地</option>
696
+ <option value="0.0.0.0">0.0.0.0 - 允许远程</option>
697
+ </select>
698
+ </div>
699
+ </div>
700
+ </div>
701
+
702
+ <!-- 【区块4:模块配置文件】 -->
703
+ <div class="form-section hidden" id="module-config-section" style="background:#f9f9f9;padding:16px;border-radius:6px;">
704
+ <h4 style="margin:0 0 12px 0;font-size:14px;font-weight:600;color:#666;">模块配置文件 (config.yaml)</h4>
705
+ <div id="module-config-tree"></div>
706
+ </div>
707
+ </div>
708
+ </section>
709
+
710
+ <!-- Token Management -->
711
+ <section id="page-tokens" class="page">
712
+ <h2 style="margin:0 0 20px 0;font-size:20px;font-weight:600;">Token 管理</h2>
713
+
714
+ <!-- 标签页导航 -->
715
+ <div class="tabs">
716
+ <button class="tab active" data-tab="kite">Kite Token</button>
717
+ <button class="tab" data-tab="evol">Evol Token</button>
718
+ </div>
719
+
720
+ <!-- Kite Token 标签页 -->
721
+ <div class="tab-content active" id="tab-kite">
722
+ <div class="panel">
723
+ <div class="table-wrapper">
724
+ <table class="data-table" id="kite-tokens-table">
725
+ <thead>
726
+ <tr>
727
+ <th style="width:140px;">Token</th>
728
+ <th style="width:180px;">设备</th>
729
+ <th style="width:120px;">绑定手机号</th>
730
+ <th style="width:150px;">创建时间</th>
731
+ <th style="width:150px;">最后使用</th>
732
+ <th style="width:150px;">过期时间</th>
733
+ <th style="width:100px;">剩余有效期</th>
734
+ <th style="width:80px;">状态</th>
735
+ <th style="width:100px;">操作</th>
736
+ </tr>
737
+ </thead>
738
+ <tbody id="kite-tokens-tbody">
739
+ <tr><td colspan="9" class="text-muted" style="text-align:center;padding:40px;">加载中...</td></tr>
740
+ </tbody>
741
+ </table>
742
+ </div>
743
+ </div>
744
+ </div>
745
+
746
+ <!-- Evol Token 标签页 -->
747
+ <div class="tab-content" id="tab-evol">
748
+ <div class="panel">
749
+ <div class="table-wrapper">
750
+ <table class="data-table" id="evol-tokens-table">
751
+ <thead>
752
+ <tr>
753
+ <th style="width:140px;">Token</th>
754
+ <th style="width:120px;">手机号</th>
755
+ <th style="width:120px;">昵称</th>
756
+ <th style="width:100px;">积分</th>
757
+ <th style="width:100px;">VIP</th>
758
+ <th style="width:150px;">获取时间</th>
759
+ <th style="width:150px;">最后使用</th>
760
+ <th style="width:150px;">过期时间</th>
761
+ </tr>
762
+ </thead>
763
+ <tbody id="evol-tokens-tbody">
764
+ <tr><td colspan="8" class="text-muted" style="text-align:center;padding:40px;">加载中...</td></tr>
765
+ </tbody>
766
+ </table>
767
+ </div>
768
+ </div>
769
+ </div>
770
+ </section>
771
+ </main>
772
+ </div>
773
+ </div>
774
+
775
+ <script src="js/dialog.js"></script>
776
+ <script src="js/kernel-client.js?v=2"></script>
777
+ <script src="js/kernel-client-example.js"></script>
778
+ <script src="js/registry-tests.js"></script>
779
+ <script src="js/evol-app.js?v=2"></script>
780
+ </body>
781
+ </html>