@meiyukichan/dsh-sandore 0.1.0-rc.6

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 (295) hide show
  1. package/LICENSE +201 -0
  2. package/cordis.patch.yml +39 -0
  3. package/dsh.plugin.json +16 -0
  4. package/lib/client/CommandEditor.d.ts +19 -0
  5. package/lib/client/DagEditor.d.ts +22 -0
  6. package/lib/client/DefinitionDetail.d.ts +13 -0
  7. package/lib/client/DefinitionList.d.ts +19 -0
  8. package/lib/client/DiscussionInput.d.ts +63 -0
  9. package/lib/client/DragHandle.d.ts +16 -0
  10. package/lib/client/EditorPane.d.ts +13 -0
  11. package/lib/client/FlowEditor.d.ts +31 -0
  12. package/lib/client/InstanceList.d.ts +24 -0
  13. package/lib/client/NewInstanceDialog.d.ts +19 -0
  14. package/lib/client/PreviewPanel.d.ts +13 -0
  15. package/lib/client/RunView.d.ts +79 -0
  16. package/lib/client/StepChatPanel.d.ts +34 -0
  17. package/lib/client/TreeNav.d.ts +27 -0
  18. package/lib/client/UnifiedTimeline.d.ts +11 -0
  19. package/lib/client/WorkflowButton.d.ts +11 -0
  20. package/lib/client/WorkflowList.d.ts +18 -0
  21. package/lib/client/WorkflowOverlay.d.ts +6 -0
  22. package/lib/client/chat/AssistantMarkdown.d.ts +22 -0
  23. package/lib/client/chat/CompactionItem.d.ts +24 -0
  24. package/lib/client/chat/ContextBody.d.ts +136 -0
  25. package/lib/client/chat/ContextInjectionRow.d.ts +25 -0
  26. package/lib/client/chat/GenericCommandCard.d.ts +10 -0
  27. package/lib/client/chat/MessageIconActions.d.ts +41 -0
  28. package/lib/client/chat/MessageItem.d.ts +65 -0
  29. package/lib/client/chat/ReasoningRow.d.ts +13 -0
  30. package/lib/client/chat/TurnTailNodeView.d.ts +29 -0
  31. package/lib/client/chat/UserMessageRow.d.ts +18 -0
  32. package/lib/client/chat/attachment/ImageLightbox.d.ts +26 -0
  33. package/lib/client/chat/attachment/MessageImage.d.ts +56 -0
  34. package/lib/client/chat/attachment/image-attachment.d.ts +41 -0
  35. package/lib/client/chat/attachment/image-labels.d.ts +21 -0
  36. package/lib/client/chat/message-chrome.d.ts +51 -0
  37. package/lib/client/chat/reference/ReferenceIcon.d.ts +20 -0
  38. package/lib/client/chat/turn-assistant.d.ts +12 -0
  39. package/lib/client/chat/turn-metrics.d.ts +42 -0
  40. package/lib/client/chat/use-calendar-day.d.ts +5 -0
  41. package/lib/client/chat/use-throttled-visual-update.d.ts +7 -0
  42. package/lib/client/chat-flow.d.ts +110 -0
  43. package/lib/client/composer-selects.d.ts +17 -0
  44. package/lib/client/dag-editor-model.d.ts +141 -0
  45. package/lib/client/describe-error.d.ts +9 -0
  46. package/lib/client/index.d.ts +6 -0
  47. package/lib/client/locales.d.ts +777 -0
  48. package/lib/client/model-faces.d.ts +156 -0
  49. package/lib/client/open-discussion.d.ts +24 -0
  50. package/lib/client/panel-model.d.ts +34 -0
  51. package/lib/client/remote.d.ts +34 -0
  52. package/lib/client/run-view-model.d.ts +304 -0
  53. package/lib/client/sandore-save.d.ts +41 -0
  54. package/lib/client/sandore-sse.d.ts +15 -0
  55. package/lib/client/step-chat-retry.d.ts +44 -0
  56. package/lib/client/tool/GenericToolCard.d.ts +28 -0
  57. package/lib/client/tool/ToolRow.d.ts +95 -0
  58. package/lib/client/tool/diff-card-model.d.ts +63 -0
  59. package/lib/client/tool/read-card-model.d.ts +67 -0
  60. package/lib/client/tool/search-card-model.d.ts +94 -0
  61. package/lib/client/tool/terminal-card-model.d.ts +86 -0
  62. package/lib/client/tool/tool-call-model.d.ts +74 -0
  63. package/lib/client/tool/web-card-model.d.ts +44 -0
  64. package/lib/client/use-focus-refresh.d.ts +1 -0
  65. package/lib/client/workflow-face.d.ts +68 -0
  66. package/lib/client/workflow-store.d.ts +80 -0
  67. package/lib/client/workspace-path.d.ts +15 -0
  68. package/lib/client.js +38389 -0
  69. package/lib/index.js +8854 -0
  70. package/lib/microflow/branch-evaluator.d.ts +290 -0
  71. package/lib/microflow/concurrency-limiter.d.ts +39 -0
  72. package/lib/microflow/errors.d.ts +39 -0
  73. package/lib/microflow/file-utils.d.ts +210 -0
  74. package/lib/microflow/finalize-manager.d.ts +414 -0
  75. package/lib/microflow/fork-session.d.ts +151 -0
  76. package/lib/microflow/index.d.ts +17 -0
  77. package/lib/microflow/internal.d.ts +56 -0
  78. package/lib/microflow/loop-manager.d.ts +127 -0
  79. package/lib/microflow/rules-resolver.d.ts +28 -0
  80. package/lib/microflow/stage-executor.d.ts +362 -0
  81. package/lib/microflow/step-navigator.d.ts +108 -0
  82. package/lib/microflow/step-runner.d.ts +190 -0
  83. package/lib/microflow/subagents.d.ts +380 -0
  84. package/lib/tool/index.d.ts +65 -0
  85. package/lib/typert.host.d.ts +16 -0
  86. package/lib/typert.host.js +25 -0
  87. package/lib/typert.remote-client.d.ts +114 -0
  88. package/lib/typert.remote-client.js +399 -0
  89. package/lib/workflow/ask-tool.d.ts +78 -0
  90. package/lib/workflow/dag-navigator.d.ts +136 -0
  91. package/lib/workflow/domain.d.ts +304 -0
  92. package/lib/workflow/engine-surface.d.ts +70 -0
  93. package/lib/workflow/errors.d.ts +13 -0
  94. package/lib/workflow/host-agent.d.ts +53 -0
  95. package/lib/workflow/index.d.ts +23 -0
  96. package/lib/workflow/interaction-manager.d.ts +170 -0
  97. package/lib/workflow/lifecycle-manager.d.ts +111 -0
  98. package/lib/workflow/persistence.d.ts +35 -0
  99. package/lib/workflow/plugin.d.ts +27 -0
  100. package/lib/workflow/reactive-state.d.ts +27 -0
  101. package/lib/workflow/recovery-manager.d.ts +158 -0
  102. package/lib/workflow/remote.d.ts +139 -0
  103. package/lib/workflow/schema.d.ts +1917 -0
  104. package/lib/workflow/seam.d.ts +254 -0
  105. package/lib/workflow/shell.d.ts +127 -0
  106. package/lib/workflow/sse.d.ts +16 -0
  107. package/lib/workflow/typert/typert.host.d.ts +16 -0
  108. package/lib/workflow/typert/typert.remote-client.d.ts +114 -0
  109. package/lib/workflow/types.d.ts +187 -0
  110. package/lib/workflow/wire.d.ts +256 -0
  111. package/lib/workflow/workflow-engine.d.ts +373 -0
  112. package/lib/workflow/yaml-error.d.ts +22 -0
  113. package/lib/workflow/yaml-parser.d.ts +23 -0
  114. package/package.json +140 -0
  115. package/packages/client/CommandEditor.tsx +73 -0
  116. package/packages/client/DagEditor.module.css +711 -0
  117. package/packages/client/DagEditor.tsx +1203 -0
  118. package/packages/client/DefinitionDetail.module.css +110 -0
  119. package/packages/client/DefinitionDetail.tsx +126 -0
  120. package/packages/client/DefinitionList.tsx +173 -0
  121. package/packages/client/DiscussionInput.tsx +763 -0
  122. package/packages/client/DragHandle.tsx +92 -0
  123. package/packages/client/EditorPane.tsx +70 -0
  124. package/packages/client/FlowEditor.tsx +227 -0
  125. package/packages/client/InstanceList.tsx +250 -0
  126. package/packages/client/NewInstanceDialog.module.css +244 -0
  127. package/packages/client/NewInstanceDialog.tsx +478 -0
  128. package/packages/client/PreviewPanel.tsx +55 -0
  129. package/packages/client/RunView.module.css +246 -0
  130. package/packages/client/RunView.tsx +314 -0
  131. package/packages/client/StepChatPanel.tsx +486 -0
  132. package/packages/client/TreeNav.tsx +294 -0
  133. package/packages/client/UnifiedTimeline.tsx +484 -0
  134. package/packages/client/WorkflowButton.module.css +72 -0
  135. package/packages/client/WorkflowButton.tsx +50 -0
  136. package/packages/client/WorkflowList.tsx +158 -0
  137. package/packages/client/WorkflowOverlay.module.css +390 -0
  138. package/packages/client/WorkflowOverlay.tsx +136 -0
  139. package/packages/client/WorkflowPanel.module.css +247 -0
  140. package/packages/client/chat/AssistantMarkdown.module.css +38 -0
  141. package/packages/client/chat/AssistantMarkdown.tsx +120 -0
  142. package/packages/client/chat/ChatView.module.css +198 -0
  143. package/packages/client/chat/CompactionItem.tsx +85 -0
  144. package/packages/client/chat/ContextBody.module.css +162 -0
  145. package/packages/client/chat/ContextBody.tsx +598 -0
  146. package/packages/client/chat/ContextInjectionRow.module.css +63 -0
  147. package/packages/client/chat/ContextInjectionRow.tsx +78 -0
  148. package/packages/client/chat/GenericCommandCard.module.css +87 -0
  149. package/packages/client/chat/GenericCommandCard.tsx +76 -0
  150. package/packages/client/chat/MessageIconActions.module.css +84 -0
  151. package/packages/client/chat/MessageIconActions.tsx +147 -0
  152. package/packages/client/chat/MessageItem.module.css +293 -0
  153. package/packages/client/chat/MessageItem.tsx +384 -0
  154. package/packages/client/chat/ReasoningRow.module.css +82 -0
  155. package/packages/client/chat/ReasoningRow.tsx +70 -0
  156. package/packages/client/chat/TurnTailNodeView.module.css +10 -0
  157. package/packages/client/chat/TurnTailNodeView.tsx +63 -0
  158. package/packages/client/chat/UserMessageRow.module.css +75 -0
  159. package/packages/client/chat/UserMessageRow.tsx +92 -0
  160. package/packages/client/chat/accessibility.module.css +9 -0
  161. package/packages/client/chat/attachment/ImageLightbox.module.css +45 -0
  162. package/packages/client/chat/attachment/ImageLightbox.tsx +70 -0
  163. package/packages/client/chat/attachment/MessageImage.module.css +70 -0
  164. package/packages/client/chat/attachment/MessageImage.tsx +136 -0
  165. package/packages/client/chat/attachment/image-attachment.ts +98 -0
  166. package/packages/client/chat/attachment/image-labels.ts +34 -0
  167. package/packages/client/chat/message-chrome.ts +96 -0
  168. package/packages/client/chat/reference/ReferenceIcon.tsx +40 -0
  169. package/packages/client/chat/turn-assistant.ts +15 -0
  170. package/packages/client/chat/turn-metrics.ts +102 -0
  171. package/packages/client/chat/use-calendar-day.ts +27 -0
  172. package/packages/client/chat/use-throttled-visual-update.ts +44 -0
  173. package/packages/client/chat-flow.spec.ts +357 -0
  174. package/packages/client/chat-flow.ts +278 -0
  175. package/packages/client/composer-selects.module.css +376 -0
  176. package/packages/client/composer-selects.tsx +531 -0
  177. package/packages/client/dag-editor-model.spec.ts +173 -0
  178. package/packages/client/dag-editor-model.ts +359 -0
  179. package/packages/client/describe-error.spec.ts +18 -0
  180. package/packages/client/describe-error.ts +12 -0
  181. package/packages/client/index.ts +144 -0
  182. package/packages/client/input.module.css +854 -0
  183. package/packages/client/is-conditional-check.spec.ts +34 -0
  184. package/packages/client/locales.ts +789 -0
  185. package/packages/client/model-faces.ts +225 -0
  186. package/packages/client/open-discussion.spec.ts +39 -0
  187. package/packages/client/open-discussion.ts +32 -0
  188. package/packages/client/panel-model.spec.ts +152 -0
  189. package/packages/client/panel-model.ts +72 -0
  190. package/packages/client/preview.module.css +95 -0
  191. package/packages/client/react-dom.d.ts +11 -0
  192. package/packages/client/reactflow-theme.css +91 -0
  193. package/packages/client/remote.spec.ts +41 -0
  194. package/packages/client/remote.ts +46 -0
  195. package/packages/client/run-view-model.spec.ts +641 -0
  196. package/packages/client/run-view-model.ts +636 -0
  197. package/packages/client/sandore-save.spec.ts +146 -0
  198. package/packages/client/sandore-save.ts +97 -0
  199. package/packages/client/sandore-sse.ts +59 -0
  200. package/packages/client/step-chat-retry.spec.ts +70 -0
  201. package/packages/client/step-chat-retry.ts +65 -0
  202. package/packages/client/timeline.module.css +503 -0
  203. package/packages/client/tool/GenericToolCard.tsx +99 -0
  204. package/packages/client/tool/ToolRow.module.css +308 -0
  205. package/packages/client/tool/ToolRow.tsx +328 -0
  206. package/packages/client/tool/diff-card-model.ts +103 -0
  207. package/packages/client/tool/read-card-model.ts +86 -0
  208. package/packages/client/tool/search-card-model.ts +166 -0
  209. package/packages/client/tool/terminal-card-model.ts +225 -0
  210. package/packages/client/tool/tool-call-model.ts +267 -0
  211. package/packages/client/tool/web-card-model.ts +80 -0
  212. package/packages/client/tree-nav.module.css +282 -0
  213. package/packages/client/use-focus-refresh.ts +23 -0
  214. package/packages/client/workflow-face.ts +72 -0
  215. package/packages/client/workflow-store.spec.ts +49 -0
  216. package/packages/client/workflow-store.ts +161 -0
  217. package/packages/client/workspace-path.ts +27 -0
  218. package/packages/css-modules.d.ts +6 -0
  219. package/packages/microflow/branch-evaluator.spec.ts +745 -0
  220. package/packages/microflow/branch-evaluator.ts +1037 -0
  221. package/packages/microflow/concurrency-limiter.ts +70 -0
  222. package/packages/microflow/errors.ts +64 -0
  223. package/packages/microflow/file-utils.spec.ts +604 -0
  224. package/packages/microflow/file-utils.ts +521 -0
  225. package/packages/microflow/finalize-manager.spec.ts +1977 -0
  226. package/packages/microflow/finalize-manager.ts +1464 -0
  227. package/packages/microflow/fork-session.spec.ts +184 -0
  228. package/packages/microflow/fork-session.ts +316 -0
  229. package/packages/microflow/index.ts +17 -0
  230. package/packages/microflow/internal.ts +166 -0
  231. package/packages/microflow/loop-manager.spec.ts +294 -0
  232. package/packages/microflow/loop-manager.ts +255 -0
  233. package/packages/microflow/rules-resolver.spec.ts +147 -0
  234. package/packages/microflow/rules-resolver.ts +58 -0
  235. package/packages/microflow/stage-executor.spec.ts +1577 -0
  236. package/packages/microflow/stage-executor.ts +1478 -0
  237. package/packages/microflow/step-navigator.spec.ts +301 -0
  238. package/packages/microflow/step-navigator.ts +300 -0
  239. package/packages/microflow/step-runner.spec.ts +1132 -0
  240. package/packages/microflow/step-runner.ts +752 -0
  241. package/packages/microflow/subagents.spec.ts +215 -0
  242. package/packages/microflow/subagents.ts +422 -0
  243. package/packages/tests/fixtures/test-workflow.yaml +128 -0
  244. package/packages/tests/mocks/agents.ts +206 -0
  245. package/packages/tests/mocks/llm.ts +46 -0
  246. package/packages/tests/mocks/session-title.ts +31 -0
  247. package/packages/tests/mocks/sessions.ts +131 -0
  248. package/packages/tests/mocks/shell.ts +60 -0
  249. package/packages/tests/mocks/storage-domain.ts +101 -0
  250. package/packages/tests/mocks/subagents.ts +197 -0
  251. package/packages/tests/mocks/subprocess.ts +59 -0
  252. package/packages/tests/mocks/user-questions.ts +33 -0
  253. package/packages/tests/mocks/workspace.ts +52 -0
  254. package/packages/tool/index.spec.ts +287 -0
  255. package/packages/tool/index.ts +348 -0
  256. package/packages/workflow/ask-tool.ts +173 -0
  257. package/packages/workflow/dag-navigator.spec.ts +236 -0
  258. package/packages/workflow/dag-navigator.ts +425 -0
  259. package/packages/workflow/domain.ts +26 -0
  260. package/packages/workflow/engine-surface.ts +71 -0
  261. package/packages/workflow/errors.ts +13 -0
  262. package/packages/workflow/host-agent.spec.ts +92 -0
  263. package/packages/workflow/host-agent.ts +62 -0
  264. package/packages/workflow/index.ts +25 -0
  265. package/packages/workflow/interaction-manager.spec.ts +390 -0
  266. package/packages/workflow/interaction-manager.ts +397 -0
  267. package/packages/workflow/lifecycle-manager.spec.ts +683 -0
  268. package/packages/workflow/lifecycle-manager.ts +288 -0
  269. package/packages/workflow/persistence.spec.ts +109 -0
  270. package/packages/workflow/persistence.ts +64 -0
  271. package/packages/workflow/plugin.ts +39 -0
  272. package/packages/workflow/reactive-state.spec.ts +69 -0
  273. package/packages/workflow/reactive-state.ts +52 -0
  274. package/packages/workflow/recovery-manager.spec.ts +606 -0
  275. package/packages/workflow/recovery-manager.ts +471 -0
  276. package/packages/workflow/remote.spec.ts +1045 -0
  277. package/packages/workflow/remote.ts +479 -0
  278. package/packages/workflow/schema.spec.ts +303 -0
  279. package/packages/workflow/schema.ts +562 -0
  280. package/packages/workflow/seam.ts +293 -0
  281. package/packages/workflow/shell.ts +142 -0
  282. package/packages/workflow/sse.ts +110 -0
  283. package/packages/workflow/typert/typert.host.d.ts +16 -0
  284. package/packages/workflow/typert/typert.host.js +25 -0
  285. package/packages/workflow/typert/typert.remote-client.d.ts +114 -0
  286. package/packages/workflow/typert/typert.remote-client.js +399 -0
  287. package/packages/workflow/types.ts +258 -0
  288. package/packages/workflow/wire.ts +267 -0
  289. package/packages/workflow/workflow-engine-e2e.spec.ts +262 -0
  290. package/packages/workflow/workflow-engine-real-e2e.spec.ts +922 -0
  291. package/packages/workflow/workflow-engine.spec.ts +4389 -0
  292. package/packages/workflow/workflow-engine.ts +2133 -0
  293. package/packages/workflow/yaml-error.ts +29 -0
  294. package/packages/workflow/yaml-parser.spec.ts +757 -0
  295. package/packages/workflow/yaml-parser.ts +287 -0
