@sakki_chin/dsh-codex-orchestrate 1.0.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.
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/client/api.js +50 -0
- package/client/components/Composer.jsx +179 -0
- package/client/components/ConversationThread.jsx +396 -0
- package/client/components/Icons.jsx +47 -0
- package/client/components/OrchestrateWorkbench.jsx +68 -0
- package/client/components/Toast.jsx +26 -0
- package/client/components/WorkflowRail.jsx +414 -0
- package/client/hooks/useOrchestrateData.jsx +122 -0
- package/client/index.jsx +103 -0
- package/client/styles.js +296 -0
- package/cordis.patch.yml +11 -0
- package/esbuild.client.mjs +43 -0
- package/lib/client.js +8974 -0
- package/package.json +63 -0
- package/schema/workflow.example.yaml +32 -0
- package/schema/workflow.schema.json +75 -0
- package/schema/workflow.schema.md +112 -0
- package/scripts/verify-edge-routing.mjs +214 -0
- package/server/codex-runner.js +129 -0
- package/server/defaults.js +83 -0
- package/server/orchestrator.js +570 -0
- package/server/orchestrator.test.cjs +423 -0
- package/server/persistence.js +124 -0
- package/server/persistence.test.cjs +175 -0
- package/server/plugin.mjs +312 -0
- package/server/plugin.test.cjs +181 -0
- package/server/turn-reduce.js +77 -0
- package/server/turn-reduce.test.cjs +96 -0
- package/server/validate.js +263 -0
package/client/styles.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
export const tokens = {
|
|
2
|
+
'--co-bg': 'var(--dsw-alias-bg-base, transparent)',
|
|
3
|
+
'--co-raised': 'var(--dsw-alias-fill-quaternary, var(--dsw-alias-interactive-bg-hover, rgba(127, 127, 127, .08)))',
|
|
4
|
+
'--co-sunken': 'var(--dsw-alias-fill-tertiary, var(--dsw-alias-fill-secondary, rgba(127, 127, 127, .12)))',
|
|
5
|
+
'--co-user': 'var(--dsw-alias-fill-secondary, rgba(127, 127, 127, .12))',
|
|
6
|
+
'--co-code': 'var(--dsw-alias-fill-quaternary, rgba(127, 127, 127, .08))',
|
|
7
|
+
'--co-border': 'var(--dsw-alias-stroke-secondary, color-mix(in srgb, currentColor 14%, transparent))',
|
|
8
|
+
'--co-border-strong': 'var(--dsw-alias-stroke-primary, color-mix(in srgb, currentColor 24%, transparent))',
|
|
9
|
+
'--co-ink': 'var(--dsw-alias-label-primary, currentColor)',
|
|
10
|
+
'--co-ink-secondary': 'var(--dsw-alias-label-secondary, color-mix(in srgb, currentColor 76%, transparent))',
|
|
11
|
+
'--co-ink-muted': 'var(--dsw-alias-label-tertiary, color-mix(in srgb, currentColor 58%, transparent))',
|
|
12
|
+
'--co-ink-faint': 'var(--dsw-alias-label-quaternary, color-mix(in srgb, currentColor 42%, transparent))',
|
|
13
|
+
'--co-accent': 'var(--dsw-alias-brand-primary, var(--dsw-alias-label-primary, currentColor))',
|
|
14
|
+
'--co-accent-ink': 'var(--dsw-alias-label-on-color, Canvas)',
|
|
15
|
+
'--co-ok': 'var(--dsw-alias-status-success, #4f9a5c)',
|
|
16
|
+
'--co-error': 'var(--dsw-alias-status-danger, #d06056)',
|
|
17
|
+
'--co-running': 'var(--dsw-alias-status-info, #5689c2)',
|
|
18
|
+
'--co-focus': 'var(--dsw-alias-focus-ring, #5689c2)',
|
|
19
|
+
'--co-font-mono': 'var(--dsw-font-family-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace)',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const styles = {
|
|
23
|
+
workbench: {
|
|
24
|
+
...tokens,
|
|
25
|
+
boxSizing: 'border-box',
|
|
26
|
+
display: 'grid',
|
|
27
|
+
gridTemplateRows: 'auto minmax(0, 1fr) auto',
|
|
28
|
+
width: '100%',
|
|
29
|
+
height: '100%',
|
|
30
|
+
minWidth: 0,
|
|
31
|
+
minHeight: 0,
|
|
32
|
+
overflow: 'hidden',
|
|
33
|
+
background: 'var(--co-bg)',
|
|
34
|
+
color: 'var(--co-ink)',
|
|
35
|
+
fontFamily: 'inherit',
|
|
36
|
+
fontSize: 14,
|
|
37
|
+
lineHeight: 1.55,
|
|
38
|
+
},
|
|
39
|
+
buttonReset: {
|
|
40
|
+
boxSizing: 'border-box',
|
|
41
|
+
border: 0,
|
|
42
|
+
padding: 0,
|
|
43
|
+
background: 'transparent',
|
|
44
|
+
color: 'inherit',
|
|
45
|
+
font: 'inherit',
|
|
46
|
+
cursor: 'pointer',
|
|
47
|
+
},
|
|
48
|
+
rail: {
|
|
49
|
+
minWidth: 0,
|
|
50
|
+
padding: '12px 14px 13px',
|
|
51
|
+
borderBottom: '1px solid var(--co-border)',
|
|
52
|
+
background: 'var(--co-bg)',
|
|
53
|
+
},
|
|
54
|
+
railMeta: {
|
|
55
|
+
display: 'flex',
|
|
56
|
+
alignItems: 'baseline',
|
|
57
|
+
justifyContent: 'space-between',
|
|
58
|
+
flexWrap: 'wrap',
|
|
59
|
+
gap: '8px 12px',
|
|
60
|
+
minWidth: 0,
|
|
61
|
+
marginBottom: 10,
|
|
62
|
+
},
|
|
63
|
+
railTitleGroup: { minWidth: 0, flex: '1 1 180px' },
|
|
64
|
+
railTitle: {
|
|
65
|
+
margin: 0,
|
|
66
|
+
overflow: 'hidden',
|
|
67
|
+
fontSize: 14,
|
|
68
|
+
fontWeight: 650,
|
|
69
|
+
letterSpacing: '-.01em',
|
|
70
|
+
textOverflow: 'ellipsis',
|
|
71
|
+
whiteSpace: 'nowrap',
|
|
72
|
+
},
|
|
73
|
+
railSub: {
|
|
74
|
+
display: 'block',
|
|
75
|
+
overflow: 'hidden',
|
|
76
|
+
marginTop: 1,
|
|
77
|
+
color: 'var(--co-ink-muted)',
|
|
78
|
+
fontSize: 11,
|
|
79
|
+
textOverflow: 'ellipsis',
|
|
80
|
+
whiteSpace: 'nowrap',
|
|
81
|
+
},
|
|
82
|
+
railControls: { display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 },
|
|
83
|
+
picker: {
|
|
84
|
+
boxSizing: 'border-box',
|
|
85
|
+
minWidth: 0,
|
|
86
|
+
maxWidth: 190,
|
|
87
|
+
padding: '4px 7px',
|
|
88
|
+
border: '1px solid var(--co-border)',
|
|
89
|
+
borderRadius: 8,
|
|
90
|
+
background: 'var(--co-raised)',
|
|
91
|
+
color: 'var(--co-ink-secondary)',
|
|
92
|
+
font: '11px/1.5 inherit',
|
|
93
|
+
textOverflow: 'ellipsis',
|
|
94
|
+
},
|
|
95
|
+
stats: {
|
|
96
|
+
display: 'flex',
|
|
97
|
+
gap: 8,
|
|
98
|
+
flexShrink: 0,
|
|
99
|
+
color: 'var(--co-ink-muted)',
|
|
100
|
+
fontSize: 11,
|
|
101
|
+
whiteSpace: 'nowrap',
|
|
102
|
+
},
|
|
103
|
+
railLanes: {
|
|
104
|
+
width: '100%',
|
|
105
|
+
minWidth: 0,
|
|
106
|
+
maxHeight: 'min(36vh, 360px)',
|
|
107
|
+
overflow: 'auto',
|
|
108
|
+
padding: '3px 2px 7px',
|
|
109
|
+
overscrollBehavior: 'contain',
|
|
110
|
+
scrollbarWidth: 'thin',
|
|
111
|
+
},
|
|
112
|
+
/* isolation 把 z-index 关在本图内,连线不会跑到 rail 之外的元素上面 */
|
|
113
|
+
graph: { position: 'relative', minWidth: '100%', isolation: 'isolate' },
|
|
114
|
+
/* 连线显式压到最底层(zIndex 0),节点卡片 zIndex 1。
|
|
115
|
+
不再依赖 DOM 顺序——两条链路顺序一旦调整,线就会盖住卡片。 */
|
|
116
|
+
edges: { position: 'absolute', inset: 0, zIndex: 0, overflow: 'visible', pointerEvents: 'none' },
|
|
117
|
+
nodeCard: {
|
|
118
|
+
boxSizing: 'border-box',
|
|
119
|
+
position: 'absolute',
|
|
120
|
+
zIndex: 1,
|
|
121
|
+
display: 'flex',
|
|
122
|
+
flexDirection: 'column',
|
|
123
|
+
justifyContent: 'center',
|
|
124
|
+
gap: 4,
|
|
125
|
+
width: 190,
|
|
126
|
+
height: 76,
|
|
127
|
+
padding: '9px 11px',
|
|
128
|
+
border: '1px solid var(--co-border)',
|
|
129
|
+
borderRadius: 12,
|
|
130
|
+
background: 'var(--co-raised)',
|
|
131
|
+
color: 'var(--co-ink)',
|
|
132
|
+
textAlign: 'left',
|
|
133
|
+
cursor: 'pointer',
|
|
134
|
+
},
|
|
135
|
+
nodeTitle: { overflow: 'hidden', fontSize: 12, fontWeight: 600, textOverflow: 'ellipsis', whiteSpace: 'nowrap' },
|
|
136
|
+
nodePrompt: {
|
|
137
|
+
display: '-webkit-box',
|
|
138
|
+
overflow: 'hidden',
|
|
139
|
+
color: 'var(--co-ink-muted)',
|
|
140
|
+
fontSize: 11,
|
|
141
|
+
lineHeight: 1.45,
|
|
142
|
+
WebkitBoxOrient: 'vertical',
|
|
143
|
+
WebkitLineClamp: 2,
|
|
144
|
+
},
|
|
145
|
+
empty: { padding: '28px 8px', color: 'var(--co-ink-faint)', fontSize: 12, textAlign: 'center' },
|
|
146
|
+
alert: {
|
|
147
|
+
margin: '0 14px',
|
|
148
|
+
padding: '7px 9px',
|
|
149
|
+
borderLeft: '2px solid var(--co-error)',
|
|
150
|
+
color: 'var(--co-error)',
|
|
151
|
+
fontSize: 12,
|
|
152
|
+
},
|
|
153
|
+
conversation: { minWidth: 0, minHeight: 0, overflowX: 'hidden', overflowY: 'auto', scrollbarWidth: 'thin' },
|
|
154
|
+
thread: {
|
|
155
|
+
boxSizing: 'border-box',
|
|
156
|
+
display: 'flex',
|
|
157
|
+
flexDirection: 'column',
|
|
158
|
+
gap: 24,
|
|
159
|
+
width: '100%',
|
|
160
|
+
maxWidth: 760,
|
|
161
|
+
minHeight: '100%',
|
|
162
|
+
margin: '0 auto',
|
|
163
|
+
padding: '22px 16px 18px',
|
|
164
|
+
},
|
|
165
|
+
turn: { display: 'flex', flexDirection: 'column', gap: 9 },
|
|
166
|
+
user: {
|
|
167
|
+
alignSelf: 'flex-end',
|
|
168
|
+
maxWidth: '88%',
|
|
169
|
+
padding: '7px 12px',
|
|
170
|
+
borderRadius: 16,
|
|
171
|
+
background: 'var(--co-user)',
|
|
172
|
+
fontSize: 13,
|
|
173
|
+
lineHeight: 1.55,
|
|
174
|
+
overflowWrap: 'anywhere',
|
|
175
|
+
whiteSpace: 'pre-wrap',
|
|
176
|
+
},
|
|
177
|
+
assistant: { alignSelf: 'stretch', display: 'flex', flexDirection: 'column', gap: 7, minWidth: 0 },
|
|
178
|
+
stream: { display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 },
|
|
179
|
+
activitySummary: {
|
|
180
|
+
display: 'flex',
|
|
181
|
+
alignItems: 'center',
|
|
182
|
+
gap: 6,
|
|
183
|
+
width: '100%',
|
|
184
|
+
minHeight: 27,
|
|
185
|
+
color: 'var(--co-ink-secondary)',
|
|
186
|
+
fontSize: 12,
|
|
187
|
+
textAlign: 'left',
|
|
188
|
+
},
|
|
189
|
+
activityBody: { margin: '2px 0 5px 6px', padding: '2px 0 2px 11px', borderLeft: '1px solid var(--co-border)' },
|
|
190
|
+
activityRow: { display: 'flex', alignItems: 'center', gap: 6, minHeight: 27, color: 'var(--co-ink-muted)', fontSize: 12 },
|
|
191
|
+
activityMeta: {
|
|
192
|
+
minWidth: 0,
|
|
193
|
+
flex: 1,
|
|
194
|
+
overflow: 'hidden',
|
|
195
|
+
color: 'var(--co-ink-muted)',
|
|
196
|
+
fontFamily: 'var(--co-font-mono)',
|
|
197
|
+
fontSize: 10.5,
|
|
198
|
+
textOverflow: 'ellipsis',
|
|
199
|
+
whiteSpace: 'nowrap',
|
|
200
|
+
},
|
|
201
|
+
prose: { maxHeight: 240, overflowY: 'auto', color: 'var(--co-ink-muted)', fontSize: 12, lineHeight: 1.62, overflowWrap: 'anywhere', whiteSpace: 'pre-wrap' },
|
|
202
|
+
code: {
|
|
203
|
+
boxSizing: 'border-box',
|
|
204
|
+
maxHeight: 280,
|
|
205
|
+
overflow: 'auto',
|
|
206
|
+
margin: 0,
|
|
207
|
+
padding: '9px 10px',
|
|
208
|
+
border: '1px solid var(--co-border)',
|
|
209
|
+
borderRadius: 8,
|
|
210
|
+
background: 'var(--co-code)',
|
|
211
|
+
color: 'var(--co-ink-secondary)',
|
|
212
|
+
fontFamily: 'var(--co-font-mono)',
|
|
213
|
+
fontSize: 11,
|
|
214
|
+
lineHeight: 1.55,
|
|
215
|
+
overflowWrap: 'anywhere',
|
|
216
|
+
whiteSpace: 'pre-wrap',
|
|
217
|
+
},
|
|
218
|
+
agentMessage: { padding: '3px 5px 7px', fontSize: 13, lineHeight: 1.75, overflowWrap: 'anywhere' },
|
|
219
|
+
agentError: { margin: '2px 5px', padding: '3px 8px', borderLeft: '2px solid var(--co-error)', color: 'var(--co-error)', fontSize: 12 },
|
|
220
|
+
turnState: { padding: '0 1px', color: 'var(--co-ink-faint)', fontSize: 12 },
|
|
221
|
+
actions: { display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: '5px 12px', minHeight: 28, color: 'var(--co-ink-muted)', fontSize: 11 },
|
|
222
|
+
action: { display: 'inline-flex', alignItems: 'center', gap: 4, minHeight: 26, color: 'var(--co-ink-secondary)', whiteSpace: 'nowrap' },
|
|
223
|
+
composerWrap: { overflow: 'hidden', padding: '10px 12px 12px', background: 'var(--co-bg)' },
|
|
224
|
+
changeSummary: {
|
|
225
|
+
width: 'max-content',
|
|
226
|
+
maxWidth: '90%',
|
|
227
|
+
margin: '0 auto 8px',
|
|
228
|
+
padding: '4px 10px',
|
|
229
|
+
border: '1px solid var(--co-border-strong)',
|
|
230
|
+
borderRadius: 999,
|
|
231
|
+
background: 'var(--co-raised)',
|
|
232
|
+
color: 'var(--co-ink-secondary)',
|
|
233
|
+
fontSize: 11,
|
|
234
|
+
},
|
|
235
|
+
composer: {
|
|
236
|
+
boxSizing: 'border-box',
|
|
237
|
+
display: 'flex',
|
|
238
|
+
flexDirection: 'column',
|
|
239
|
+
justifyContent: 'space-between',
|
|
240
|
+
gap: 8,
|
|
241
|
+
width: '100%',
|
|
242
|
+
maxWidth: 760,
|
|
243
|
+
minHeight: 86,
|
|
244
|
+
margin: '0 auto',
|
|
245
|
+
padding: 9,
|
|
246
|
+
border: '1px solid var(--co-border)',
|
|
247
|
+
borderRadius: 15,
|
|
248
|
+
background: 'var(--co-raised)',
|
|
249
|
+
},
|
|
250
|
+
textarea: {
|
|
251
|
+
boxSizing: 'border-box',
|
|
252
|
+
width: '100%',
|
|
253
|
+
minHeight: 27,
|
|
254
|
+
maxHeight: 180,
|
|
255
|
+
resize: 'none',
|
|
256
|
+
padding: '0 2px',
|
|
257
|
+
border: 0,
|
|
258
|
+
outline: 0,
|
|
259
|
+
background: 'transparent',
|
|
260
|
+
color: 'var(--co-ink)',
|
|
261
|
+
font: '13px/1.5 inherit',
|
|
262
|
+
},
|
|
263
|
+
composerBar: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, minWidth: 0 },
|
|
264
|
+
tools: { display: 'flex', alignItems: 'center', gap: 4, minWidth: 0 },
|
|
265
|
+
toolButton: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 5, height: 28, padding: '0 6px', borderRadius: 8, color: 'var(--co-ink-muted)', fontSize: 11 },
|
|
266
|
+
send: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, width: 28, height: 28, borderRadius: '50%', background: 'var(--co-accent)', color: 'var(--co-accent-ink)' },
|
|
267
|
+
runtime: {
|
|
268
|
+
display: 'flex',
|
|
269
|
+
alignItems: 'center',
|
|
270
|
+
gap: 10,
|
|
271
|
+
width: '100%',
|
|
272
|
+
maxWidth: 760,
|
|
273
|
+
minWidth: 0,
|
|
274
|
+
margin: '6px auto 0',
|
|
275
|
+
overflow: 'hidden',
|
|
276
|
+
color: 'var(--co-ink-faint)',
|
|
277
|
+
fontFamily: 'var(--co-font-mono)',
|
|
278
|
+
fontSize: 9,
|
|
279
|
+
whiteSpace: 'nowrap',
|
|
280
|
+
},
|
|
281
|
+
toast: {
|
|
282
|
+
position: 'absolute',
|
|
283
|
+
zIndex: 10,
|
|
284
|
+
bottom: 94,
|
|
285
|
+
left: '50%',
|
|
286
|
+
maxWidth: '86%',
|
|
287
|
+
transform: 'translateX(-50%)',
|
|
288
|
+
padding: '7px 13px',
|
|
289
|
+
borderRadius: 8,
|
|
290
|
+
background: 'var(--co-accent)',
|
|
291
|
+
color: 'var(--co-accent-ink)',
|
|
292
|
+
boxShadow: '0 14px 42px rgba(0, 0, 0, .18)',
|
|
293
|
+
fontSize: 12,
|
|
294
|
+
},
|
|
295
|
+
menuButton: { display: 'block', width: '100%', padding: '7px 10px', border: 0, background: 'transparent', color: 'inherit', textAlign: 'left', cursor: 'pointer' },
|
|
296
|
+
}
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# dsh bundle patch:把本插件插入 profile 的 layer stack。
|
|
2
|
+
#
|
|
3
|
+
# 关键点:`name` 用**包名**,不是绝对路径。
|
|
4
|
+
# 宿主 `dsh plugin add` 在 pnpm 装完之后会 reconcile `dsh.profile.bundles`:
|
|
5
|
+
# 一个声明了 `dsh.bundle` 的依赖会自动入栈(按依赖顺序追加),
|
|
6
|
+
# 因此换机器不需要任何人手改 ~/.dsh 下的配置。
|
|
7
|
+
#
|
|
8
|
+
# 对照范本:dshmarket / dsh-better-sidebar 都是一样的形态。
|
|
9
|
+
- insert:
|
|
10
|
+
- id: codex-orchestrate
|
|
11
|
+
name: '@sakki_chin/dsh-codex-orchestrate'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { build } from 'esbuild'
|
|
2
|
+
|
|
3
|
+
/* 必须与 package.json 的 name 完全一致。
|
|
4
|
+
* 宿主 client-modules 用「包名」作为启动图 row 的 id(/plugins/??<id>/client.js),
|
|
5
|
+
* 浏览器侧 __ModuleLoader__.load({ id }) 也要用同一个 id 才能被认领;
|
|
6
|
+
* 两者不一致的表现是「插件静默不加载」,没有报错。 */
|
|
7
|
+
const packageName = '@sakki_chin/dsh-codex-orchestrate'
|
|
8
|
+
|
|
9
|
+
// DSH Desktop 在浏览器外壳中冻结提供的精确模块键。即使本入口目前只
|
|
10
|
+
// import React,也保留完整表,避免后续误把第二份宿主运行时打进 bundle。
|
|
11
|
+
const platformModules = [
|
|
12
|
+
'react',
|
|
13
|
+
'react/jsx-runtime',
|
|
14
|
+
'react-dom',
|
|
15
|
+
'react-dom/client',
|
|
16
|
+
'@deepseek-ai/cordis',
|
|
17
|
+
'@deepseek-ai/dsh-client-store',
|
|
18
|
+
'@deepseek-ai/dsh-client-ui-slots',
|
|
19
|
+
'@deepseek-ai/dsh-client-ui-primitives',
|
|
20
|
+
'@deepseek-ai/dsh-client-ui-dockkit',
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
await build({
|
|
24
|
+
entryPoints: ['client/index.jsx'],
|
|
25
|
+
outfile: 'lib/client.js',
|
|
26
|
+
bundle: true,
|
|
27
|
+
format: 'cjs',
|
|
28
|
+
platform: 'browser',
|
|
29
|
+
target: ['es2022'],
|
|
30
|
+
/* 不产出 sourcemap:宿主对 .map 是可选读(ENOENT 即跳过,不报错),
|
|
31
|
+
而 .map 比 bundle 本身还大(约 666KB),去掉可让包体减半。 */
|
|
32
|
+
sourcemap: false,
|
|
33
|
+
external: platformModules,
|
|
34
|
+
// XMarkdown 自带的全局样式不进入宿主;工作台使用作用域内联样式和
|
|
35
|
+
// --dsw-alias-* 主题变量,避免额外的 client.css 或 <style> 注入。
|
|
36
|
+
loader: { '.css': 'empty' },
|
|
37
|
+
banner: {
|
|
38
|
+
js: `window.__ModuleLoader__.load({ id: ${JSON.stringify(packageName)}, factory: (require) => { var module = { exports: {} }; var exports = module.exports;`,
|
|
39
|
+
},
|
|
40
|
+
footer: {
|
|
41
|
+
js: 'return module.exports; } });',
|
|
42
|
+
},
|
|
43
|
+
})
|