@zhin.js/client 1.0.0 → 1.0.2

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 (43) hide show
  1. package/README.md +334 -67
  2. package/app/index.html +4 -3
  3. package/app/postcss.config.js +5 -0
  4. package/app/src/components/ThemeToggle.tsx +21 -0
  5. package/app/src/hooks/useTheme.ts +17 -0
  6. package/app/src/layouts/dashboard.tsx +259 -0
  7. package/app/src/main.tsx +121 -0
  8. package/app/src/pages/dashboard-bots.tsx +198 -0
  9. package/app/src/pages/dashboard-home.tsx +301 -0
  10. package/app/src/pages/dashboard-logs.tsx +298 -0
  11. package/app/src/pages/dashboard-plugin-detail.tsx +360 -0
  12. package/app/src/pages/dashboard-plugins.tsx +166 -0
  13. package/app/src/style.css +1105 -0
  14. package/app/src/theme/index.ts +92 -0
  15. package/app/tailwind.config.js +70 -0
  16. package/app/tsconfig.json +5 -0
  17. package/dist/index.js +15 -3
  18. package/package.json +20 -7
  19. package/src/index.ts +19 -3
  20. package/src/router/index.tsx +55 -0
  21. package/src/store/index.ts +111 -0
  22. package/src/store/reducers/index.ts +16 -0
  23. package/src/store/reducers/route.ts +122 -0
  24. package/src/store/reducers/script.ts +103 -0
  25. package/src/store/reducers/ui.ts +31 -0
  26. package/src/types.ts +11 -17
  27. package/src/websocket/index.ts +193 -0
  28. package/src/websocket/useWebSocket.ts +42 -0
  29. package/app/components.d.ts +0 -33
  30. package/app/src/App.vue +0 -7
  31. package/app/src/main.ts +0 -127
  32. package/app/src/pages/$.vue +0 -899
  33. package/app/src/pages/404.vue +0 -11
  34. package/app/src/pages/contexts/overview.vue +0 -177
  35. package/app/src/pages/dashboard.vue +0 -323
  36. package/app/src/pages/plugins/installed.vue +0 -734
  37. package/app/src/pages/system/status.vue +0 -241
  38. package/app/src/services/api.ts +0 -155
  39. package/app/src/styles/README.md +0 -202
  40. package/app/src/styles/common.css +0 -0
  41. package/global.d.ts +0 -19
  42. package/src/router.ts +0 -44
  43. package/src/store.ts +0 -53
