@roaming-ai/dsh-group-chat 0.2.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 (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/cordis.patch.yml +12 -0
  4. package/lib/client.js +3308 -0
  5. package/lib/client.js.map +1 -0
  6. package/lib/index.js +2583 -0
  7. package/lib/types/client/Bubble.d.ts +10 -0
  8. package/lib/types/client/Glyph.d.ts +12 -0
  9. package/lib/types/client/GroupChatPanel.d.ts +10 -0
  10. package/lib/types/client/GroupChatPanel.old.d.ts +10 -0
  11. package/lib/types/client/GroupChatSettingsSection.d.ts +15 -0
  12. package/lib/types/client/PermissionSelect.d.ts +13 -0
  13. package/lib/types/client/RoleDrawer.d.ts +17 -0
  14. package/lib/types/client/ThinkRow.d.ts +9 -0
  15. package/lib/types/client/ToolRow.d.ts +9 -0
  16. package/lib/types/client/api.d.ts +8 -0
  17. package/lib/types/client/components/AsidePanel.d.ts +31 -0
  18. package/lib/types/client/components/Bubble.d.ts +19 -0
  19. package/lib/types/client/components/ChatPanel.d.ts +57 -0
  20. package/lib/types/client/components/Composer.d.ts +48 -0
  21. package/lib/types/client/components/Glyph.d.ts +12 -0
  22. package/lib/types/client/components/GroupChatSettingsSection.d.ts +15 -0
  23. package/lib/types/client/components/MessageFlow.d.ts +15 -0
  24. package/lib/types/client/components/NavPanel.d.ts +40 -0
  25. package/lib/types/client/components/PermissionSelect.d.ts +13 -0
  26. package/lib/types/client/components/RoleDrawer.d.ts +17 -0
  27. package/lib/types/client/components/ThinkRow.d.ts +9 -0
  28. package/lib/types/client/components/ToolRow.d.ts +9 -0
  29. package/lib/types/client/components/index.d.ts +9 -0
  30. package/lib/types/client/components.d.ts +22 -0
  31. package/lib/types/client/drawer.d.ts +17 -0
  32. package/lib/types/client/glyph.d.ts +12 -0
  33. package/lib/types/client/hooks/index.d.ts +6 -0
  34. package/lib/types/client/hooks/useComposer.d.ts +27 -0
  35. package/lib/types/client/hooks/useFileSearch.d.ts +19 -0
  36. package/lib/types/client/hooks/useGroupChatState.d.ts +95 -0
  37. package/lib/types/client/hooks/useMentionState.d.ts +27 -0
  38. package/lib/types/client/index.d.ts +52 -0
  39. package/lib/types/client/lib/api.d.ts +8 -0
  40. package/lib/types/client/lib/model.d.ts +80 -0
  41. package/lib/types/client/lib/styles.d.ts +10 -0
  42. package/lib/types/client/lib/ui.d.ts +17 -0
  43. package/lib/types/client/model.d.ts +78 -0
  44. package/lib/types/client/panel.d.ts +10 -0
  45. package/lib/types/client/settings.d.ts +15 -0
  46. package/lib/types/client/styles.d.ts +10 -0
  47. package/lib/types/client/ui.d.ts +17 -0
  48. package/lib/types/client/utils/utils.d.ts +29 -0
  49. package/lib/types/client/utils.d.ts +22 -0
  50. package/lib/types/core/json.d.ts +9 -0
  51. package/lib/types/core/status.d.ts +18 -0
  52. package/lib/types/core/tools.d.ts +59 -0
  53. package/lib/types/core/types.d.ts +256 -0
  54. package/lib/types/host/actions.d.ts +34 -0
  55. package/lib/types/host/api/actions.d.ts +36 -0
  56. package/lib/types/host/api/http.d.ts +16 -0
  57. package/lib/types/host/api/index.d.ts +7 -0
  58. package/lib/types/host/api/routes.d.ts +11 -0
  59. package/lib/types/host/broadcast.d.ts +20 -0
  60. package/lib/types/host/conversation.d.ts +25 -0
  61. package/lib/types/host/engine/conversation.d.ts +25 -0
  62. package/lib/types/host/engine/index.d.ts +7 -0
  63. package/lib/types/host/engine/retitle.d.ts +20 -0
  64. package/lib/types/host/http.d.ts +16 -0
  65. package/lib/types/host/index.d.ts +8 -0
  66. package/lib/types/host/materials/index.d.ts +6 -0
  67. package/lib/types/host/materials/materials.d.ts +40 -0
  68. package/lib/types/host/materials.d.ts +32 -0
  69. package/lib/types/host/persistence/index.d.ts +6 -0
  70. package/lib/types/host/persistence/persistence.d.ts +31 -0
  71. package/lib/types/host/persistence/store.d.ts +65 -0
  72. package/lib/types/host/persistence.d.ts +31 -0
  73. package/lib/types/host/routes.d.ts +11 -0
  74. package/lib/types/host/service.d.ts +28 -0
  75. package/lib/types/host/state.d.ts +45 -0
  76. package/lib/types/host/store.d.ts +65 -0
  77. package/lib/types/host/tools/index.d.ts +6 -0
  78. package/lib/types/host/tools/tools.d.ts +28 -0
  79. package/lib/types/host/tools.d.ts +28 -0
  80. package/lib/types/index.d.ts +41 -0
  81. package/lib/types/mount-once.d.ts +9 -0
  82. package/lib/types/shared/file-mention-grammar.d.ts +37 -0
  83. package/lib/types/shared/file-mention-grammar.test.d.ts +5 -0
  84. package/package.json +98 -0
  85. package/src/client/GroupChatPanel.tsx +385 -0
  86. package/src/client/components/AsidePanel.tsx +188 -0
  87. package/src/client/components/Bubble.tsx +76 -0
  88. package/src/client/components/ChatPanel.tsx +214 -0
  89. package/src/client/components/Composer.tsx +238 -0
  90. package/src/client/components/Glyph.tsx +27 -0
  91. package/src/client/components/GroupChatSettingsSection.tsx +74 -0
  92. package/src/client/components/MessageFlow.tsx +97 -0
  93. package/src/client/components/NavPanel.tsx +249 -0
  94. package/src/client/components/PermissionSelect.tsx +159 -0
  95. package/src/client/components/RoleDrawer.tsx +186 -0
  96. package/src/client/components/ThinkRow.tsx +32 -0
  97. package/src/client/components/ToolRow.tsx +51 -0
  98. package/src/client/components/index.ts +10 -0
  99. package/src/client/hooks/index.ts +7 -0
  100. package/src/client/hooks/useComposer.ts +272 -0
  101. package/src/client/hooks/useFileSearch.ts +115 -0
  102. package/src/client/hooks/useGroupChatState.ts +214 -0
  103. package/src/client/hooks/useMentionState.ts +56 -0
  104. package/src/client/index.ts +110 -0
  105. package/src/client/lib/api.ts +23 -0
  106. package/src/client/lib/model.ts +119 -0
  107. package/src/client/lib/styles.ts +317 -0
  108. package/src/client/lib/ui.ts +27 -0
  109. package/src/client/react-dom-shim.d.ts +13 -0
  110. package/src/client/utils/utils.ts +104 -0
  111. package/src/core/json.ts +28 -0
  112. package/src/core/status.ts +33 -0
  113. package/src/core/tools.ts +41 -0
  114. package/src/core/types.ts +222 -0
  115. package/src/host/api/actions.ts +335 -0
  116. package/src/host/api/http.ts +80 -0
  117. package/src/host/api/index.ts +8 -0
  118. package/src/host/api/routes.ts +95 -0
  119. package/src/host/broadcast.ts +65 -0
  120. package/src/host/engine/conversation.ts +331 -0
  121. package/src/host/engine/index.ts +8 -0
  122. package/src/host/engine/retitle.ts +135 -0
  123. package/src/host/index.ts +9 -0
  124. package/src/host/materials/index.ts +7 -0
  125. package/src/host/materials/materials.ts +193 -0
  126. package/src/host/persistence/index.ts +7 -0
  127. package/src/host/persistence/persistence.ts +311 -0
  128. package/src/host/persistence/store.ts +375 -0
  129. package/src/host/service.ts +78 -0
  130. package/src/host/state.ts +85 -0
  131. package/src/host/tools/index.ts +7 -0
  132. package/src/host/tools/tools.ts +194 -0
  133. package/src/index.ts +99 -0
  134. package/src/mount-once.ts +49 -0
  135. package/src/shared/file-mention-grammar.test.ts +77 -0
  136. package/src/shared/file-mention-grammar.ts +82 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 聊天消息气泡(user / system / 角色发言)。
3
+ * @module dsh-group-chat/client/Bubble
4
+ */
5
+ import type { ReactNode } from 'react';
6
+ import { type ClientSnapshot } from './model.ts';
7
+ export declare function Bubble(props: {
8
+ snap: ClientSnapshot;
9
+ m: ClientSnapshot['messages'][number];
10
+ }): ReactNode;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 侧边栏入口图标。
3
+ *
4
+ * 整行命中层携带 “newSession” 类名:任务看板等 DOM 注入式面板用
5
+ * [class*="newSession"] 识别“侧边栏导航点击”并自动收起自己,与点击
6
+ * “新建会话”行为一致——类名不可哈希化。
7
+ * @module dsh-group-chat/client/glyph
8
+ */
9
+ import type { ReactNode } from 'react';
10
+ export declare function Glyph(props: {
11
+ size?: number;
12
+ }): ReactNode;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 主面板:三区工作台——左导航栏(搜索 + 群组→会话目录树)、中央会话流
3
+ * (@成员 点名 + markdown 渲染 + 思考折叠)、右上下文栏(群成员角色卡 +
4
+ * 工作区目录),右栏可收起,角色编辑走右侧滑出抽屉。
5
+ *
6
+ * 面板数据走 /api/group-chat/*(fetch + SSE),Host 半持有全部状态。
7
+ * @module dsh-group-chat/client/panel
8
+ */
9
+ import { type ReactNode } from 'react';
10
+ export declare function GroupChatPanel(): ReactNode;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 主面板:三区工作台——左导航栏(搜索 + 群组→会话目录树)、中央会话流
3
+ * (@成员 点名 + markdown 渲染 + 思考折叠)、右上下文栏(群成员角色卡 +
4
+ * 工作区目录),右栏可收起,角色编辑走右侧滑出抽屉。
5
+ *
6
+ * 面板数据走 /api/group-chat/*(fetch + SSE),Host 半持有全部状态。
7
+ * @module dsh-group-chat/client/panel
8
+ */
9
+ import { type ReactNode } from 'react';
10
+ export declare function GroupChatPanel(): ReactNode;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 设置页:启停开关(settings.section 插槽)。写 host 的 group-chat 设置
3
+ * 命名空间(settings.yaml 持久化)。
4
+ * @module dsh-group-chat/client/settings
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
8
+ /** Host 侧注册的设置命名空间 shape。 */
9
+ interface GroupChatSettings {
10
+ enabled?: boolean;
11
+ }
12
+ export declare function GroupChatSettingsSection(props: {
13
+ settingsScope: SettingsScope<GroupChatSettings>;
14
+ }): ReactNode;
15
+ export {};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 群组权限档位选择器(对齐主会话 composer 左下角的 /permission 选择器):
3
+ * 触发芯片(盾形图标 + 档位名 + chevron)+ Menu 上弹三档 + 完全权限风险
4
+ * 确认弹窗(与主会话同款 RiskConfirmation 原语与文案)。
5
+ * @module dsh-group-chat/client/permission-select
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ import type { PermissionTier } from '../core/types.ts';
9
+ export interface PermissionSelectProps {
10
+ tier: PermissionTier;
11
+ onSelect: (tier: PermissionTier) => void;
12
+ }
13
+ export declare function PermissionSelect(props: PermissionSelectProps): ReactNode;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 角色编辑抽屉(右侧滑出,不遮挡会话流阅读)。
3
+ * @module dsh-group-chat/client/drawer
4
+ */
5
+ import { type ReactNode } from 'react';
6
+ import { type ModelsResponse, type RoleDraft } from './model.ts';
7
+ export interface RoleDrawerProps {
8
+ draft: RoleDraft;
9
+ set: (draft: RoleDraft) => void;
10
+ models: ModelsResponse | null;
11
+ modelsError: string | null;
12
+ onRetryModels: () => void;
13
+ onSave: () => void;
14
+ onCancel: () => void;
15
+ formError: string;
16
+ }
17
+ export declare function RoleDrawer(props: RoleDrawerProps): ReactNode;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 思考折叠行(对标宿主 ReasoningRow:折叠摘要 / 展开全文)。
3
+ * @module dsh-group-chat/client/ThinkRow
4
+ */
5
+ import { type ReactNode } from 'react';
6
+ export declare function ThinkRow(props: {
7
+ text: string;
8
+ running?: boolean;
9
+ }): ReactNode;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 工具调用折叠行(对标思考折叠:摘要行 / 展开输出)。
3
+ * @module dsh-group-chat/client/ToolRow
4
+ */
5
+ import { type ReactNode } from 'react';
6
+ import type { ToolCallView } from './model.ts';
7
+ export declare function ToolRow(props: {
8
+ c: ToolCallView;
9
+ }): ReactNode;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 浏览器半 transport:/api/group-chat/* 同源 JSON 端点。
3
+ * @module dsh-group-chat/client/api
4
+ */
5
+ export declare const api: {
6
+ state: () => Promise<unknown>;
7
+ action: (payload: Record<string, unknown>) => Promise<unknown>;
8
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * 右侧成员与工作区栏组件
3
+ * @module dsh-group-chat/client/components
4
+ */
5
+ import type { ReactNode } from 'react';
6
+ import { type ClientSnapshot, type SnapshotRole } from '../lib/model.ts';
7
+ interface AsidePanelProps {
8
+ snap: ClientSnapshot;
9
+ group: ClientSnapshot['groups'][number];
10
+ asideOpen: boolean;
11
+ wsDraft: string | null;
12
+ setWsDraft: (val: string | null) => void;
13
+ fileBrowser: {
14
+ open: boolean;
15
+ loading: boolean;
16
+ list: import('../../core/types.ts').BrowseResult | null;
17
+ error: string;
18
+ } | null;
19
+ setFileBrowser: (val: {
20
+ open: boolean;
21
+ loading: boolean;
22
+ list: import('../../core/types.ts').BrowseResult | null;
23
+ error: string;
24
+ } | null) => void;
25
+ mutate: (args: Record<string, unknown>) => Promise<unknown>;
26
+ openRoleEditor: (role: SnapshotRole | null) => Promise<void>;
27
+ openBrowser: (path: string | undefined) => Promise<void>;
28
+ selectCurrentDir: () => void;
29
+ }
30
+ export declare function AsidePanel(props: AsidePanelProps): ReactNode;
31
+ export {};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 聊天消息气泡(user / system / 角色发言)。
3
+ *
4
+ * 帧稳定 memo:SSE 全量快照(~65KB × 7fps)每帧重建全部消息对象 identity,
5
+ * 但已完成消息在 host 侧 append 后不可变——按渲染相关字段做值比较,流式
6
+ * 期间跳过已完成消息的重渲(每帧仅 live 行与派生列表变化),避免全量
7
+ * MarkdownText 重新解析打满主线程导致「卡死后一次性蹦出」。
8
+ * @module dsh-group-chat/client/Bubble
9
+ */
10
+ import { type ReactNode } from 'react';
11
+ import { type ClientSnapshot, type SnapshotRole } from '../lib/model.ts';
12
+ export interface BubbleProps {
13
+ m: ClientSnapshot['messages'][number];
14
+ /** 父级解析好的发言角色(user/system 消息为 null)——避免 Bubble 依赖 snap identity。 */
15
+ role: SnapshotRole | null;
16
+ }
17
+ declare function BubbleInner({ m, role }: BubbleProps): ReactNode;
18
+ export declare const Bubble: import("react").MemoExoticComponent<typeof BubbleInner>;
19
+ export {};
@@ -0,0 +1,57 @@
1
+ /**
2
+ * 中央会话面板组件
3
+ * @module dsh-group-chat/client/components
4
+ */
5
+ import type { ReactNode } from 'react';
6
+ import type { ClientSnapshot, SnapshotRole } from '../lib/model.ts';
7
+ import type { AtToken } from '../../shared/file-mention-grammar.ts';
8
+ interface ChatPanelProps {
9
+ snap: ClientSnapshot;
10
+ sess: ClientSnapshot['sessions'][number] | null;
11
+ group: ClientSnapshot['groups'][number];
12
+ enabledRoles: SnapshotRole[];
13
+ participants: string[];
14
+ mentionedRoles: SnapshotRole[];
15
+ busyNow: boolean;
16
+ input: string;
17
+ mention: AtToken | null;
18
+ mentionCandidates: SnapshotRole[];
19
+ mentionIdxC: number;
20
+ fileCandidates: Array<{
21
+ path: string;
22
+ isDir: boolean;
23
+ }>;
24
+ fileSearchError: string | null;
25
+ fileSearchLoading: boolean;
26
+ rounds: number;
27
+ err: string;
28
+ atBottom: boolean;
29
+ topicDraft: string | null;
30
+ msgById: Record<string, ClientSnapshot['messages'][number]>;
31
+ navOpen: boolean;
32
+ asideOpen: boolean;
33
+ inputRef: React.RefObject<HTMLDivElement>;
34
+ scrollRef: React.RefObject<HTMLDivElement>;
35
+ setTopicDraft: (val: string | null) => void;
36
+ setConfirmClear: (val: boolean) => void;
37
+ setMentionIdx: (val: number) => void;
38
+ setRounds: (val: number) => void;
39
+ setNavOpen: (val: boolean) => void;
40
+ setAsideOpen: (val: boolean) => void;
41
+ togglePart: (rid: string) => void;
42
+ onMsgsScroll: () => void;
43
+ onInputCE: () => void;
44
+ onInputKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => void;
45
+ onPasteCE: (e: React.ClipboardEvent<HTMLDivElement>) => void;
46
+ onDropCE: (e: React.DragEvent<HTMLDivElement>) => void;
47
+ onDragOverCE: (e: React.DragEvent<HTMLDivElement>) => void;
48
+ insertChip: (role: SnapshotRole) => void;
49
+ insertFileChip: (path: string, kind: 'file' | 'directory') => void;
50
+ sendMsg: () => Promise<void>;
51
+ stopRun: () => Promise<void>;
52
+ action: (payload: Record<string, unknown>) => Promise<unknown>;
53
+ mutate: (args: Record<string, unknown>) => Promise<unknown>;
54
+ setMention: (val: AtToken | null) => void;
55
+ }
56
+ export declare function ChatPanel(props: ChatPanelProps): ReactNode;
57
+ export {};
@@ -0,0 +1,48 @@
1
+ /**
2
+ * 消息输入编辑器组件
3
+ * @module dsh-group-chat/client/components
4
+ */
5
+ import type { ReactNode, KeyboardEvent as ReactKeyboardEvent, ClipboardEvent as ReactClipboardEvent, DragEvent as ReactDragEvent } from 'react';
6
+ import { type ClientSnapshot, type SnapshotRole } from '../lib/model.ts';
7
+ import type { AtToken } from '../../shared/file-mention-grammar.ts';
8
+ interface ComposerProps {
9
+ snap: ClientSnapshot;
10
+ sess: ClientSnapshot['sessions'][number] | null;
11
+ group: ClientSnapshot['groups'][number];
12
+ enabledRoles: SnapshotRole[];
13
+ participants: string[];
14
+ mentionedRoles: SnapshotRole[];
15
+ busyNow: boolean;
16
+ input: string;
17
+ mention: AtToken | null;
18
+ mentionCandidates: SnapshotRole[];
19
+ mentionIdxC: number;
20
+ fileCandidates: Array<{
21
+ path: string;
22
+ isDir: boolean;
23
+ }>;
24
+ fileSearchError: string | null;
25
+ fileSearchLoading: boolean;
26
+ rounds: number;
27
+ err: string;
28
+ atBottom: boolean;
29
+ bubblesLength: number;
30
+ inputRef: React.RefObject<HTMLDivElement>;
31
+ scrollRef: React.RefObject<HTMLDivElement>;
32
+ setMentionIdx: (val: number) => void;
33
+ setRounds: (val: number) => void;
34
+ togglePart: (rid: string) => void;
35
+ onInputCE: () => void;
36
+ onInputKeyDown: (e: ReactKeyboardEvent<HTMLDivElement>) => void;
37
+ onPasteCE: (e: ReactClipboardEvent<HTMLDivElement>) => void;
38
+ onDropCE: (e: ReactDragEvent<HTMLDivElement>) => void;
39
+ onDragOverCE: (e: ReactDragEvent<HTMLDivElement>) => void;
40
+ insertChip: (role: SnapshotRole) => void;
41
+ insertFileChip: (path: string, kind: 'file' | 'directory') => void;
42
+ sendMsg: () => Promise<void>;
43
+ stopRun: () => Promise<void>;
44
+ mutate: (args: Record<string, unknown>) => Promise<unknown>;
45
+ setMention: (val: AtToken | null) => void;
46
+ }
47
+ export declare function Composer(props: ComposerProps): ReactNode;
48
+ export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 侧边栏入口图标。
3
+ *
4
+ * 整行命中层携带 “newSession” 类名:任务看板等 DOM 注入式面板用
5
+ * [class*="newSession"] 识别“侧边栏导航点击”并自动收起自己,与点击
6
+ * “新建会话”行为一致——类名不可哈希化。
7
+ * @module dsh-group-chat/client/glyph
8
+ */
9
+ import type { ReactNode } from 'react';
10
+ export declare function Glyph(props: {
11
+ size?: number;
12
+ }): ReactNode;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 设置页:启停开关(settings.section 插槽)。写 host 的 group-chat 设置
3
+ * 命名空间(settings.yaml 持久化)。
4
+ * @module dsh-group-chat/client/settings
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
8
+ /** Host 侧注册的设置命名空间 shape。 */
9
+ interface GroupChatSettings {
10
+ enabled?: boolean;
11
+ }
12
+ export declare function GroupChatSettingsSection(props: {
13
+ settingsScope: SettingsScope<GroupChatSettings>;
14
+ }): ReactNode;
15
+ export {};
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 消息流显示组件
3
+ * @module dsh-group-chat/client/components
4
+ */
5
+ import type { ReactNode } from 'react';
6
+ import { type ClientSnapshot } from '../lib/model.ts';
7
+ interface MessageFlowProps {
8
+ snap: ClientSnapshot;
9
+ sess: ClientSnapshot['sessions'][number] | null;
10
+ busyNow: boolean;
11
+ msgById: Record<string, ClientSnapshot['messages'][number]>;
12
+ action: (payload: Record<string, unknown>) => Promise<unknown>;
13
+ }
14
+ export declare function MessageFlow(props: MessageFlowProps): ReactNode;
15
+ export {};
@@ -0,0 +1,40 @@
1
+ /**
2
+ * 左侧导航栏组件
3
+ * @module dsh-group-chat/client/components
4
+ */
5
+ import type { ReactNode } from 'react';
6
+ import { type ClientSnapshot } from '../lib/model.ts';
7
+ interface NavPanelProps {
8
+ snap: ClientSnapshot;
9
+ search: string;
10
+ setSearch: (val: string) => void;
11
+ collapsedGroups: Set<string>;
12
+ setCollapsedGroups: (fn: (prev: Set<string>) => Set<string>) => void;
13
+ gid: string | null;
14
+ sid: string | null;
15
+ setGid: (val: string) => void;
16
+ setSid: (val: string) => void;
17
+ setPartsSel: (val: string[] | null) => void;
18
+ renameDraft: {
19
+ kind: 'group' | 'session';
20
+ id: string;
21
+ value: string;
22
+ } | null;
23
+ setRenameDraft: (val: {
24
+ kind: 'group' | 'session';
25
+ id: string;
26
+ value: string;
27
+ } | null) => void;
28
+ confirmDel: {
29
+ kind: 'group' | 'session';
30
+ id: string;
31
+ } | null;
32
+ setConfirmDel: (val: {
33
+ kind: 'group' | 'session';
34
+ id: string;
35
+ } | null) => void;
36
+ mutate: (args: Record<string, unknown>) => Promise<unknown>;
37
+ navOpen: boolean;
38
+ }
39
+ export declare function NavPanel(props: NavPanelProps): ReactNode;
40
+ export {};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 群组权限档位选择器(对齐主会话 composer 左下角的 /permission 选择器):
3
+ * 触发芯片(盾形图标 + 档位名 + chevron)+ Menu 上弹三档 + 完全权限风险
4
+ * 确认弹窗(与主会话同款 RiskConfirmation 原语与文案)。
5
+ * @module dsh-group-chat/client/permission-select
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ import type { PermissionTier } from '../../core/types.ts';
9
+ export interface PermissionSelectProps {
10
+ tier: PermissionTier;
11
+ onSelect: (tier: PermissionTier) => void;
12
+ }
13
+ export declare function PermissionSelect(props: PermissionSelectProps): ReactNode;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 角色编辑抽屉(右侧滑出,不遮挡会话流阅读)。
3
+ * @module dsh-group-chat/client/drawer
4
+ */
5
+ import { type ReactNode } from 'react';
6
+ import { type ModelsResponse, type RoleDraft } from '../lib/model.ts';
7
+ export interface RoleDrawerProps {
8
+ draft: RoleDraft;
9
+ set: (draft: RoleDraft) => void;
10
+ models: ModelsResponse | null;
11
+ modelsError: string | null;
12
+ onRetryModels: () => void;
13
+ onSave: () => void;
14
+ onCancel: () => void;
15
+ formError: string;
16
+ }
17
+ export declare function RoleDrawer(props: RoleDrawerProps): ReactNode;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 思考折叠行(对标宿主 ReasoningRow:折叠摘要 / 展开全文)。
3
+ * @module dsh-group-chat/client/ThinkRow
4
+ */
5
+ import { type ReactNode } from 'react';
6
+ export declare function ThinkRow(props: {
7
+ text: string;
8
+ running?: boolean;
9
+ }): ReactNode;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 工具调用折叠行(对标思考折叠:摘要行 / 展开输出)。
3
+ * @module dsh-group-chat/client/ToolRow
4
+ */
5
+ import { type ReactNode } from 'react';
6
+ import type { ToolCallView } from '../lib/model.ts';
7
+ export declare function ToolRow(props: {
8
+ c: ToolCallView;
9
+ }): ReactNode;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 组件统一导出
3
+ * @module dsh-group-chat/client/components
4
+ */
5
+ export * from './NavPanel.tsx';
6
+ export * from './AsidePanel.tsx';
7
+ export * from './ChatPanel.tsx';
8
+ export * from './Composer.tsx';
9
+ export * from './MessageFlow.tsx';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * 会话流内容组件:思考折叠行、工具调用折叠行、聊天气泡。
3
+ * 对标宿主同源渲染(MarkdownText 正文 + 思考折叠行 + CodeBlock 代码块)。
4
+ * @module dsh-group-chat/client/components
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import { Icon } from './ui.ts';
8
+ import { type ClientSnapshot, type ToolCallView } from './model.ts';
9
+ /** 思考折叠行(对标宿主 ReasoningRow:折叠摘要 / 展开全文)。 */
10
+ export declare function ThinkRow(props: {
11
+ text: string;
12
+ running?: boolean;
13
+ }): ReactNode;
14
+ export declare function ToolRow(props: {
15
+ c: ToolCallView;
16
+ }): ReactNode;
17
+ /** 聊天消息(user / system / 角色发言)。 */
18
+ export declare function Bubble(props: {
19
+ snap: ClientSnapshot;
20
+ m: ClientSnapshot['messages'][number];
21
+ }): ReactNode;
22
+ export { Icon };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 角色编辑抽屉(右侧滑出,不遮挡会话流阅读)。
3
+ * @module dsh-group-chat/client/drawer
4
+ */
5
+ import { type ReactNode } from 'react';
6
+ import { type ModelsResponse, type RoleDraft } from './model.ts';
7
+ export interface RoleDrawerProps {
8
+ draft: RoleDraft;
9
+ set: (draft: RoleDraft) => void;
10
+ models: ModelsResponse | null;
11
+ modelsError: string | null;
12
+ onRetryModels: () => void;
13
+ onSave: () => void;
14
+ onCancel: () => void;
15
+ formError: string;
16
+ }
17
+ export declare function RoleDrawer(props: RoleDrawerProps): ReactNode;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 侧边栏入口图标。
3
+ *
4
+ * 整行命中层携带 “newSession” 类名:任务看板等 DOM 注入式面板用
5
+ * [class*="newSession"] 识别“侧边栏导航点击”并自动收起自己,与点击
6
+ * “新建会话”行为一致——类名不可哈希化。
7
+ * @module dsh-group-chat/client/glyph
8
+ */
9
+ import type { ReactNode } from 'react';
10
+ export declare function Glyph(props: {
11
+ size?: number;
12
+ }): ReactNode;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Hooks 统一导出
3
+ * @module dsh-group-chat/client/hooks
4
+ */
5
+ export * from './useGroupChatState.ts';
6
+ export * from './useComposer.ts';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 消息输入相关 hooks
3
+ * @module dsh-group-chat/client/hooks
4
+ */
5
+ import { type ClipboardEvent as ReactClipboardEvent, type DragEvent as ReactDragEvent, type KeyboardEvent as ReactKeyboardEvent } from 'react';
6
+ import type { AtToken } from '../../shared/file-mention-grammar.ts';
7
+ import type { SnapshotRole } from '../lib/model.ts';
8
+ export declare function useComposerEffects(inputRef: React.RefObject<HTMLDivElement>, scrollRef: React.RefObject<HTMLDivElement>, input: string, atBottom: boolean, snap: unknown): {
9
+ onMsgsScroll: () => boolean | undefined;
10
+ };
11
+ export declare function useComposerInput(inputRef: React.RefObject<HTMLDivElement>, setInput: (val: string) => void, setMention: (val: AtToken | null) => void, setMentionIdx: (val: number) => void): {
12
+ syncFromDOM: () => void;
13
+ onInputCE: () => void;
14
+ onPasteCE: (e: ReactClipboardEvent<HTMLDivElement>) => void;
15
+ onDragOverCE: (e: ReactDragEvent<HTMLDivElement>) => void;
16
+ onDropCE: (e: ReactDragEvent<HTMLDivElement>) => void;
17
+ };
18
+ export declare function useMentionChip(inputRef: React.RefObject<HTMLDivElement>, setMention: (val: AtToken | null) => void, setMentionIdx: (val: number) => void, syncFromDOM: () => void): {
19
+ insertChip: (role: SnapshotRole) => void;
20
+ insertFileChip: (path: string, kind: "file" | "directory") => void;
21
+ };
22
+ export declare function useInputKeyboard(mention: AtToken | null, mentionCandidates: SnapshotRole[], mentionIdxC: number, setMentionIdx: (val: number | ((prev: number) => number)) => void, insertChip: (role: SnapshotRole) => void, insertFileChip: (path: string, kind: 'file' | 'directory') => void, fileCandidates: Array<{
23
+ path: string;
24
+ isDir: boolean;
25
+ }>, setMention: (val: AtToken | null) => void, sendMsg: () => Promise<void>): {
26
+ onInputKeyDown: (e: ReactKeyboardEvent<HTMLDivElement>) => void;
27
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 文件搜索 hook:防抖 + 取消过期请求 + 短缓存。
3
+ * @module dsh-group-chat/client/hooks
4
+ */
5
+ import type { AtToken } from '../../shared/file-mention-grammar.ts';
6
+ export interface FileCandidate {
7
+ path: string;
8
+ isDir: boolean;
9
+ }
10
+ export interface FileSearchResult {
11
+ fileCandidates: FileCandidate[];
12
+ fileSearchError: string | null;
13
+ fileSearchLoading: boolean;
14
+ }
15
+ /**
16
+ * 文件搜索:query 变化 180ms 内合并;过期 fetch 真正 abort;
17
+ * 命中短缓存立刻出结果。离开文件模式才清空列表,避免每个按键闪「检索中」。
18
+ */
19
+ export declare function useFileSearch(mention: AtToken | null, groupId: string | undefined): FileSearchResult;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * 群聊面板核心状态管理 hook
3
+ * @module dsh-group-chat/client/hooks
4
+ */
5
+ import type { ClientSnapshot, ModelsResponse, RoleDraft } from '../lib/model.ts';
6
+ import type { AtToken } from '../../shared/file-mention-grammar.ts';
7
+ export interface MutateResponse {
8
+ ok: boolean;
9
+ snapshot?: ClientSnapshot;
10
+ lastCreated?: ClientSnapshot['lastCreated'];
11
+ error?: string;
12
+ }
13
+ export interface ActionOk {
14
+ ok: boolean;
15
+ error?: string;
16
+ }
17
+ export declare function useGroupChatState(): {
18
+ snap: ClientSnapshot | null;
19
+ setSnap: (s: ClientSnapshot) => void;
20
+ gid: string | null;
21
+ setGid: (v: string) => void;
22
+ sid: string | null;
23
+ setSid: (v: string) => void;
24
+ search: string;
25
+ setSearch: import("react").Dispatch<import("react").SetStateAction<string>>;
26
+ collapsedGroups: Set<string>;
27
+ setCollapsedGroups: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
28
+ renameDraft: {
29
+ kind: "group" | "session";
30
+ id: string;
31
+ value: string;
32
+ } | null;
33
+ setRenameDraft: import("react").Dispatch<import("react").SetStateAction<{
34
+ kind: "group" | "session";
35
+ id: string;
36
+ value: string;
37
+ } | null>>;
38
+ confirmDel: {
39
+ kind: "group" | "session";
40
+ id: string;
41
+ } | null;
42
+ setConfirmDel: import("react").Dispatch<import("react").SetStateAction<{
43
+ kind: "group" | "session";
44
+ id: string;
45
+ } | null>>;
46
+ confirmClear: boolean;
47
+ setConfirmClear: import("react").Dispatch<import("react").SetStateAction<boolean>>;
48
+ roleDraft: RoleDraft | null;
49
+ setRoleDraft: import("react").Dispatch<import("react").SetStateAction<RoleDraft | null>>;
50
+ roleFormError: string;
51
+ setRoleFormError: import("react").Dispatch<import("react").SetStateAction<string>>;
52
+ models: ModelsResponse | null;
53
+ setModels: import("react").Dispatch<import("react").SetStateAction<ModelsResponse | null>>;
54
+ modelsError: string | null;
55
+ setModelsError: import("react").Dispatch<import("react").SetStateAction<string | null>>;
56
+ fileBrowser: {
57
+ open: boolean;
58
+ loading: boolean;
59
+ list: import("../../core/types.ts").BrowseResult | null;
60
+ error: string;
61
+ } | null;
62
+ setFileBrowser: import("react").Dispatch<import("react").SetStateAction<{
63
+ open: boolean;
64
+ loading: boolean;
65
+ list: import("../../core/types.ts").BrowseResult | null;
66
+ error: string;
67
+ } | null>>;
68
+ wsDraft: string | null;
69
+ setWsDraft: import("react").Dispatch<import("react").SetStateAction<string | null>>;
70
+ partsSel: string[] | null;
71
+ setPartsSel: import("react").Dispatch<import("react").SetStateAction<string[] | null>>;
72
+ rounds: number;
73
+ setRounds: import("react").Dispatch<import("react").SetStateAction<number>>;
74
+ input: string;
75
+ setInput: import("react").Dispatch<import("react").SetStateAction<string>>;
76
+ err: string;
77
+ setErr: import("react").Dispatch<import("react").SetStateAction<string>>;
78
+ topicDraft: string | null;
79
+ setTopicDraft: import("react").Dispatch<import("react").SetStateAction<string | null>>;
80
+ mention: AtToken | null;
81
+ setMention: import("react").Dispatch<import("react").SetStateAction<AtToken | null>>;
82
+ mentionIdx: number;
83
+ setMentionIdx: import("react").Dispatch<import("react").SetStateAction<number>>;
84
+ asideOpen: boolean;
85
+ setAsideOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
86
+ navOpen: boolean;
87
+ setNavOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
88
+ atBottom: boolean;
89
+ setAtBottom: import("react").Dispatch<import("react").SetStateAction<boolean>>;
90
+ inputRef: import("react").MutableRefObject<HTMLDivElement | null>;
91
+ sendingRef: import("react").MutableRefObject<boolean>;
92
+ scrollRef: import("react").MutableRefObject<HTMLDivElement | null>;
93
+ action: (payload: Record<string, unknown>) => Promise<unknown>;
94
+ mutate: (args: Record<string, unknown>) => Promise<MutateResponse | null>;
95
+ };