@@ -0,0 +1,158 @@
1
+ /**
2
+ * WorkflowList:工作流 overlay 左栏列表(实例/定义 toggle + 搜索 + 新增)。
3
+ *
4
+ * 模式切换与选中态走模块级 `workflow-store`(跨 overlay 开合保留);内容区复用
5
+ * `InstanceList`(默认态实例,3s 轮询)与 `DefinitionList`(编排态定义)。
6
+ * @module @deepseek-ai/dsh-client-ui-sandore/src/client/WorkflowList
7
+ */
8
+ import { useState, useSyncExternalStore } from 'react'
9
+ import {
10
+ Button, IconPlusOutline16, IconSearchOutline16, Input,
11
+ } from '@deepseek-ai/dsh-client-ui-primitives'
12
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'
13
+ import type { WorkspaceView } from '@deepseek-ai/dsh-client-runtime/client'
14
+
15
+ import { InstanceList } from './InstanceList.tsx'
16
+ import { DefinitionList } from './DefinitionList.tsx'
17
+ import { NewInstanceDialog } from './NewInstanceDialog.tsx'
18
+ import type { WorkflowOverlayFace } from './workflow-face.ts'
19
+ import {
20
+ getWorkflowState, newDefinition, selectDefinition, selectInstance, setWorkflowState, subscribeWorkflowState, toggleListCollapse,
21
+ } from './workflow-store.ts'
22
+ import css from './WorkflowOverlay.module.css'
23
+
24
+ /** WorkflowList 接收的 props。 */
25
+ export interface WorkflowListProps {
26
+ /** 类型化翻译函数(sandore 命名空间)。 */
27
+ t: TranslateNS<'sandore'>
28
+ /** 工作区成员表(供 InstanceList 按工作区分组)。 */
29
+ workspaces: readonly WorkspaceView[]
30
+ /** 业务 face(列表类 RPC 已解包)。 */
31
+ face: WorkflowOverlayFace
32
+ /** 刷新计数:变化时重挂载列表(保存/删除/手动刷新后)。 */
33
+ refreshKey: number
34
+ /** 列表列宽(px,拖拽分隔条驱动)。 */
35
+ width: number
36
+ }
37
+
38
+ /** 渲染工作流 overlay 左栏列表。 */
39
+ export function WorkflowList({ t, workspaces, face, refreshKey, width }: WorkflowListProps) {
40
+ const listMode = useSyncExternalStore(subscribeWorkflowState, () => getWorkflowState().listMode)
41
+ const selectedInstanceId = useSyncExternalStore(subscribeWorkflowState, () => getWorkflowState().selectedInstanceId)
42
+ const selectedDefinitionId = useSyncExternalStore(subscribeWorkflowState, () => getWorkflowState().selectedDefinition?.id)
43
+ const [query, setQuery] = useState('')
44
+ /** 新增实例弹窗开关(实例模式下「+」按钮打开)。 */
45
+ const [creatingInstance, setCreatingInstance] = useState(false)
46
+ /** 实例列表即时刷新计数:新建/删除实例后 +1,重挂载 InstanceList 立即拉取
47
+ (不等 3s 轮询周期,新建后列表立即可见)。 */
48
+ const [instanceTick, setInstanceTick] = useState(0)
49
+
50
+ return (
51
+ <section className={css.list} style={{ width }} data-sandore-wf-list>
52
+ <header className={css.listHeader}>
53
+ <div className={css.listTitleRow}>
54
+ <div className={css.listTitleGroup}>
55
+ <span className={css.listTitle}>{t('panel.title')}</span>
56
+ {/* 收起左栏:切换为窄条 rail(展开 + 新增)。 */}
57
+ <button
58
+ type="button"
59
+ className={css.railBtn}
60
+ title={t('list.collapse')}
61
+ aria-label={t('list.collapse')}
62
+ onClick={toggleListCollapse}
63
+ >
64
+ {/* panel-left-close:收起左栏。 */}
65
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
66
+ <rect x="3" y="3" width="18" height="18" rx="2" />
67
+ <path d="M9 3v18" />
68
+ <path d="m16 15-3-3 3-3" />
69
+ </svg>
70
+ </button>
71
+ </div>
72
+ {/* 实例/编排 开关:胶囊轨道 + 滑块,点击切换激活侧。 */}
73
+ <div className={css.toggle} role="tablist" aria-label={t('list.mode.switch')}>
74
+ <span className={`${css.toggleThumb} ${listMode === 'definition' ? css.toggleThumbRight : ''}`} />
75
+ <button
76
+ type="button"
77
+ role="tab"
78
+ aria-selected={listMode === 'instance'}
79
+ className={listMode === 'instance' ? css.toggleActive : ''}
80
+ onClick={() => { setWorkflowState({ listMode: 'instance' }) }}
81
+ >
82
+ {t('list.mode.instance')}
83
+ </button>
84
+ <button
85
+ type="button"
86
+ role="tab"
87
+ aria-selected={listMode === 'definition'}
88
+ className={listMode === 'definition' ? css.toggleActive : ''}
89
+ onClick={() => { setWorkflowState({ listMode: 'definition' }) }}
90
+ >
91
+ {t('list.mode.definition')}
92
+ </button>
93
+ </div>
94
+ </div>
95
+ <div className={css.listToolbar}>
96
+ <Input
97
+ className={css.search ?? ''}
98
+ icon={<IconSearchOutline16 />}
99
+ value={query}
100
+ onChange={event => { setQuery(event.target.value) }}
101
+ placeholder={t('panel.search')}
102
+ aria-label={t('panel.search')}
103
+ />
104
+ <Button
105
+ size="sm"
106
+ variant="primary"
107
+ icon={<IconPlusOutline16 />}
108
+ title={t('panel.add.instance.hint')}
109
+ onClick={() => {
110
+ if (listMode === 'instance') setCreatingInstance(true)
111
+ else newDefinition()
112
+ }}
113
+ >
114
+ {listMode === 'definition' ? t('panel.add.definition') : t('panel.add.instance')}
115
+ </Button>
116
+ </div>
117
+ </header>
118
+ <div className={css.listBody}>
119
+ {listMode === 'definition' ? (
120
+ <DefinitionList
121
+ key={`def-${refreshKey}`}
122
+ t={t}
123
+ query={query}
124
+ activeId={selectedDefinitionId}
125
+ listDefinitions={face.listDefinitions}
126
+ deleteDefinition={face.deleteDefinition}
127
+ onOpen={selectDefinition}
128
+ />
129
+ ) : (
130
+ <InstanceList
131
+ key={`inst-${refreshKey}-${instanceTick}`}
132
+ t={t}
133
+ workspaces={workspaces}
134
+ query={query}
135
+ activeId={selectedInstanceId}
136
+ listInstances={face.listInstances}
137
+ deleteInstance={face.deleteInstance}
138
+ onOpen={selectInstance}
139
+ onInstanceDeleted={() => { setInstanceTick(tick => tick + 1) }}
140
+ />
141
+ )}
142
+ </div>
143
+ {creatingInstance && (
144
+ <NewInstanceDialog
145
+ t={t}
146
+ face={face}
147
+ onClose={() => { setCreatingInstance(false) }}
148
+ onCreated={instanceId => {
149
+ setCreatingInstance(false)
150
+ selectInstance(instanceId)
151
+ // 立即重挂载实例列表,让新实例马上可见(不必等轮询周期)。
152
+ setInstanceTick(tick => tick + 1)
153
+ }}
154
+ />
155
+ )}
156
+ </section>
157
+ )
158
+ }
@@ -0,0 +1,390 @@
1
+ /* WorkflowOverlay:shell.overlay 全局工作流 UI(覆盖 conversation/details 列,sidebar 可见)。 */
2
+
3
+ .layer {
4
+ position: absolute;
5
+ inset: 0;
6
+ z-index: 30;
7
+ pointer-events: none;
8
+ }
9
+
10
+ .overlay {
11
+ position: absolute;
12
+ top: 0;
13
+ right: 0;
14
+ bottom: 0;
15
+ left: var(--wf-left, 248px);
16
+ display: flex;
17
+ flex-direction: column;
18
+ min-width: 0;
19
+ background: var(--dsw-alias-bg-base);
20
+ box-shadow: -4px 0 24px rgba(0, 0, 0, 0.08);
21
+ pointer-events: auto;
22
+ animation: overlay-in 0.18s ease;
23
+ }
24
+
25
+ @keyframes overlay-in {
26
+ from {
27
+ transform: translateX(16px);
28
+ opacity: 0;
29
+ }
30
+ to {
31
+ transform: translateX(0);
32
+ opacity: 1;
33
+ }
34
+ }
35
+
36
+ .header {
37
+ flex: none;
38
+ display: flex;
39
+ align-items: center;
40
+ gap: 8px;
41
+ min-height: 44px;
42
+ padding: 0 12px;
43
+ box-sizing: border-box;
44
+ border-bottom: 1px solid var(--dsw-alias-border-l1);
45
+ background: var(--dsw-alias-bg-elevated);
46
+ }
47
+
48
+ .headerTitle {
49
+ font-size: 14px;
50
+ font-weight: 600;
51
+ line-height: 20px;
52
+ color: var(--dsw-alias-label-primary);
53
+ }
54
+
55
+ .spacer {
56
+ flex: 1;
57
+ }
58
+
59
+ .iconBtn {
60
+ display: inline-flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ width: 28px;
64
+ height: 28px;
65
+ padding: 0;
66
+ border: none;
67
+ border-radius: 8px;
68
+ background: transparent;
69
+ color: var(--dsw-alias-label-caption);
70
+ cursor: pointer;
71
+ }
72
+
73
+ .iconBtn:hover {
74
+ background: var(--dsw-alias-bg-hover);
75
+ color: var(--dsw-alias-label-secondary);
76
+ }
77
+
78
+ /* ── 双栏工作台 ─────────────────────────────────────────────────────────── */
79
+
80
+ .body {
81
+ flex: 1;
82
+ min-height: 0;
83
+ display: flex;
84
+ position: relative;
85
+ overflow: hidden;
86
+ }
87
+
88
+ /* 拖拽分隔条(照 DSH AppFrame .drag-handle 观感)。 */
89
+ .dragHandle {
90
+ flex: none;
91
+ width: 7px;
92
+ cursor: col-resize;
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ background: transparent;
97
+ touch-action: none;
98
+ }
99
+
100
+ .dragHandle::after {
101
+ content: '';
102
+ width: 1px;
103
+ height: 100%;
104
+ background: var(--dsw-alias-border-l1);
105
+ transition: background 0.15s, width 0.15s;
106
+ }
107
+
108
+ .dragHandle:hover::after,
109
+ .dragHandle.dragging::after {
110
+ background: var(--dsw-alias-accent-primary);
111
+ width: 2px;
112
+ }
113
+
114
+ /* ── 左栏列表 ────────────────────────────────────────────────────────────── */
115
+
116
+ .list {
117
+ flex: none;
118
+ min-width: 240px;
119
+ display: flex;
120
+ flex-direction: column;
121
+ background: var(--dsw-alias-bg-elevated);
122
+ overflow: hidden;
123
+ }
124
+
125
+ .listHeader {
126
+ flex: none;
127
+ display: flex;
128
+ flex-direction: column;
129
+ gap: 8px;
130
+ padding: 10px 12px;
131
+ box-sizing: border-box;
132
+ border-bottom: 1px solid var(--dsw-alias-border-l2);
133
+ }
134
+
135
+ .listTitleRow {
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: space-between;
139
+ gap: 8px;
140
+ }
141
+
142
+ .listTitle {
143
+ font-size: 13px;
144
+ font-weight: 600;
145
+ line-height: 20px;
146
+ color: var(--dsw-alias-label-primary);
147
+ }
148
+
149
+ /* 标题 + 收起按钮 左组(收起按钮紧贴标题,开关仍贴右缘)。 */
150
+ .listTitleGroup {
151
+ display: inline-flex;
152
+ align-items: center;
153
+ gap: 2px;
154
+ min-width: 0;
155
+ }
156
+
157
+ /* 实例/编排 开关:紧凑黑白配色(白轨道 + 黑滑块)。滑块为选中侧,激活白字/未激活灰字。 */
158
+ .toggle {
159
+ position: relative;
160
+ display: inline-flex;
161
+ align-items: center;
162
+ border-radius: 999px;
163
+ background: #fff;
164
+ border: 1px solid rgba(0, 0, 0, 0.25);
165
+ padding: 2px;
166
+ width: 80px;
167
+ height: 22px;
168
+ box-sizing: border-box;
169
+ }
170
+
171
+ /* 滑块:黑色圆钮(选中侧),左右滑动。 */
172
+ .toggleThumb {
173
+ position: absolute;
174
+ top: 2px;
175
+ left: 2px;
176
+ width: calc(50% - 3px);
177
+ height: calc(100% - 4px);
178
+ border-radius: 999px;
179
+ background: #000;
180
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
181
+ transition: left 0.18s ease;
182
+ pointer-events: none;
183
+ }
184
+
185
+ .toggleThumb.toggleThumbRight {
186
+ left: calc(50% + 1px);
187
+ }
188
+
189
+ .toggle button {
190
+ position: relative;
191
+ z-index: 1;
192
+ flex: 1;
193
+ padding: 0 4px;
194
+ border: none;
195
+ background: transparent;
196
+ font-size: 11px;
197
+ line-height: 18px;
198
+ font-family: inherit;
199
+ text-align: center;
200
+ color: rgba(0, 0, 0, 0.5);
201
+ cursor: pointer;
202
+ transition: color 0.18s ease;
203
+ }
204
+
205
+ .toggle button:hover {
206
+ color: rgba(0, 0, 0, 0.8);
207
+ }
208
+
209
+ .toggle button.toggleActive {
210
+ /* 黑滑块上用柔和浅色文字(纯白刺眼、主题深色不可见;浅灰居中)。 */
211
+ color: rgba(255, 255, 255, 0.92);
212
+ font-weight: 500;
213
+ }
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+ .listToolbar {
222
+ display: flex;
223
+ align-items: center;
224
+ gap: 6px;
225
+ }
226
+
227
+ /* 搜索框与新增按钮(Button sm,28px)等高:覆盖 Input 原子默认 32px 高。 */
228
+ .listToolbar .search {
229
+ flex: 1;
230
+ min-width: 0;
231
+ height: 28px;
232
+ box-sizing: border-box;
233
+ }
234
+
235
+ .search input {
236
+ width: 100%;
237
+ }
238
+
239
+ .listBody {
240
+ flex: 1;
241
+ min-height: 0;
242
+ overflow-y: auto;
243
+ padding: 6px 10px 12px;
244
+ box-sizing: border-box;
245
+ }
246
+
247
+ /* ── 收起态左栏窄条 rail ──────────────────────────────────────────────────── */
248
+
249
+ .listRail {
250
+ flex: none;
251
+ width: 44px;
252
+ display: flex;
253
+ flex-direction: column;
254
+ align-items: center;
255
+ gap: 4px;
256
+ padding: 8px 0;
257
+ box-sizing: border-box;
258
+ background: var(--dsw-alias-bg-elevated);
259
+ border-right: 1px solid var(--dsw-alias-border-l1);
260
+ overflow: hidden;
261
+ }
262
+
263
+ /* 窄条 rail 图标按钮(展开/新增;WorkflowList header 收起按钮同款)。 */
264
+ .railBtn {
265
+ display: inline-flex;
266
+ align-items: center;
267
+ justify-content: center;
268
+ width: 32px;
269
+ height: 32px;
270
+ padding: 0;
271
+ border: none;
272
+ border-radius: 8px;
273
+ background: transparent;
274
+ color: var(--dsw-alias-label-caption);
275
+ cursor: pointer;
276
+ }
277
+
278
+ .railBtn:hover {
279
+ background: var(--dsw-alias-bg-hover);
280
+ color: var(--dsw-alias-label-secondary);
281
+ }
282
+
283
+ /* ── 右栏编辑区 ──────────────────────────────────────────────────────────── */
284
+
285
+ .editorCol {
286
+ flex: 1;
287
+ min-width: 0;
288
+ display: flex;
289
+ flex-direction: column;
290
+ background: var(--dsw-alias-bg-base);
291
+ overflow: hidden;
292
+ }
293
+
294
+ .modeBar {
295
+ flex: none;
296
+ display: flex;
297
+ align-items: center;
298
+ gap: 8px;
299
+ min-height: 44px;
300
+ padding: 0 16px;
301
+ box-sizing: border-box;
302
+ border-bottom: 1px solid var(--dsw-alias-border-l2);
303
+ background: var(--dsw-alias-bg-elevated);
304
+ }
305
+
306
+ .editorTitle {
307
+ min-width: 0;
308
+ overflow: hidden;
309
+ text-overflow: ellipsis;
310
+ white-space: nowrap;
311
+ font-size: 13px;
312
+ font-weight: 600;
313
+ line-height: 20px;
314
+ color: var(--dsw-alias-label-primary);
315
+ }
316
+
317
+ .modeSwitch {
318
+ display: inline-flex;
319
+ border-radius: 8px;
320
+ background: var(--dsw-alias-bg-sunken);
321
+ padding: 2px;
322
+ gap: 1px;
323
+ }
324
+
325
+ .modeSwitch button {
326
+ padding: 4px 12px;
327
+ border: none;
328
+ border-radius: 6px;
329
+ background: transparent;
330
+ font-size: 11px;
331
+ font-family: inherit;
332
+ color: var(--dsw-alias-label-caption);
333
+ cursor: pointer;
334
+ }
335
+
336
+ .modeSwitch button:hover {
337
+ color: var(--dsw-alias-label-secondary);
338
+ }
339
+
340
+ .modeSwitch button.modeActive {
341
+ background: var(--dsw-alias-bg-base);
342
+ color: var(--dsw-alias-label-primary);
343
+ box-shadow: var(--dsw-shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.05));
344
+ font-weight: 500;
345
+ }
346
+
347
+ .runError {
348
+ flex: none;
349
+ margin: 0;
350
+ padding: 6px 16px;
351
+ font-size: 12px;
352
+ line-height: 18px;
353
+ color: var(--dsw-alias-state-error-primary);
354
+ background: var(--dsw-alias-state-error-bg, rgba(239, 68, 68, 0.1));
355
+ overflow-wrap: anywhere;
356
+ }
357
+
358
+ .editorBody {
359
+ flex: 1;
360
+ min-height: 0;
361
+ display: flex;
362
+ position: relative;
363
+ overflow: hidden;
364
+ }
365
+
366
+ .editorPlaceholder {
367
+ flex: 1;
368
+ display: flex;
369
+ align-items: center;
370
+ justify-content: center;
371
+ padding: 24px;
372
+ font-size: 13px;
373
+ line-height: 20px;
374
+ color: var(--dsw-alias-label-caption);
375
+ text-align: center;
376
+ }
377
+
378
+ /* 内联错误提示(编辑器加载/保存失败等)。 */
379
+ .error {
380
+ flex: none;
381
+ margin: 0;
382
+ padding: 6px 16px;
383
+ font-size: 12px;
384
+ line-height: 18px;
385
+ color: var(--dsw-alias-state-error-primary);
386
+ background: var(--dsw-alias-state-error-bg, rgba(239, 68, 68, 0.1));
387
+ overflow-wrap: anywhere;
388
+ }
389
+
390
+
@@ -0,0 +1,136 @@
1
+ /**
2
+ * WorkflowOverlay:shell.overlay 全局工作流 UI(root scope,不挂会话)。
3
+ *
4
+ * 覆盖 conversation/details 列(sidebar 保持可见可点):双栏工作台
5
+ * (左 WorkflowList + 分隔条 + 右 EditorPane)。无顶部栏——关闭经侧边栏
6
+ * 入口按钮再次点击(toggle)完成。sidebar 实测宽经 ResizeObserver 同步到
7
+ * `--wf-left`,overlay 内容永远从 sidebar 右缘开始。
8
+ * 打开/关闭/选中态全部在 `workflow-store`。
9
+ * @module @deepseek-ai/dsh-client-ui-sandore/src/client/WorkflowOverlay
10
+ */
11
+ import { useEffect, useRef, useState, useSyncExternalStore } from 'react'
12
+ import type { GlobalStandardProps, InjectFace, PropsLocale, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'
13
+
14
+ import { WorkflowList } from './WorkflowList.tsx'
15
+ import { EditorPane } from './EditorPane.tsx'
16
+ import { DragHandle } from './DragHandle.tsx'
17
+ import type { WorkflowOverlayFace } from './workflow-face.ts'
18
+ import {
19
+ getWorkflowState, newDefinition, resizeListWidth, subscribeWorkflowState, toggleListCollapse,
20
+ } from './workflow-store.ts'
21
+ import css from './WorkflowOverlay.module.css'
22
+
23
+ /** WorkflowOverlay 的组件 props:注入 face + locale + 全局标准 prop(useWorkspaces)。 */
24
+ export type WorkflowOverlayProps =
25
+ InjectFace<WorkflowOverlayFace> & PropsLocale<'sandore'> & GlobalStandardProps
26
+
27
+ /** 渲染 shell.overlay 全局工作流 UI(关闭时渲染 null)。 */
28
+ export function WorkflowOverlay({
29
+ useWorkspaces, listInstances, listDefinitions, startInstance, listModelDirectory, pickDirectory,
30
+ deleteDefinition, deleteInstance, getYaml, save, remote, openSession, modelDirectory, permissions, runCommand, queryPermission, t,
31
+ }: WorkflowOverlayProps) {
32
+ const open = useSyncExternalStore(subscribeWorkflowState, () => getWorkflowState().open)
33
+ const listWidth = useSyncExternalStore(subscribeWorkflowState, () => getWorkflowState().listWidth)
34
+ const listCollapsed = useSyncExternalStore(subscribeWorkflowState, () => getWorkflowState().listCollapsed)
35
+ const workspaces = useWorkspaces(state => state.items)
36
+ const [refreshKey, setRefreshKey] = useState(0)
37
+ const layerRef = useRef<HTMLDivElement>(null)
38
+
39
+ // sidebar 实测宽 → --wf-left:覆盖 conversation/details 列,sidebar 保持可见。
40
+ // 注:`[data-slot="sidebar"]` 是 display:contents 的 0 宽 wrapper,需沿祖先链找
41
+ // 第一个有实际宽度的元素(`.sidebarCol` grid 列),并观察它保持同步(拖拽/折叠)。
42
+ useEffect(() => {
43
+ const layer = layerRef.current
44
+ if (layer === null) return
45
+ let observed: Element | null = null
46
+ const measure = (): void => {
47
+ let el: Element | null = document.querySelector('[data-slot="sidebar"]')
48
+ let width = 0
49
+ while (el !== null && width <= 0) {
50
+ width = el.getBoundingClientRect().width
51
+ if (width <= 0) el = el.parentElement
52
+ }
53
+ observed = el
54
+ layer.style.setProperty('--wf-left', `${width > 0 ? width : 248}px`)
55
+ }
56
+ measure()
57
+ if (observed !== null) {
58
+ const observer = new ResizeObserver(measure)
59
+ observer.observe(observed)
60
+ return () => { observer.disconnect() }
61
+ }
62
+ return undefined
63
+ }, [open])
64
+
65
+ if (!open) return null
66
+
67
+ const face: WorkflowOverlayFace = {
68
+ listInstances, listDefinitions, startInstance, listModelDirectory, pickDirectory,
69
+ deleteDefinition, deleteInstance, getYaml, save, remote, openSession, modelDirectory, permissions, runCommand, queryPermission,
70
+ }
71
+
72
+ return (
73
+ <div className={css.layer} ref={layerRef} data-sandore-overlay-layer>
74
+ <div className={css.overlay} data-sandore-overlay>
75
+ <div className={css.body}>
76
+ {listCollapsed ? (
77
+ // 收起态:窄条 rail(展开 + 新增);右栏 EditorPane flex:1 自动占满。
78
+ <ListRail t={t} onExpand={toggleListCollapse} />
79
+ ) : (
80
+ <>
81
+ <WorkflowList t={t} workspaces={workspaces} face={face} refreshKey={refreshKey} width={listWidth} />
82
+ <DragHandle side="list" className={css.dragHandle} onDrag={resizeListWidth} />
83
+ </>
84
+ )}
85
+ <EditorPane
86
+ t={t}
87
+ face={face}
88
+ onSaved={() => { setRefreshKey(key => key + 1) }}
89
+ />
90
+ </div>
91
+ </div>
92
+ </div>
93
+ )
94
+ }
95
+
96
+ /** 收起态左栏窄条 rail:展开按钮 + 新增按钮。
97
+ *
98
+ * 新增按钮直接调 `workflow-store.newDefinition`(与展开态 WorkflowList「新增定义」
99
+ * 同一动作;face 无 newDefinition 字段),overlay 开合间能力保留。 */
100
+ function ListRail({ t, onExpand }: {
101
+ t: TranslateNS<'sandore'>
102
+ /** 点击展开左栏(→ toggleListCollapse)。 */
103
+ onExpand(): void
104
+ }) {
105
+ return (
106
+ <div className={css.listRail} data-sandore-wf-rail>
107
+ <button
108
+ type="button"
109
+ className={css.railBtn}
110
+ title={t('list.expand')}
111
+ aria-label={t('list.expand')}
112
+ onClick={onExpand}
113
+ >
114
+ {/* panel-left-open:展开左栏。 */}
115
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
116
+ <rect x="3" y="3" width="18" height="18" rx="2" />
117
+ <path d="M9 3v18" />
118
+ <path d="m14 9 3 3-3 3" />
119
+ </svg>
120
+ </button>
121
+ <button
122
+ type="button"
123
+ className={css.railBtn}
124
+ title={t('panel.add.definition')}
125
+ aria-label={t('panel.add.definition')}
126
+ onClick={() => { newDefinition() }}
127
+ >
128
+ {/* plus:新增定义(切编排态 + 空白 DagEditor)。 */}
129
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
130
+ <path d="M5 12h14" />
131
+ <path d="M12 5v14" />
132
+ </svg>
133
+ </button>
134
+ </div>
135
+ )
136
+ }