@@ -1,11 +0,0 @@
1
- <script setup lang="ts">
2
-
3
- </script>
4
-
5
- <template>
6
- 404 not found
7
- </template>
8
-
9
- <style scoped>
10
-
11
- </style>
@@ -1,177 +0,0 @@
1
- <template>
2
- <div class="page-layout">
3
- <!-- 页面头部 -->
4
- <Card class="page-header-card">
5
- <template #content>
6
- <div class="flex-row justify-between">
7
- <div class="flex-row">
8
- <div class="icon-container icon-primary">
9
- <i class="pi pi-sitemap"></i>
10
- </div>
11
- <div class="flex-column">
12
- <h1>上下文管理</h1>
13
- <p>管理和监控框架中的所有上下文</p>
14
- </div>
15
- </div>
16
- <Button
17
- icon="pi pi-refresh"
18
- label="刷新"
19
- @click="refreshData"
20
- :loading="refreshing"
21
- severity="secondary"
22
- outlined
23
- />
24
- </div>
25
- </template>
26
- </Card>
27
-
28
- <!-- 统计卡片 -->
29
- <div class="stats-container">
30
- <Card class="stats-card">
31
- <template #content>
32
- <div class="flex-row gap-large">
33
- <div class="icon-container icon-total">
34
- <i class="pi pi-sitemap"></i>
35
- </div>
36
- <div class="flex-column flex-1">
37
- <div class="stat-value">{{ totalContexts }}</div>
38
- <div class="stat-label">总上下文数</div>
39
- <div class="stat-sub">所有已注册上下文</div>
40
- </div>
41
- </div>
42
- </template>
43
- </Card>
44
-
45
- <Card class="stats-card">
46
- <template #content>
47
- <div class="flex-row gap-large">
48
- <div class="icon-container icon-active">
49
- <i class="pi pi-check-circle"></i>
50
- </div>
51
- <div class="flex-column flex-1">
52
- <div class="stat-value">{{ activeContexts }}</div>
53
- <div class="stat-label">活跃上下文</div>
54
- <div class="stat-sub">正在运行中</div>
55
- </div>
56
- </div>
57
- </template>
58
- </Card>
59
- </div>
60
-
61
- <!-- 主要内容区域 -->
62
- <div class="layout-container">
63
- <div class="layout-main">
64
- <Card class="content-card">
65
- <template #title>
66
- <i class="pi pi-list"></i>
67
- <span>所有上下文</span>
68
- <Button
69
- icon="pi pi-refresh"
70
- severity="secondary"
71
- text
72
- rounded
73
- size="small"
74
- :loading="refreshing"
75
- @click="refreshData"
76
- v-tooltip="'刷新数据'"
77
- />
78
- </template>
79
- <template #content>
80
- <div v-if="allContexts.length" class="grid-auto-fit">
81
- <div
82
- v-for="context in allContexts"
83
- :key="context.name"
84
- class="context-item"
85
- >
86
- <div class="icon-container icon-small icon-primary">
87
- <i class="pi pi-circle-fill"></i>
88
- </div>
89
- <div class="flex-column flex-1">
90
- <div class="detail-label">{{ context.name }}</div>
91
- <div class="detail-value">{{ context.description }}</div>
92
- </div>
93
- <div class="flex-none">
94
- <Tag
95
- value="活跃"
96
- severity="success"
97
- icon="pi pi-check"
98
- size="small"
99
- />
100
- </div>
101
- </div>
102
- </div>
103
- <div v-else class="empty-state">
104
- <div class="icon-container">
105
- <i class="pi pi-sitemap"></i>
106
- </div>
107
- <h3>暂无上下文</h3>
108
- <p>系统中还没有注册任何上下文</p>
109
- </div>
110
- </template>
111
- </Card>
112
- </div>
113
- </div>
114
- </div>
115
- </template>
116
-
117
- <script setup lang="ts">
118
- import { computed, ref } from 'vue'
119
- import { useCommonStore } from '@zhin.js/client'
120
-
121
- const commonStore = useCommonStore()
122
- const refreshing = ref(false)
123
-
124
- // 系统数据
125
- const systemData = computed(() => (commonStore.store as any).system)
126
- const pluginsData = computed(() => (commonStore.store as any).plugins || [])
127
- const adaptersData = computed(() => (commonStore.store as any).adapters || [])
128
-
129
- // 上下文数据(从多个来源聚合)
130
- const allContexts = computed(() => {
131
- const contexts = []
132
-
133
- // 从系统数据中获取上下文(如果有的话)
134
- if (systemData.value?.contexts) {
135
- contexts.push(...systemData.value.contexts.map(ctx => ({
136
- name: ctx.name,
137
- description: ctx.description || `${ctx.name} 上下文`,
138
- status: 'active'
139
- })))
140
- }
141
-
142
- // 从适配器数据中添加上下文
143
- contexts.push(...adaptersData.value.map(adapter => ({
144
- name: adapter.name,
145
- description: adapter.description || `${adapter.platform} 平台适配器`,
146
- status: adapter.status || 'active'
147
- })))
148
-
149
- return contexts
150
- })
151
-
152
- // 统计数据
153
- const totalContexts = computed(() => allContexts.value.length)
154
- const activeContexts = computed(() =>
155
- allContexts.value.filter(ctx => ctx.status === 'active').length
156
- )
157
-
158
- // 刷新数据
159
- const refreshData = async () => {
160
- refreshing.value = true
161
- try {
162
- if (window.ZhinDataAPI?.updateAllData) {
163
- await window.ZhinDataAPI.updateAllData()
164
- } else {
165
- throw new Error('全局API未就绪')
166
- }
167
- } catch (error) {
168
- // console.error 已替换为注释
169
- } finally {
170
- refreshing.value = false
171
- }
172
- }
173
- </script>
174
-
175
- <style scoped>
176
- /* 页面特定样式 - 所有样式已移至 common.css,使用PrimeVue组件类名控制 */
177
- </style>
@@ -1,323 +0,0 @@
1
- <template>
2
- <div class="page-layout">
3
- <!-- 页面头部 -->
4
- <Card class="page-header-card">
5
- <template #content>
6
- <div class="flex-row justify-between">
7
- <div class="flex items-center space-x-4">
8
- <div class="bg-blue-500 hover:bg-blue-600 p-3 rounded-lg transition-colors">
9
- <i class="pi pi-desktop text-white text-xl"></i>
10
- </div>
11
- <div class="flex flex-col">
12
- <h1 class="text-2xl font-bold text-white">欢迎使用 Zhin Bot</h1>
13
- <p class="text-white/90">现代化的聊天机器人框架管理平台</p>
14
- </div>
15
- </div>
16
- <Button
17
- icon="pi pi-refresh"
18
- label="刷新数据"
19
- @click="refreshData"
20
- :loading="refreshing"
21
- severity="secondary"
22
- outlined
23
- />
24
- </div>
25
- </template>
26
- </Card>
27
-
28
- <!-- 统计卡片 -->
29
- <div class="stats-container">
30
- <Card class="stats-card">
31
- <template #content>
32
- <div class="flex-row gap-large">
33
- <div class="icon-container icon-blue">
34
- <i class="pi pi-th-large"></i>
35
- </div>
36
- <div class="flex-column flex-1">
37
- <div class="stat-value">{{ pluginsData?.length || 0 }}</div>
38
- <div class="stat-label">已安装插件</div>
39
- <div class="stat-sub">{{ activePluginsCount }} 个活跃</div>
40
- </div>
41
- </div>
42
- </template>
43
- </Card>
44
-
45
- <Card class="stats-card">
46
- <template #content>
47
- <div class="flex-row gap-large">
48
- <div class="icon-container icon-green">
49
- <i class="pi pi-sitemap"></i>
50
- </div>
51
- <div class="flex-column flex-1">
52
- <div class="stat-value">{{ totalContexts }}</div>
53
- <div class="stat-label">上下文</div>
54
- <div class="stat-sub">{{ activeContexts }} 个活跃</div>
55
- </div>
56
- </div>
57
- </template>
58
- </Card>
59
-
60
- <Card class="stats-card">
61
- <template #content>
62
- <div class="flex-row gap-large">
63
- <div class="icon-container icon-purple">
64
- <i class="pi pi-code"></i>
65
- </div>
66
- <div class="flex-column flex-1">
67
- <div class="stat-value">{{ totalCommands }}</div>
68
- <div class="stat-label">命令数量</div>
69
- <div class="stat-sub">来自所有插件</div>
70
- </div>
71
- </div>
72
- </template>
73
- </Card>
74
-
75
- <Card class="stats-card">
76
- <template #content>
77
- <div class="flex-row gap-large">
78
- <div class="icon-container icon-orange">
79
- <i class="pi pi-chart-bar"></i>
80
- </div>
81
- <div class="flex-column flex-1">
82
- <div class="stat-value">{{ formatMemory(systemData?.memory.heapUsed) }}</div>
83
- <div class="stat-label">内存使用</div>
84
- <div class="stat-sub">{{ memoryUsagePercent }}% 已使用</div>
85
- </div>
86
- </div>
87
- </template>
88
- </Card>
89
- </div>
90
-
91
- <!-- 主要内容区域 -->
92
- <div class="layout-container">
93
- <!-- 左侧:系统状态 + 插件概览 -->
94
- <div class="layout-main">
95
- <!-- 系统状态 -->
96
- <Card class="content-card">
97
- <template #title>
98
- <i class="pi pi-desktop"></i>
99
- <span>系统状态</span>
100
- </template>
101
- <template #content>
102
- <div class="detail-grid">
103
- <div class="detail-item">
104
- <div class="icon-container icon-small icon-blue">
105
- <i class="pi pi-microchip"></i>
106
- </div>
107
- <div class="flex-column flex-1">
108
- <div class="detail-label">运行平台</div>
109
- <div class="detail-value">{{ systemData?.platform }} {{ systemData?.nodeVersion }}</div>
110
- </div>
111
- </div>
112
-
113
- <div class="detail-item">
114
- <div class="icon-container icon-small icon-green">
115
- <i class="pi pi-chart-line"></i>
116
- </div>
117
- <div class="flex-column flex-1">
118
- <div class="detail-label">内存使用情况</div>
119
- <div class="detail-value">
120
- {{ formatMemory(systemData?.memory.heapUsed) }} / {{ formatMemory(systemData?.memory.heapTotal) }}
121
- </div>
122
- <ProgressBar
123
- :value="memoryUsagePercent"
124
- :showValue="false"
125
- />
126
- </div>
127
- </div>
128
-
129
- <div class="detail-item">
130
- <div class="icon-container icon-small icon-purple">
131
- <i class="pi pi-clock"></i>
132
- </div>
133
- <div class="flex-column flex-1">
134
- <div class="detail-label">进程信息</div>
135
- <div class="detail-value">PID: {{ systemData?.pid }} · 运行时间: {{ formatUptime(systemData?.uptime) }}</div>
136
- </div>
137
- </div>
138
- </div>
139
- </template>
140
- </Card>
141
-
142
- <!-- 插件概览 -->
143
- <Card class="content-card">
144
- <template #title>
145
- <i class="pi pi-th-large"></i>
146
- <span>插件概览</span>
147
- <Button
148
- label="查看全部"
149
- text
150
- size="small"
151
- @click="router.push('/plugins/installed')"
152
- />
153
- </template>
154
- <template #content>
155
- <div class="detail-grid">
156
- <div
157
- v-for="plugin in pluginsData?.slice(0, 5)"
158
- :key="plugin.name"
159
- class="detail-item"
160
- >
161
- <div class="icon-container icon-small icon-primary">
162
- <i class="pi pi-puzzle-piece"></i>
163
- </div>
164
- <div class="flex-column flex-1">
165
- <div class="detail-label">{{ plugin.name }}</div>
166
- <div class="detail-value flex-row">
167
- <Tag
168
- :value="plugin.status"
169
- :severity="getStatusSeverity(plugin.status)"
170
- size="small"
171
- />
172
- <span>{{ formatUptime(plugin.uptime) }}</span>
173
- </div>
174
- </div>
175
- </div>
176
- </div>
177
- </template>
178
- </Card>
179
- </div>
180
-
181
- <!-- 右侧:上下文状态 -->
182
- <div class="layout-sidebar">
183
- <Card class="content-card">
184
- <template #title>
185
- <i class="pi pi-sitemap"></i>
186
- <span>上下文状态</span>
187
- <Button
188
- label="查看详情"
189
- text
190
- size="small"
191
- @click="router.push('/contexts/overview')"
192
- />
193
- </template>
194
- <template #content>
195
- <div class="grid-auto-fit">
196
- <div
197
- v-for="adapter in adaptersData"
198
- :key="adapter.name"
199
- class="context-item"
200
- >
201
- <div class="icon-container icon-small icon-primary">
202
- <i :class="getPlatformIcon(adapter.platform)"></i>
203
- </div>
204
- <div class="flex-column flex-1">
205
- <div class="detail-label">{{ adapter.name }}</div>
206
- <div class="detail-value">{{ adapter.status }}</div>
207
- </div>
208
- <Tag
209
- :value="adapter.status"
210
- :severity="getStatusSeverity(adapter.status)"
211
- size="small"
212
- />
213
- </div>
214
- </div>
215
- </template>
216
- </Card>
217
- </div>
218
- </div>
219
- </div>
220
- </template>
221
-
222
- <script setup lang="ts">
223
- import { computed, ref } from 'vue'
224
- import { useCommonStore } from '@zhin.js/client'
225
- import { useRouter } from 'vue-router'
226
-
227
- const commonStore = useCommonStore()
228
- const router = useRouter()
229
- const refreshing = ref(false)
230
- // 数据
231
- const systemData = computed(() => (commonStore.store as any).system)
232
- const pluginsData = computed(() => (commonStore.store as any).plugins || [])
233
- const adaptersData = computed(() => (commonStore.store as any).adapters || [])
234
-
235
- // 统计数据
236
- const activePluginsCount = computed(() => {
237
- return pluginsData.value.length // 所有返回的插件都是活跃的
238
- })
239
-
240
- // 上下文统计(基于真实数据)
241
- const totalContexts = computed(() => {
242
- // 核心上下文 + 服务上下文 + 从插件提供的上下文
243
- return pluginsData.value.reduce((total, plugin) => total + (plugin.context_count || 0), 0)
244
- })
245
-
246
- const activeContexts = computed(() => {
247
- // 所有上下文都是活跃的
248
- return totalContexts.value
249
- })
250
-
251
- const totalCommands = computed(() => {
252
- return pluginsData.value.reduce((total, plugin) => total + (plugin.command_count || 0), 0)
253
- })
254
-
255
- const memoryUsagePercent = computed(() => {
256
- if (!systemData.value?.memory) return 0
257
- const { heapUsed, heapTotal } = systemData.value.memory
258
- return Math.round((heapUsed / heapTotal) * 100)
259
- })
260
-
261
- // 格式化函数
262
- const formatUptime = (seconds?: number) => {
263
- if (!seconds) return '0秒'
264
-
265
- const hours = Math.floor(seconds / 3600)
266
- const minutes = Math.floor((seconds % 3600) / 60)
267
-
268
- if (hours > 0) {
269
- return `${hours}小时${minutes}分钟`
270
- } else if (minutes > 0) {
271
- return `${minutes}分钟`
272
- } else {
273
- return `${Math.floor(seconds)}秒`
274
- }
275
- }
276
-
277
- const formatMemory = (bytes?: number) => {
278
- if (!bytes) return '0B'
279
-
280
- const sizes = ['B', 'KB', 'MB', 'GB']
281
- const i = Math.floor(Math.log(bytes) / Math.log(1024))
282
- return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`
283
- }
284
-
285
- const getStatusSeverity = (status: string) => {
286
- switch (status) {
287
- case 'active': return 'success'
288
- case 'disposed':
289
- case 'inactive': return 'danger'
290
- default: return 'info'
291
- }
292
- }
293
-
294
- const getPlatformIcon = (platform: string) => {
295
- switch (platform) {
296
- case 'qq': return 'pi pi-comment'
297
- case 'kook': return 'pi pi-discord'
298
- case 'console': return 'pi pi-desktop'
299
- default: return 'pi pi-circle'
300
- }
301
- }
302
-
303
- const refreshData = async () => {
304
- refreshing.value = true
305
- try {
306
- // 使用全局API
307
- if (window.ZhinDataAPI?.updateAllData) {
308
- await window.ZhinDataAPI.updateAllData()
309
- // console.log 已替换为注释
310
- } else {
311
- throw new Error('全局API未就绪')
312
- }
313
- } catch (error) {
314
- // console.error 已替换为注释
315
- } finally {
316
- refreshing.value = false
317
- }
318
- }
319
- </script>
320
-
321
- <style scoped>
322
- /* 页面特定样式 - 所有样式已移至 common.css,使用PrimeVue组件类名控制 */
323
- </style>