@zhin.js/console 1.0.50 → 1.0.52
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 +19 -0
- package/README.md +22 -0
- package/browser.tsconfig.json +19 -0
- package/client/src/components/PageHeader.tsx +26 -0
- package/client/src/components/ui/accordion.tsx +2 -1
- package/client/src/components/ui/badge.tsx +1 -3
- package/client/src/components/ui/scroll-area.tsx +5 -2
- package/client/src/components/ui/select.tsx +7 -3
- package/client/src/components/ui/separator.tsx +5 -2
- package/client/src/components/ui/tabs.tsx +4 -2
- package/client/src/layouts/dashboard.tsx +223 -121
- package/client/src/main.tsx +34 -34
- package/client/src/pages/bot-detail/MessageBody.tsx +110 -0
- package/client/src/pages/bot-detail/date-utils.ts +8 -0
- package/client/src/pages/bot-detail/index.tsx +798 -0
- package/client/src/pages/bot-detail/types.ts +92 -0
- package/client/src/pages/bot-detail/useBotConsole.tsx +600 -0
- package/client/src/pages/bots.tsx +111 -73
- package/client/src/pages/database/constants.ts +16 -0
- package/client/src/pages/database/database-page.tsx +170 -0
- package/client/src/pages/database/document-collection-view.tsx +155 -0
- package/client/src/pages/database/index.tsx +1 -0
- package/client/src/pages/database/json-field.tsx +11 -0
- package/client/src/pages/database/kv-bucket-view.tsx +169 -0
- package/client/src/pages/database/related-table-view.tsx +221 -0
- package/client/src/pages/env.tsx +38 -28
- package/client/src/pages/files/code-editor.tsx +85 -0
- package/client/src/pages/files/editor-constants.ts +9 -0
- package/client/src/pages/files/file-editor.tsx +133 -0
- package/client/src/pages/files/file-icons.tsx +25 -0
- package/client/src/pages/files/files-page.tsx +92 -0
- package/client/src/pages/files/hljs-global.d.ts +10 -0
- package/client/src/pages/files/index.tsx +1 -0
- package/client/src/pages/files/language.ts +18 -0
- package/client/src/pages/files/tree-node.tsx +69 -0
- package/client/src/pages/files/use-hljs-theme.ts +23 -0
- package/client/src/pages/logs.tsx +77 -22
- package/client/src/style.css +144 -0
- package/client/src/utils/parseComposerContent.ts +57 -0
- package/client/tailwind.config.js +1 -0
- package/client/tsconfig.json +3 -1
- package/dist/assets/index-COKXlFo2.js +124 -0
- package/dist/assets/style-kkLO-vsa.css +3 -0
- package/dist/client.js +4262 -1
- package/dist/index.html +2 -2
- package/dist/radix-ui.js +1261 -1262
- package/dist/react-dom-client.js +2243 -2240
- package/dist/react-dom.js +15 -15
- package/dist/style.css +1 -3
- package/lib/index.js +1010 -81
- package/lib/transform.js +16 -2
- package/lib/websocket.js +845 -28
- package/node.tsconfig.json +18 -0
- package/package.json +15 -16
- package/src/bin.ts +24 -0
- package/src/bot-db-models.ts +74 -0
- package/src/bot-hub.ts +240 -0
- package/src/bot-persistence.ts +270 -0
- package/src/build.ts +90 -0
- package/src/dev.ts +107 -0
- package/src/index.ts +337 -0
- package/src/transform.ts +199 -0
- package/src/websocket.ts +1369 -0
- package/client/src/pages/database.tsx +0 -708
- package/client/src/pages/files.tsx +0 -470
- package/client/src/pages/login-assist.tsx +0 -225
- package/dist/index.js +0 -124
package/client/src/style.css
CHANGED
|
@@ -35,6 +35,15 @@
|
|
|
35
35
|
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
36
36
|
--sidebar-border: 220 13% 91%;
|
|
37
37
|
--sidebar-ring: 240 5.9% 10%;
|
|
38
|
+
/* Bot 详情 IM 区(参考 Telegram Web A 间距与层次) */
|
|
39
|
+
--im-list-bg: 228 24% 97%;
|
|
40
|
+
--im-chat-bg: 228 30% 98%;
|
|
41
|
+
--im-bubble-in: 0 0% 100%;
|
|
42
|
+
--im-bubble-out: 213 82% 51%;
|
|
43
|
+
--im-bubble-out-fg: 0 0% 100%;
|
|
44
|
+
--im-date-bg: 0 0% 100%;
|
|
45
|
+
--im-date-fg: 222 12% 40%;
|
|
46
|
+
--im-at: 213 90% 42%;
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
.dark {
|
|
@@ -65,6 +74,14 @@
|
|
|
65
74
|
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
|
66
75
|
--sidebar-border: 240 3.7% 15.9%;
|
|
67
76
|
--sidebar-ring: 240 4.9% 83.9%;
|
|
77
|
+
--im-list-bg: 222 14% 11%;
|
|
78
|
+
--im-chat-bg: 222 16% 8%;
|
|
79
|
+
--im-bubble-in: 215 14% 17%;
|
|
80
|
+
--im-bubble-out: 213 65% 48%;
|
|
81
|
+
--im-bubble-out-fg: 0 0% 100%;
|
|
82
|
+
--im-date-bg: 215 14% 16%;
|
|
83
|
+
--im-date-fg: 215 12% 72%;
|
|
84
|
+
--im-at: 204 100% 68%;
|
|
68
85
|
}
|
|
69
86
|
}
|
|
70
87
|
|
|
@@ -220,6 +237,117 @@
|
|
|
220
237
|
overflow: hidden;
|
|
221
238
|
}
|
|
222
239
|
|
|
240
|
+
/* 机器人详情:三栏 IM 布局 */
|
|
241
|
+
.im-layout {
|
|
242
|
+
padding: 0;
|
|
243
|
+
gap: 0;
|
|
244
|
+
height: calc(100vh - 42px - 2rem);
|
|
245
|
+
border-radius: var(--radius);
|
|
246
|
+
border: 1px solid hsl(var(--border));
|
|
247
|
+
background: hsl(var(--background));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.im-layout .channel-sidebar {
|
|
251
|
+
border: none;
|
|
252
|
+
border-radius: 0;
|
|
253
|
+
background: hsl(var(--im-list-bg));
|
|
254
|
+
border-right: 1px solid hsl(var(--border) / 0.65);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.im-main-split {
|
|
258
|
+
flex: 1;
|
|
259
|
+
display: flex;
|
|
260
|
+
min-width: 0;
|
|
261
|
+
min-height: 0;
|
|
262
|
+
height: 100%;
|
|
263
|
+
overflow: hidden;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.im-center {
|
|
267
|
+
flex: 1;
|
|
268
|
+
display: flex;
|
|
269
|
+
flex-direction: column;
|
|
270
|
+
min-width: 0;
|
|
271
|
+
min-height: 0;
|
|
272
|
+
background: hsl(var(--im-chat-bg));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.im-right-panel {
|
|
276
|
+
width: min(300px, 32vw);
|
|
277
|
+
flex-shrink: 0;
|
|
278
|
+
display: none;
|
|
279
|
+
flex-direction: column;
|
|
280
|
+
border-left: 1px solid hsl(var(--border) / 0.65);
|
|
281
|
+
background: hsl(var(--card));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
@media (min-width: 900px) {
|
|
285
|
+
.im-right-panel.im-right-visible {
|
|
286
|
+
display: flex;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.im-date-pill {
|
|
291
|
+
align-self: center;
|
|
292
|
+
margin: 0.5rem 0;
|
|
293
|
+
padding: 0.2rem 0.65rem;
|
|
294
|
+
border-radius: 9999px;
|
|
295
|
+
font-size: 0.72rem;
|
|
296
|
+
font-weight: 500;
|
|
297
|
+
color: hsl(var(--im-date-fg));
|
|
298
|
+
background: hsl(var(--im-date-bg));
|
|
299
|
+
box-shadow: 0 0 0 1px hsl(var(--border) / 0.45);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.im-bubble-in {
|
|
303
|
+
max-width: min(78%, 28rem);
|
|
304
|
+
border-radius: 0.65rem 0.65rem 0.65rem 0.2rem;
|
|
305
|
+
padding: 0.45rem 0.65rem 0.5rem;
|
|
306
|
+
background: hsl(var(--im-bubble-in));
|
|
307
|
+
box-shadow: 0 1px 0 hsl(var(--border) / 0.35);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.im-bubble-out {
|
|
311
|
+
max-width: min(78%, 28rem);
|
|
312
|
+
border-radius: 0.65rem 0.65rem 0.2rem 0.65rem;
|
|
313
|
+
padding: 0.45rem 0.65rem 0.5rem;
|
|
314
|
+
background: hsl(var(--im-bubble-out));
|
|
315
|
+
color: hsl(var(--im-bubble-out-fg));
|
|
316
|
+
box-shadow: 0 1px 0 hsl(0 0% 0% / 0.12);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.im-bubble-out .im-meta,
|
|
320
|
+
.im-bubble-out .text-muted-foreground {
|
|
321
|
+
color: hsl(var(--im-bubble-out-fg) / 0.85);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.im-bubble-out .im-at {
|
|
325
|
+
color: hsl(var(--im-bubble-out-fg) / 0.95);
|
|
326
|
+
text-decoration: underline;
|
|
327
|
+
text-underline-offset: 2px;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.im-composer {
|
|
331
|
+
border-top: 1px solid hsl(var(--border) / 0.7);
|
|
332
|
+
background: hsl(var(--card));
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.im-chat-header {
|
|
336
|
+
flex-shrink: 0;
|
|
337
|
+
border-bottom: 1px solid hsl(var(--border) / 0.65);
|
|
338
|
+
background: hsl(var(--card));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.im-at {
|
|
342
|
+
color: hsl(var(--im-at));
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.menu-item.im-row-compact {
|
|
346
|
+
padding: 0.4rem 0.55rem;
|
|
347
|
+
border-radius: 0.45rem;
|
|
348
|
+
gap: 0.55rem;
|
|
349
|
+
}
|
|
350
|
+
|
|
223
351
|
.rich-text-editor {
|
|
224
352
|
font-family: inherit;
|
|
225
353
|
transition: border-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -251,6 +379,22 @@
|
|
|
251
379
|
display: block;
|
|
252
380
|
}
|
|
253
381
|
|
|
382
|
+
.rich-text-editor .editor-video,
|
|
383
|
+
.rich-text-editor .editor-audio {
|
|
384
|
+
display: inline-flex;
|
|
385
|
+
align-items: center;
|
|
386
|
+
gap: 4px;
|
|
387
|
+
padding: 4px 10px;
|
|
388
|
+
margin: 2px 0;
|
|
389
|
+
border-radius: 6px;
|
|
390
|
+
border: 1px solid hsl(var(--border));
|
|
391
|
+
background: hsl(var(--muted) / 0.45);
|
|
392
|
+
font-size: 0.8rem;
|
|
393
|
+
vertical-align: middle;
|
|
394
|
+
user-select: none;
|
|
395
|
+
cursor: default;
|
|
396
|
+
}
|
|
397
|
+
|
|
254
398
|
.rich-text-editor .editor-at {
|
|
255
399
|
display: inline-flex;
|
|
256
400
|
align-items: center;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** 与机器人消息段结构一致,供解析/规范化使用 */
|
|
2
|
+
export type MessageContent = Array<{ type: string; data?: Record<string, unknown> }>
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 解析输入框文本为消息段(与沙盒约定一致)。
|
|
6
|
+
* 支持 [@名称]、[face:id]、[image:url]、[video:url]、[audio:url]
|
|
7
|
+
*/
|
|
8
|
+
export function parseComposerToSegments(text: string): MessageContent {
|
|
9
|
+
const segments: MessageContent = []
|
|
10
|
+
const regex =
|
|
11
|
+
/\[@([^\]]+)\]|\[face:(\d+)\]|\[image:([^\]]+)\]|\[video:([^\]]+)\]|\[audio:([^\]]+)\]/g
|
|
12
|
+
let lastIndex = 0
|
|
13
|
+
let match: RegExpExecArray | null
|
|
14
|
+
while ((match = regex.exec(text)) !== null) {
|
|
15
|
+
if (match.index > lastIndex) {
|
|
16
|
+
const t = text.substring(lastIndex, match.index)
|
|
17
|
+
if (t) segments.push({ type: 'text', data: { text: t } })
|
|
18
|
+
}
|
|
19
|
+
if (match[1]) segments.push({ type: 'at', data: { qq: match[1], name: match[1] } })
|
|
20
|
+
else if (match[2]) segments.push({ type: 'face', data: { id: parseInt(match[2], 10) } })
|
|
21
|
+
else if (match[3]) segments.push({ type: 'image', data: { url: match[3] } })
|
|
22
|
+
else if (match[4]) segments.push({ type: 'video', data: { url: match[4] } })
|
|
23
|
+
else if (match[5]) segments.push({ type: 'audio', data: { url: match[5] } })
|
|
24
|
+
lastIndex = regex.lastIndex
|
|
25
|
+
}
|
|
26
|
+
if (lastIndex < text.length) {
|
|
27
|
+
const r = text.substring(lastIndex)
|
|
28
|
+
if (r) segments.push({ type: 'text', data: { text: r } })
|
|
29
|
+
}
|
|
30
|
+
return segments.length > 0 ? segments : [{ type: 'text', data: { text } }]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function hasRenderableComposerSegments(segments: MessageContent): boolean {
|
|
34
|
+
if (!segments.length) return false
|
|
35
|
+
return segments.some((s) => {
|
|
36
|
+
if (s.type === 'text') return Boolean(String(s.data?.text ?? '').trim())
|
|
37
|
+
return true
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** 统一 WS 推送 / 收件箱里的 content(数组、JSON 字符串、纯文本) */
|
|
42
|
+
export function normalizeInboundContent(raw: unknown): MessageContent {
|
|
43
|
+
if (Array.isArray(raw)) {
|
|
44
|
+
return raw as MessageContent
|
|
45
|
+
}
|
|
46
|
+
if (typeof raw === 'string') {
|
|
47
|
+
if (!raw.trim()) return []
|
|
48
|
+
try {
|
|
49
|
+
const p = JSON.parse(raw) as unknown
|
|
50
|
+
if (Array.isArray(p)) return p as MessageContent
|
|
51
|
+
} catch {
|
|
52
|
+
/* 非 JSON */
|
|
53
|
+
}
|
|
54
|
+
return [{ type: 'text', data: { text: raw } }]
|
|
55
|
+
}
|
|
56
|
+
return []
|
|
57
|
+
}
|
|
@@ -18,6 +18,7 @@ export default {
|
|
|
18
18
|
`${cwd}/node_modules/@zhin.js/*/client/**/*.{js,ts,jsx,tsx}`,
|
|
19
19
|
`${cwd}/node_modules/@zhin.js/*/dist/**/*.{js,ts,jsx,tsx}`,
|
|
20
20
|
`${cwd}/plugins/*/client/**/*.{js,ts,jsx,tsx}`,
|
|
21
|
+
`${cwd}/plugins/**/client/**/*.{js,ts,jsx,tsx}`,
|
|
21
22
|
`${cwd}/client/**/*.{js,ts,jsx,tsx}`,
|
|
22
23
|
].filter(Boolean),
|
|
23
24
|
theme: {
|