@xiaoso/dsh-workflow-lite 0.0.0-stage → 0.1.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 (156) hide show
  1. package/LICENSE +24 -0
  2. package/README.en.md +84 -0
  3. package/README.md +83 -2
  4. package/THIRD_PARTY_NOTICES.md +762 -0
  5. package/assets/icon-full.webp +0 -0
  6. package/assets/icon.webp +0 -0
  7. package/assets/wordmark.png +0 -0
  8. package/cordis.patch.yml +3 -0
  9. package/lib/client.js +127442 -0
  10. package/lib/index.mjs +9613 -0
  11. package/lib/types/client/app/addStep.d.ts +25 -0
  12. package/lib/types/client/app/desktop.d.ts +52 -0
  13. package/lib/types/client/app/host.d.ts +29 -0
  14. package/lib/types/client/app/sessions.d.ts +117 -0
  15. package/lib/types/client/app/theme.d.ts +27 -0
  16. package/lib/types/client/app/usePluginConfig.d.ts +59 -0
  17. package/lib/types/client/app/useRunFile.d.ts +24 -0
  18. package/lib/types/client/app/useRunGraph.d.ts +51 -0
  19. package/lib/types/client/app/useRunHistory.d.ts +21 -0
  20. package/lib/types/client/app/useRuns.d.ts +84 -0
  21. package/lib/types/client/app/useVersions.d.ts +50 -0
  22. package/lib/types/client/app/useWorkflow.d.ts +67 -0
  23. package/lib/types/client/app/viewport.d.ts +14 -0
  24. package/lib/types/client/i18n.d.ts +930 -0
  25. package/lib/types/client/index.d.ts +18 -0
  26. package/lib/types/client/model/connect.d.ts +44 -0
  27. package/lib/types/client/model/editor.d.ts +252 -0
  28. package/lib/types/client/model/fileKind.d.ts +15 -0
  29. package/lib/types/client/model/hostPath.d.ts +15 -0
  30. package/lib/types/client/model/htmlPreview.d.ts +24 -0
  31. package/lib/types/client/model/hubRuns.d.ts +45 -0
  32. package/lib/types/client/model/layout.d.ts +83 -0
  33. package/lib/types/client/model/library.d.ts +109 -0
  34. package/lib/types/client/model/nudge.d.ts +43 -0
  35. package/lib/types/client/model/pathSample.d.ts +26 -0
  36. package/lib/types/client/model/route.d.ts +121 -0
  37. package/lib/types/client/model/runDraft.d.ts +68 -0
  38. package/lib/types/client/model/runGraph.d.ts +15 -0
  39. package/lib/types/client/model/runHistory.d.ts +40 -0
  40. package/lib/types/client/model/themes.d.ts +87 -0
  41. package/lib/types/client/model/time.d.ts +7 -0
  42. package/lib/types/client/rpc.d.ts +42 -0
  43. package/lib/types/client/ui/AppearancePicker.d.ts +23 -0
  44. package/lib/types/client/ui/Canvas.d.ts +76 -0
  45. package/lib/types/client/ui/Confirm.d.ts +42 -0
  46. package/lib/types/client/ui/DocViewer.d.ts +67 -0
  47. package/lib/types/client/ui/Dock.d.ts +13 -0
  48. package/lib/types/client/ui/FileTag.d.ts +9 -0
  49. package/lib/types/client/ui/FileViewer.d.ts +30 -0
  50. package/lib/types/client/ui/FlowStreaks.d.ts +40 -0
  51. package/lib/types/client/ui/Handoff.d.ts +30 -0
  52. package/lib/types/client/ui/HostPicker.d.ts +31 -0
  53. package/lib/types/client/ui/HubDialog.d.ts +38 -0
  54. package/lib/types/client/ui/HubRunRow.d.ts +22 -0
  55. package/lib/types/client/ui/HubRuns.d.ts +19 -0
  56. package/lib/types/client/ui/HubSettings.d.ts +20 -0
  57. package/lib/types/client/ui/HubStorage.d.ts +18 -0
  58. package/lib/types/client/ui/HubWorkflowList.d.ts +21 -0
  59. package/lib/types/client/ui/HubWorkflowRow.d.ts +33 -0
  60. package/lib/types/client/ui/HubWorkflows.d.ts +26 -0
  61. package/lib/types/client/ui/HubWorkspacePicker.d.ts +16 -0
  62. package/lib/types/client/ui/Icon.d.ts +83 -0
  63. package/lib/types/client/ui/InputPanel.d.ts +37 -0
  64. package/lib/types/client/ui/InputsDialog.d.ts +22 -0
  65. package/lib/types/client/ui/Inspector.d.ts +51 -0
  66. package/lib/types/client/ui/Issues.d.ts +15 -0
  67. package/lib/types/client/ui/Launch.d.ts +30 -0
  68. package/lib/types/client/ui/Library.d.ts +23 -0
  69. package/lib/types/client/ui/LinkRow.d.ts +31 -0
  70. package/lib/types/client/ui/Markdown.d.ts +21 -0
  71. package/lib/types/client/ui/NodeHeads.d.ts +47 -0
  72. package/lib/types/client/ui/NoteDrawer.d.ts +21 -0
  73. package/lib/types/client/ui/OpenWith.d.ts +21 -0
  74. package/lib/types/client/ui/Outputs.d.ts +61 -0
  75. package/lib/types/client/ui/PanelHead.d.ts +21 -0
  76. package/lib/types/client/ui/PlanDialog.d.ts +18 -0
  77. package/lib/types/client/ui/PreviewCard.d.ts +38 -0
  78. package/lib/types/client/ui/QuickAdd.d.ts +30 -0
  79. package/lib/types/client/ui/ResourceItemDialog.d.ts +33 -0
  80. package/lib/types/client/ui/ResourceItems.d.ts +30 -0
  81. package/lib/types/client/ui/ResourcePanel.d.ts +26 -0
  82. package/lib/types/client/ui/Resources.d.ts +43 -0
  83. package/lib/types/client/ui/RunDraftBar.d.ts +35 -0
  84. package/lib/types/client/ui/RunEdge.d.ts +29 -0
  85. package/lib/types/client/ui/RunFiles.d.ts +24 -0
  86. package/lib/types/client/ui/RunInput.d.ts +26 -0
  87. package/lib/types/client/ui/RunItemDialog.d.ts +43 -0
  88. package/lib/types/client/ui/RunModeSwitch.d.ts +14 -0
  89. package/lib/types/client/ui/RunNav.d.ts +22 -0
  90. package/lib/types/client/ui/RunNodeState.d.ts +42 -0
  91. package/lib/types/client/ui/RunOverview.d.ts +27 -0
  92. package/lib/types/client/ui/RunPosition.d.ts +24 -0
  93. package/lib/types/client/ui/RunResource.d.ts +40 -0
  94. package/lib/types/client/ui/RunStatusMenu.d.ts +28 -0
  95. package/lib/types/client/ui/RunStep.d.ts +45 -0
  96. package/lib/types/client/ui/RunTopBar.d.ts +42 -0
  97. package/lib/types/client/ui/RunView.d.ts +43 -0
  98. package/lib/types/client/ui/SettingsDialog.d.ts +25 -0
  99. package/lib/types/client/ui/SettingsFields.d.ts +37 -0
  100. package/lib/types/client/ui/SkillPicker.d.ts +25 -0
  101. package/lib/types/client/ui/SkillPreview.d.ts +27 -0
  102. package/lib/types/client/ui/StepMark.d.ts +16 -0
  103. package/lib/types/client/ui/StepPanel.d.ts +26 -0
  104. package/lib/types/client/ui/ThemePicker.d.ts +13 -0
  105. package/lib/types/client/ui/TipLayer.d.ts +17 -0
  106. package/lib/types/client/ui/TopBar.d.ts +32 -0
  107. package/lib/types/client/ui/VersionList.d.ts +19 -0
  108. package/lib/types/client/ui/VersionRow.d.ts +19 -0
  109. package/lib/types/client/ui/VersionsDialog.d.ts +18 -0
  110. package/lib/types/client/ui/WorkflowRow.d.ts +32 -0
  111. package/lib/types/client/ui/WorkflowSwitcher.d.ts +20 -0
  112. package/lib/types/client/ui/WorkflowView.d.ts +27 -0
  113. package/lib/types/client/ui/lines.d.ts +13 -0
  114. package/lib/types/client/ui/primitives.d.ts +119 -0
  115. package/lib/types/client/ui/resourceUi.d.ts +49 -0
  116. package/lib/types/client/ui/stepIcons.d.ts +10 -0
  117. package/lib/types/host/authoringSkill.d.ts +17 -0
  118. package/lib/types/host/config.d.ts +54 -0
  119. package/lib/types/host/hostFs.d.ts +69 -0
  120. package/lib/types/host/plan.d.ts +68 -0
  121. package/lib/types/host/pluginConfig.d.ts +57 -0
  122. package/lib/types/host/rpc.d.ts +45 -0
  123. package/lib/types/host/runs/files.d.ts +37 -0
  124. package/lib/types/host/runs/notice.d.ts +21 -0
  125. package/lib/types/host/runs/service.d.ts +258 -0
  126. package/lib/types/host/runs/skill.d.ts +16 -0
  127. package/lib/types/host/runs/storage.d.ts +16 -0
  128. package/lib/types/host/runs/store.d.ts +56 -0
  129. package/lib/types/host/skillView.d.ts +22 -0
  130. package/lib/types/host/store/atomic.d.ts +34 -0
  131. package/lib/types/host/store/materialize.d.ts +19 -0
  132. package/lib/types/host/store/merge.d.ts +25 -0
  133. package/lib/types/host/store/paths.d.ts +86 -0
  134. package/lib/types/host/store/repository.d.ts +217 -0
  135. package/lib/types/host/store/versions.d.ts +38 -0
  136. package/lib/types/host/tool/tool.d.ts +432 -0
  137. package/lib/types/index.d.ts +35 -0
  138. package/lib/types/shared/appearance.d.ts +49 -0
  139. package/lib/types/shared/compile.d.ts +71 -0
  140. package/lib/types/shared/graph.d.ts +54 -0
  141. package/lib/types/shared/graphDiff.d.ts +29 -0
  142. package/lib/types/shared/inputs.d.ts +46 -0
  143. package/lib/types/shared/limits.d.ts +77 -0
  144. package/lib/types/shared/model.d.ts +122 -0
  145. package/lib/types/shared/naming.d.ts +59 -0
  146. package/lib/types/shared/outputPaths.d.ts +49 -0
  147. package/lib/types/shared/resources.d.ts +98 -0
  148. package/lib/types/shared/runCursor.d.ts +54 -0
  149. package/lib/types/shared/runState.d.ts +221 -0
  150. package/lib/types/shared/runSync.d.ts +24 -0
  151. package/lib/types/shared/types.d.ts +488 -0
  152. package/lib/types/shared/validate.d.ts +54 -0
  153. package/lib/types/shared/wire.d.ts +600 -0
  154. package/locale/en.json +6 -0
  155. package/locale/zh.json +6 -0
  156. package/package.json +144 -4
@@ -0,0 +1,18 @@
1
+ /**
2
+ * dsh-workflow-lite — 浏览器半。
3
+ *
4
+ * 把工作流视图挂到会话页的 tab 上(`conversation.view` 槽位),并接上共享 Connection 的
5
+ * `/api` 通道。UI 文案走本插件的 locale 词典(`workflow-lite`)。
6
+ *
7
+ * tab 的显示名用 **thunk**:槽位每次读取时重新求值,所以切语言不用重新注册。
8
+ *
9
+ * @module @xiaoso/dsh-workflow-lite/client
10
+ */
11
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
12
+ /** 视图需要的三个客户端服务。 */
13
+ export declare const inject: string[];
14
+ /**
15
+ * 挂载视图。
16
+ * @param ctx - 浏览器插件上下文。
17
+ */
18
+ export declare function apply(ctx: ClientContext): void;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * dsh-workflow-lite — 拖线连接的规则:从哪个连接点拖出来、能落到哪些连接点上、连上会是什么线。
3
+ *
4
+ * 连接点各有分工(「左右走流程,上下走资源」):
5
+ * - 步骤左 `in`:入口——接上游步骤(流程)或资源卡(读取);
6
+ * - 步骤右 `out`:出口——只连下一个步骤(流程);
7
+ * - 步骤底 `file`:出口——只连资源卡(写入);
8
+ * - 资源左 `in`:入口——只接步骤的写点(写入);
9
+ * - 资源右 `out`:出口——只连步骤(读取);
10
+ * - 输入右 `out`:出口——只连步骤(把回答交给它,落点和读资源一样)。输入没有入口。
11
+ * 步骤上还有几个备用点(上边的写点 `fileUp`、上下边的读点 `read` / `readTop`),挂哪个由画布按位置挑。
12
+ *
13
+ * 画布据此在拖线时只露出能连的连接点,并在松手前预告这条线的含义。
14
+ *
15
+ * @module @xiaoso/dsh-workflow-lite/client/model/connect
16
+ */
17
+ import type { WorkflowDocument, WorkflowNode } from '../../shared/types.ts';
18
+ /**
19
+ * 正在拖的是哪种线(按起点):
20
+ * `flow` 步骤右 → 找步骤;`write` 步骤底/上的写点 → 找资源;`read` 资源右 → 找步骤;
21
+ * `back` 从步骤左边倒着拖 → 找步骤右 / 资源右;`writeBack` 从资源左边倒着拖 → 找步骤的写点;
22
+ * `readBack` 从步骤的读点倒着拖 → 找资源或输入;`ask` 输入右 → 找步骤。
23
+ */
24
+ export type DragKind = 'flow' | 'write' | 'read' | 'ask' | 'back' | 'writeBack' | 'readBack';
25
+ /** 拖线起点是哪种卡。 */
26
+ export type CardKind = 'step' | 'resource' | 'input';
27
+ export declare function dragKindOf(from: CardKind, handleId: string | null | undefined): DragKind | null;
28
+ /** React Flow 交过来的连接(已按 source → target 摆正)。 */
29
+ export interface HandleLink {
30
+ source: string;
31
+ sourceHandle?: string | null;
32
+ target: string;
33
+ targetHandle?: string | null;
34
+ }
35
+ /** 这条拖出来的线能不能连:不连自己、资源不连资源,且两头的连接点分工要对得上。 */
36
+ export declare function linkAllowed(doc: WorkflowDocument, link: HandleLink): boolean;
37
+ /** 连上之后会是什么线:流程 / 产出 / 更新 / 读取 / 交回答;`exists` = 已经连着了,松手什么也不会变。 */
38
+ export interface LinkPreview {
39
+ kind: 'flow' | 'produce' | 'update' | 'read' | 'ask';
40
+ source: WorkflowNode;
41
+ target: WorkflowNode;
42
+ exists: boolean;
43
+ }
44
+ export declare function previewLink(doc: WorkflowDocument, link: HandleLink): LinkPreview | null;
@@ -0,0 +1,252 @@
1
+ /**
2
+ * dsh-workflow-lite — 编辑器状态机(**纯逻辑**,组件只管接线)。
3
+ *
4
+ * 事实源是磁盘上的那份 JSON。三个计数讲清"有没有没落盘的改动":
5
+ * - `rev` 每次改文档 +1(撤销/重做也算——它们同样需要落盘);
6
+ * - `savedRev` 磁盘上已知持有的那一版;
7
+ * - `savingRev` 在途那笔保存对应的版本。
8
+ * `rev !== savedRev` 即为脏。保存期间又来的改动不会被误判成已落盘,因为保存成功只把
9
+ * `savedRev` 推到 `savingRev`,而不是推到最新。
10
+ *
11
+ * 节点身份一律按 `idKey`(大小写不敏感)比较;`label` 只用于显示。
12
+ *
13
+ * @module @xiaoso/dsh-workflow-lite/client/model/editor
14
+ */
15
+ import { type Handoff, type InputData, type NodeData, type Point, type ResourceData, type ValidationProblem, type WorkflowDocument, type WorkflowEdge, type WorkflowNode, type WorkflowSettings } from '../../shared/types.ts';
16
+ /** 选中态:步骤、连线,或什么都不选。用一个联合表达,互斥是结构上保证的。 */
17
+ export type Selection = {
18
+ kind: 'node';
19
+ id: string;
20
+ } | {
21
+ kind: 'edge';
22
+ id: string;
23
+ } | null;
24
+ /** `idle` 没打开任何工作流;`broken` 文件读不了(只读,绝不写盘)。 */
25
+ export type Phase = 'idle' | 'loading' | 'ready' | 'broken';
26
+ export interface EditorState {
27
+ phase: Phase;
28
+ name: string | null;
29
+ doc: WorkflowDocument | null;
30
+ /** 本地文档所基于的磁盘内容哈希(保存时提交它做写前比对)。 */
31
+ baseHash: string | null;
32
+ /** host 给的全部校验问题(四级)。 */
33
+ problems: ValidationProblem[];
34
+ /** `broken` 态的说明与原文。 */
35
+ broken: {
36
+ message: string;
37
+ raw: string | null;
38
+ } | null;
39
+ selection: Selection;
40
+ rev: number;
41
+ savedRev: number;
42
+ saving: boolean;
43
+ savingRev: number;
44
+ saveError: string | null;
45
+ /** 撤销栈:每个元素是"那次改动之前"的文档。 */
46
+ past: WorkflowDocument[];
47
+ future: WorkflowDocument[];
48
+ /** 当前历史条目的合并键;相同键的连续改动并成一条撤销步。 */
49
+ mergeKey: string | null;
50
+ /**
51
+ * 每压一条新的撤销步 +1(撤销、重做、合并进上一步都不算),换基线也不归零。
52
+ * 撤销栈到了上限时长度不再变,靠它才看得出"又多了一步"(实例视图把图和状态的撤销排成一条时用)。
53
+ */
54
+ historySeq: number;
55
+ /** 每载入一份新基线 +1:画布据此重新定视口(保存不算,免得每存一次都跳一下)。 */
56
+ loadSeq: number;
57
+ }
58
+ /** 撤销栈上限。 */
59
+ export declare const HISTORY_LIMIT = 60;
60
+ export declare const initialState: EditorState;
61
+ /** 会改文档的动作。 */
62
+ export type Edit = {
63
+ type: 'addNode';
64
+ id: string;
65
+ /** 步骤的 `data`;带着 `output`(来自模板)时展开成挂在它右下方的资源节点。 */
66
+ data: NodeData;
67
+ position: Point;
68
+ /** 顺手从这个节点连一条线过来(「添加下一步」;从资源拖出来 = 新步骤读这个资源)。 */
69
+ from?: string;
70
+ }
71
+ /**
72
+ * 加一个资源节点。给了 `writer` 就连「步骤 → 资源」(写),给了 `reader` 就连「资源 → 步骤」(读)。
73
+ * 没给坐标时挂在写它(读它)的步骤右下方。`select` = 加完选中它(缺省不动选中)。
74
+ */
75
+ | {
76
+ type: 'addResource';
77
+ data: ResourceData;
78
+ position?: Point;
79
+ writer?: string;
80
+ reader?: string;
81
+ select?: boolean;
82
+ }
83
+ /**
84
+ * 加一个输入节点。给了 `reader` 就连「输入 → 步骤」(把回答交给它);没给坐标时放在它左边。
85
+ * 加完选中它(好接着写问题)。
86
+ */
87
+ | {
88
+ type: 'addInput';
89
+ id: string;
90
+ data: InputData;
91
+ position?: Point;
92
+ reader?: string;
93
+ }
94
+ /** 改输入节点(值为 `undefined` 的键 = 清掉这一项)。`merge` 同 `patchNode`。 */
95
+ | {
96
+ type: 'patchInput';
97
+ id: string;
98
+ patch: Partial<InputData>;
99
+ merge?: string;
100
+ }
101
+ /** 一次加进一小片图(示例流程):算一条撤销步。`settings` 并进工作流设置(同一步)。 */
102
+ | {
103
+ type: 'addGraph';
104
+ settings?: WorkflowSettings;
105
+ nodes: WorkflowNode[];
106
+ edges: {
107
+ source: string;
108
+ target: string;
109
+ when?: string;
110
+ handoff?: Handoff | false;
111
+ update?: boolean;
112
+ }[];
113
+ } | {
114
+ type: 'removeNode';
115
+ id: string;
116
+ }
117
+ /**
118
+ * 改坐标。`silent` = 程序自动补位:照样落盘,但不进撤销栈
119
+ * (`Ctrl+Z` 撤出一个"节点全叠在原点"的版本不是任何人想要的)。
120
+ */
121
+ | {
122
+ type: 'moveNodes';
123
+ positions: Record<string, Point>;
124
+ silent?: boolean;
125
+ }
126
+ /**
127
+ * 改步骤的 `data`。值为 `undefined` 的键表示**清掉这一项**。
128
+ * `merge` 相同的连续改动并成一条撤销步(连续打字)。
129
+ */
130
+ | {
131
+ type: 'patchNode';
132
+ id: string;
133
+ patch: Partial<NodeData>;
134
+ merge?: string;
135
+ }
136
+ /** 改资源节点:名字 / 描述 / 内容(值为 `undefined` 的键 = 清掉;`items` 整份替换)。 */
137
+ | {
138
+ type: 'patchResource';
139
+ id: string;
140
+ patch: Partial<ResourceData>;
141
+ merge?: string;
142
+ } | {
143
+ type: 'connect';
144
+ source: string;
145
+ target: string;
146
+ when?: string;
147
+ } | {
148
+ type: 'removeEdge';
149
+ id: string;
150
+ }
151
+ /** 改条件。`merge` 相同的连续改动并成一条撤销步(在自定义条件里连续打字)。 */
152
+ | {
153
+ type: 'setWhen';
154
+ id: string;
155
+ when: string | undefined;
156
+ merge?: string;
157
+ }
158
+ /**
159
+ * 改交接(步骤 → 步骤)。`undefined` = 交执行结果,`false` = 只管先后,对象 = 交执行结果并附说明。
160
+ * `merge` 相同的连续改动并成一条撤销步(在交接说明里连续打字)。
161
+ */
162
+ | {
163
+ type: 'setHandoff';
164
+ id: string;
165
+ handoff: Handoff | false | undefined;
166
+ merge?: string;
167
+ }
168
+ /** 改写入方式(步骤 → 资源):整份写出 / 在原文件上更新。 */
169
+ | {
170
+ type: 'setUpdate';
171
+ id: string;
172
+ update: boolean;
173
+ }
174
+ /** 视口是视图状态:照样落盘,但不进撤销栈。 */
175
+ /** 换掉整份工作流设置(设置对话框「完成」时一次交出来 = 一条撤销步)。 */
176
+ | {
177
+ type: 'setSettings';
178
+ settings: WorkflowSettings | undefined;
179
+ }
180
+ /** 整张换掉(实例视图撤回某一处改动时用);选中的东西不在了就放掉。 */
181
+ | {
182
+ type: 'replaceDoc';
183
+ doc: WorkflowDocument;
184
+ };
185
+ export type Action = Edit | {
186
+ type: 'loading';
187
+ name: string;
188
+ } | {
189
+ type: 'loaded';
190
+ name: string;
191
+ doc: WorkflowDocument;
192
+ baseHash: string;
193
+ problems: ValidationProblem[];
194
+ } | {
195
+ type: 'broken';
196
+ name: string;
197
+ message: string;
198
+ raw: string | null;
199
+ problems: ValidationProblem[];
200
+ } | {
201
+ type: 'closed';
202
+ } | {
203
+ type: 'renamed';
204
+ name: string;
205
+ } | {
206
+ type: 'select';
207
+ selection: Selection;
208
+ } | {
209
+ type: 'undo';
210
+ } | {
211
+ type: 'redo';
212
+ }
213
+ /** 丢掉重做栈(实例视图里别处有了新的一步:撤销排成一条,新的一步之后都不能重做)。 */
214
+ | {
215
+ type: 'dropFuture';
216
+ }
217
+ /** 一次交互结束(输入失焦):断开历史合并。 */
218
+ | {
219
+ type: 'seal';
220
+ } | {
221
+ type: 'saveStarted';
222
+ rev: number;
223
+ } | {
224
+ type: 'saveDone';
225
+ baseHash: string;
226
+ } | {
227
+ type: 'saveFailed';
228
+ message: string;
229
+ }
230
+ /**
231
+ * 回读磁盘后的刷新。带 `doc` = 本地没有在途改动,整份换成磁盘上(合并后)的版本;
232
+ * `external` = 这份来自外部改动而不是自己的保存,旧历史作废。
233
+ */
234
+ | {
235
+ type: 'refreshed';
236
+ problems: ValidationProblem[];
237
+ doc?: WorkflowDocument;
238
+ baseHash?: string;
239
+ external?: boolean;
240
+ };
241
+ export declare function isDirty(state: EditorState): boolean;
242
+ export declare function findNode(doc: WorkflowDocument, id: string): WorkflowNode | undefined;
243
+ export declare function findEdge(doc: WorkflowDocument, id: string): WorkflowEdge | undefined;
244
+ /** 一条边的条件值(空串与缺省同义)。 */
245
+ export declare function whenOf(edge: WorkflowEdge): string | undefined;
246
+ /** 新步骤的 id:撞名就加 `-2`、`-3`…(**绝不静默覆盖**)。 */
247
+ export declare function uniqueNodeId(doc: WorkflowDocument, base: string): string;
248
+ /** 这个资源已经有步骤在写(`except` 除外)——再接上来的写入默认是"在原文件上更新"。 */
249
+ export declare function alreadyWritten(doc: WorkflowDocument, resourceId: string, except?: string): boolean;
250
+ /** 图里资源已经用掉的文件路径(规范化、小写后)。 */
251
+ export declare function takenPaths(doc: WorkflowDocument): string[];
252
+ export declare function reduce(state: EditorState, action: Action): EditorState;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * dsh-workflow-lite — 文件的类型:按扩展名粗分几类,给类型签配色、决定能不能在查看框里看。
3
+ *
4
+ * @module @xiaoso/dsh-workflow-lite/client/model/fileKind
5
+ */
6
+ export type FileKind = 'markdown' | 'text' | 'code' | 'data' | 'image' | 'other';
7
+ /** 路径的最后一段。 */
8
+ export declare function fileBaseName(path: string): string;
9
+ /** 路径去掉最后一段剩下的目录(没有就是空串)。 */
10
+ export declare function fileDirName(path: string): string;
11
+ /** 扩展名,小写、不带点;没有就是空串。 */
12
+ export declare function extensionOf(path: string): string;
13
+ export declare function fileKindOf(path: string): FileKind;
14
+ /** 字节数写成人看的样子:`812 B`、`3.4 KB`、`1.2 MB`。 */
15
+ export declare function formatBytes(bytes: number): string;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * dsh-workflow-lite — 主机路径拆成面包屑(选择文件 / 文件夹时的路径栏)。
3
+ *
4
+ * 只认分隔符已统一成 `/` 的绝对路径(`host/list` 回的就是这种):
5
+ * `C:/Users/me` → `C:`、`Users`、`me`;`/home/me` → `/`、`home`、`me`;`//server/share/x` → `//server/share`、`x`。
6
+ *
7
+ * @module @xiaoso/dsh-workflow-lite/client/model/hostPath
8
+ */
9
+ export interface Crumb {
10
+ /** 显示的名字。 */
11
+ label: string;
12
+ /** 点它跳去的绝对路径。 */
13
+ path: string;
14
+ }
15
+ export declare function crumbs(path: string): Crumb[];
@@ -0,0 +1,24 @@
1
+ /**
2
+ * dsh-workflow-lite — 在查看框里渲染 HTML 之前,给页面补细滚动条,颜色跟着页面自己的底色走。
3
+ *
4
+ * 框里的页面是独立的源,外面的样式进不去,只能在交给 `srcdoc` 的文字里补。
5
+ *
6
+ * 滚动条画在页面上,该看的是**页面的**底色,不是画布的主题:没写背景的页面在框里是白底(画布暗色时也是),
7
+ * 暗色看板在亮色画布里照样是暗底。所以补一小段脚本,页面加载后读 `<body>` / `<html>` 的背景色,
8
+ * 深底用浅色滑块、浅底用深色滑块;脚本跑起来之前先用一个两种底色上都看得见的中灰。
9
+ *
10
+ * 样式用 `:where()` 把优先级压到零——页面自己写了滚动条样式就用页面的。插在 `<head>` 后
11
+ * (没有就在 `<html>` / doctype 后),不能插到 doctype 前面,否则页面会掉进怪异模式。
12
+ *
13
+ * @module @xiaoso/dsh-workflow-lite/client/model/htmlPreview
14
+ */
15
+ /** 深底上的滑块、浅底上的滑块、还不知道底色时的滑块。 */
16
+ export declare const THUMB: {
17
+ readonly onDark: "rgba(255,255,255,.28)";
18
+ readonly onLight: "rgba(0,0,0,.28)";
19
+ readonly unknown: "rgba(128,128,128,.45)";
20
+ };
21
+ /** 补进页面的那一段。 */
22
+ export declare const PREVIEW_STYLE: string;
23
+ /** 把 {@link PREVIEW_STYLE} 插进页面。 */
24
+ export declare function withPreviewStyle(html: string): string;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * dsh-workflow-lite — 工作流中心「运行实例」页的筛选与分组:按工作区分组、按工作区 / 会话 / 关键字筛。
3
+ *
4
+ * 工作区就是实例建立时会话的 `cwd`;路径的大小写、分隔符、末尾斜杠不同也算同一个(Windows)。
5
+ * 没记下工作区的实例归在一组(键是空串)。
6
+ *
7
+ * @module @xiaoso/dsh-workflow-lite/client/model/hubRuns
8
+ */
9
+ import type { InstanceSummary } from '../../shared/runState.ts';
10
+ /** 一个工作区。 */
11
+ export interface HubWorkspace {
12
+ /** 比较用的键(标准化后的路径;没有工作区是空串)。 */
13
+ key: string;
14
+ /** 原样的路径(取这一组里最新那个实例记下的写法)。 */
15
+ path: string | undefined;
16
+ /** 显示用的名字:路径最后一段。 */
17
+ name: string;
18
+ count: number;
19
+ /** 是不是本会话所在的工作区。 */
20
+ here: boolean;
21
+ }
22
+ /** 工作区的比较键。 */
23
+ export declare function workspaceKey(cwd: string | undefined): string;
24
+ /** 路径最后一段(`D:\a\b` → `b`;盘符根 `D:\` → `D:`)。 */
25
+ export declare function workspaceName(path: string): string;
26
+ /** 列表里出现过的工作区:本会话的在最前,其余按最近一次建实例的时间,新的在前。 */
27
+ export declare function workspacesOf(items: readonly InstanceSummary[], hereCwd: string | undefined): HubWorkspace[];
28
+ /** 关键字命中没有:工作流名、会话标题、目标、工作区路径、实例 id,忽略大小写;空白分开的几个词都要命中。 */
29
+ export declare function matchesQuery(item: InstanceSummary, sessionTitle: string | undefined, query: string): boolean;
30
+ export interface HubFilter {
31
+ /** `'all'` = 全部工作区;否则是 {@link workspaceKey}。 */
32
+ workspace: string;
33
+ /** 只看本会话的。 */
34
+ mine: boolean;
35
+ query: string;
36
+ }
37
+ /** 按筛选条件挑出实例,再按工作区分组(组的顺序同 {@link workspacesOf},组内保持原顺序:新的在前)。 */
38
+ export declare function groupRuns(items: readonly InstanceSummary[], options: HubFilter & {
39
+ session: string | undefined;
40
+ hereCwd: string | undefined;
41
+ titleOf: (session: string | undefined) => string | undefined;
42
+ }): {
43
+ workspace: HubWorkspace;
44
+ items: InstanceSummary[];
45
+ }[];
@@ -0,0 +1,83 @@
1
+ /**
2
+ * dsh-workflow-lite — 自动布局。
3
+ *
4
+ * 整图重排交给 ELK(`elkjs` 的 layered 算法):分层、同层排序(减少交叉)、算坐标都是它做的。
5
+ * 我们只把自己的版式语法喂给它:
6
+ * - **列 = 执行批次**:用 ELK 的 interactive 分层,按批次给出横坐标,版面本身就在讲执行次序;
7
+ * - **资源挂在写它的步骤下面**:一个步骤和它写的资源在 ELK 眼里是一整块(步骤卡 + 下面竖着一串
8
+ * 资源卡),块的高度随资源卡的高度变,ELK 按真实高度排,谁也压不到谁;资源卡往右缩进,写线从步骤的
9
+ * 写点竖着落下来、分叉进每张资源卡的左边(见 route.ts),不会穿过任何卡片;
10
+ * - 没人写、只被读的资源单独成块,放在第一个读它的步骤的前一列;只被后面的步骤在原文件上更新、
11
+ * 却被前面的步骤读的(共享的状态文档、台账)也一样——它本来就在,是输入;
12
+ * - 读线只拉相邻一列的(或者读它的步骤没别的线拉着):跨好几列的读线不参与排版,免得把主线挤歪;
13
+ * - 流程线的进出口固定在步骤卡(不是整块)的半高处,ELK 才会把一条链摆成一条直线。
14
+ * - 列距整齐划一;只有相邻两列之间的线上挂着条件牌子 / 交接标记时,把那一处拉开到放得下牌子。
15
+ *
16
+ * 补位(只给个别新节点找地方)仍是同步的就近规则:已经摆好的版面一律不动。
17
+ *
18
+ * `(0,0)` 是"还没摆过"的哨兵值(host 新建节点时的初始坐标),所以版面原点不落在它上面。
19
+ *
20
+ * @module @xiaoso/dsh-workflow-lite/client/model/layout
21
+ */
22
+ import type { GraphAnalysis } from '../../shared/graph.ts';
23
+ import type { Point, ResourceData, WorkflowDocument, WorkflowNode } from '../../shared/types.ts';
24
+ /** 步骤卡的宽度(CSS 里写死同一个数)与估算高度。 */
25
+ export declare const NODE_W = 216;
26
+ export declare const NODE_H = 96;
27
+ /** 资源卡的宽度(CSS 里写死同一个数)与紧凑时的高度(只有一项、没起名字:一行,像一张文件卡)。 */
28
+ export declare const RES_W = 200;
29
+ export declare const RES_H = 56;
30
+ /** 资源卡上最多列几项,再多折成"还有 N 项"。 */
31
+ export declare const RES_SHOWN = 4;
32
+ /** 资源卡是不是紧凑的一行:没名字、没描述、最多一项。 */
33
+ export declare function isCompactResource(data: ResourceData): boolean;
34
+ /** 资源卡的估算高度(画布量出来之前按它排)。 */
35
+ export declare function resourceHeight(data: ResourceData): number;
36
+ /** 输入卡的宽度(CSS 里写死同一个数)与估算高度:挂在读它的步骤旁边。 */
37
+ export declare const INPUT_W = 180;
38
+ export declare const INPUT_H = 56;
39
+ /** 一张卡的标称尺寸(还没量出来时按它算)。 */
40
+ export declare function cardSize(node: WorkflowNode): {
41
+ w: number;
42
+ h: number;
43
+ };
44
+ /**
45
+ * 资源卡相对写它的步骤:往右缩进 `RES_DX`(左边要让出树干和拐弯),第一张离步骤底边
46
+ * `RES_DY`,往下每张隔 `RES_GAP`。
47
+ */
48
+ export declare const RES_DX = 84;
49
+ /** 列距(「添加下一步」也按它往右挪一列)与行距。 */
50
+ export declare const COL_STEP: number;
51
+ export declare const ROW_STEP = 132;
52
+ /**
53
+ * 一个资源卡该放哪:挂在写它的步骤(没人写就是读它的步骤)下面、往右缩进,被占了就往下找。
54
+ * @param anchor - 写它 / 读它的步骤的坐标;没有就放在版面左下。
55
+ */
56
+ export declare function resourceSpot(doc: WorkflowDocument, anchor: Point | undefined, skip?: string, height?: number): Point;
57
+ /**
58
+ * 一个输入卡该放哪:读它的步骤左边、和步骤上沿对齐,被占了就往下找;没有读它的步骤就放在版面左上方。
59
+ */
60
+ export declare function inputSpot(doc: WorkflowDocument, reader: Point | undefined, skip?: string): Point;
61
+ /** 这个节点是不是还没摆过。 */
62
+ export declare function isUnplaced(position: Point): boolean;
63
+ /** 量出来的卡片尺寸(画布上已经渲染过的卡);没有就按估算尺寸。 */
64
+ export type SizeOf = (id: string) => {
65
+ width: number;
66
+ height: number;
67
+ } | undefined;
68
+ /**
69
+ * 整图重排:每个节点都重算,同一张图必然摆成同一版式。
70
+ * @param sizeOf - 卡片的真实尺寸(步骤卡的高度随内容变);不给就按估算尺寸。
71
+ */
72
+ export declare function tidy(doc: WorkflowDocument, analysis: GraphAnalysis, sizeOf?: SizeOf): Promise<Record<string, Point>>;
73
+ /** 从 `want` 起往下找一个不压住任何已有卡片的位置。 */
74
+ export declare function freeSpot(occupied: readonly Point[], want: Point): Point;
75
+ /** 「添加下一步」的落点:源步骤的右边一列,被占了就往下找。 */
76
+ export declare function nextTo(doc: WorkflowDocument, source: Point): Point;
77
+ /**
78
+ * 给**还没摆过**的节点补坐标(已有坐标的一律不动)。
79
+ *
80
+ * 全都没摆过 ⇒ 整图重排;只有个别没摆过(模型用工具新加了一步)⇒ 挨着它的上游放,
81
+ * 不去动用户已经摆好的版面。
82
+ */
83
+ export declare function placeMissing(doc: WorkflowDocument, analysis: GraphAnalysis): Promise<Record<string, Point>>;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * dsh-workflow-lite — 步骤库的内容,与「库 → 画布」的拖放载荷。
3
+ *
4
+ * 内置步骤是**起点不是规范**:开箱即用的提示词骨架,插进图里之后随便改。没有它们,
5
+ * 一张新图只能从空白提示词写起。文案全部走 locale 词典(键名在这里,正文在 `i18n.ts`)。
6
+ *
7
+ * @module @xiaoso/dsh-workflow-lite/client/model/library
8
+ */
9
+ import type { Handoff, InputData, InputKind, NodeData, WorkflowNode, WorkflowSettings } from '../../shared/types.ts';
10
+ import type { LocaleKey, T } from '../i18n.ts';
11
+ export interface StepPreset {
12
+ /** 建议的节点 id(撞名由 `uniqueNodeId` 加序号)。 */
13
+ id: string;
14
+ labelKey: LocaleKey;
15
+ descKey: LocaleKey;
16
+ promptKey: LocaleKey;
17
+ /** 产出契约;`false` = 显式声明不产出文件。 */
18
+ output?: string | false;
19
+ /** 产出文件的生成规则(进计划的「产出要求」)。 */
20
+ ruleKey?: LocaleKey;
21
+ }
22
+ /** 呈现顺序 = 一条常见主线的顺序。 */
23
+ export declare const PRESETS: readonly StepPreset[];
24
+ /**
25
+ * 右侧面板正在看步骤库里的哪一项(与画布上的选中互斥)。
26
+ * `new` = 正在新建一个「我的步骤」,`seed` 是预填的内容(复制内置步骤时带过来)。
27
+ */
28
+ export type LibraryFocus = {
29
+ kind: 'preset';
30
+ id: string;
31
+ } | {
32
+ kind: 'template';
33
+ name: string;
34
+ } | {
35
+ kind: 'new';
36
+ seed: NodeData;
37
+ name: string;
38
+ };
39
+ /** 空白步骤的建议 id。 */
40
+ export declare const BLANK_ID = "step";
41
+ /** 输入节点的建议 id。 */
42
+ export declare const INPUT_ID = "ask";
43
+ /**
44
+ * 输入的四种交互(呈现顺序)与文案。步骤库里只有一个「用户输入」,拖到画布上默认是一句话,
45
+ * 在属性面板里切换交互方式。
46
+ */
47
+ export declare const INPUT_KIND_OPTIONS: readonly {
48
+ kind: InputKind;
49
+ labelKey: LocaleKey;
50
+ }[];
51
+ /** 交互方式的显示名。 */
52
+ export declare function inputKindLabel(kind: InputKind): LocaleKey;
53
+ /** 新输入节点的 `data`:一句话,带一个起手的问题(空问题挡编译)。 */
54
+ export declare function inputData(t: T): InputData;
55
+ /** 内置步骤实例化成节点的 `data`。 */
56
+ export declare function presetData(preset: StepPreset, t: T): NodeData;
57
+ /**
58
+ * 示例流程:侦察 → 实现 → 审查,通过去汇总,未通过去修复再回到审查。
59
+ * 一次把能用的东西都摆出来,比任何说明文字都快:
60
+ * - 顺序、条件分支(通过 / 未通过)、循环(修完回到审查),线上附交接说明;
61
+ * - 用户输入:执行前问「这次要做什么」(多行文字、必填,交给侦察与实现)和「审查要多严格」(单选,交给审查);
62
+ * - 资源:每一步的产出挂在它右下方;审查报告由修复在原文件上打钩、汇总读它的最终版;
63
+ * 「项目资料」一张卡放文件夹、文件、网址三项,侦察和实现都读它;
64
+ * 「团队约定」是一段自定义提示词,一条线都不连 = 交给每一步;
65
+ * - 设置:打开「记录运行状态」,执行后能在实例里看进度。
66
+ */
67
+ export declare function starterGraph(t: T): {
68
+ settings: WorkflowSettings;
69
+ nodes: WorkflowNode[];
70
+ edges: {
71
+ source: string;
72
+ target: string;
73
+ when?: string;
74
+ handoff?: Handoff | false;
75
+ update?: boolean;
76
+ }[];
77
+ };
78
+ /** 自定义 MIME,免得跟别处的拖放撞车。 */
79
+ export declare const DND_MIME = "application/x-workflow-lite-step";
80
+ /** 从库里拿出来的东西:空白步骤、内置步骤,或磁盘上的节点模板。 */
81
+ export type StepSource = {
82
+ kind: 'blank';
83
+ }
84
+ /**
85
+ * 一张资源卡(不是步骤,但同样从库里拖、从菜单里加)。从步骤的写点 / 「+」加的是这一步的产出文件;
86
+ * 别处加的是一张空的资源卡。
87
+ */
88
+ | {
89
+ kind: 'resource';
90
+ }
91
+ /** 一个输入节点(执行前问用户的问题)。 */
92
+ | {
93
+ kind: 'input';
94
+ } | {
95
+ kind: 'preset';
96
+ id: string;
97
+ } | {
98
+ kind: 'template';
99
+ name: string;
100
+ };
101
+ export declare function encodeStepSource(source: StepSource): string;
102
+ /**
103
+ * 解码。`dataTransfer` 里可能是别的应用拖进来的任意内容,那不是错误而是"不归我们管":
104
+ * 任何不认识的输入一律返回 `null`,**永不抛异常**。
105
+ *
106
+ * 用 `Map` 查键而不是直接读属性:`JSON.parse('{"__proto__":{"kind":"blank"}}')` 得到的对象
107
+ * 会顺着原型链读出一个它自己并没有的 `kind`;`Map.get` 只认自有键。
108
+ */
109
+ export declare function decodeStepSource(raw: string | null | undefined): StepSource | null;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * dsh-workflow-lite — 直角线分道(nudging):不同颜色的线不叠在同一条道上。
3
+ *
4
+ * 每条直角线是各自挑路的(走廊、绕行折线),两条不同种类的线常常挑中同一条缝、同一条走廊,
5
+ * 叠成一根分不清。这里在挑完路之后统一过一遍(libavoid 的 orthogonal nudging 那一步的简化版):
6
+ * - 找出**共线(或挨得不到一个道距)、又有一段重叠**的横段 / 竖段,连成一簇;
7
+ * - 同一种颜色(`group`)的线可以继续合在一条道上(本来就是一类线,合着反而清爽);
8
+ * - 不同颜色的分到相邻的平行道上,道距 `GAP`,在这一簇所在的空当(上下 / 左右最近的卡片之间)里
9
+ * 尽量居中摆开,空当窄就把道距压小;
10
+ * - 只挪中间的段:接在连接点上的头尾两段不动,挪一段只是让它两头相邻的段变长 / 变短,线还是直角的;
11
+ * - 道的先后按线从哪边来、往哪边去排(从上面来的走上面那条道),尽量不因为分道再多出交叉。
12
+ *
13
+ * 纯计算,不碰 DOM。
14
+ * @module @xiaoso/dsh-workflow-lite/client/model/nudge
15
+ */
16
+ import type { Rect } from './route.ts';
17
+ export interface Track {
18
+ id: string;
19
+ /** 颜色类(同一类的线可以合道)。 */
20
+ group: string;
21
+ /** 折点(含两头)。 */
22
+ points: readonly [number, number][];
23
+ }
24
+ /**
25
+ * 给一组直角线分道。返回挪过的线的新折点(没挪的不在结果里);传进来的数组不改。
26
+ * @param boxes - 卡片(道不能摆进卡片里)。
27
+ */
28
+ export declare function nudge(tracks: readonly Track[], boxes: readonly Rect[]): Map<string, [number, number][]>;
29
+ /** 走廊线上的一块条件牌子:挂在 `y` 这条走廊上,只能在 `from`..`to` 之间挪,原本想放在 `prefer`。 */
30
+ export interface Chip {
31
+ id: string;
32
+ y: number;
33
+ from: number;
34
+ to: number;
35
+ prefer: number;
36
+ width: number;
37
+ }
38
+ /**
39
+ * 走廊上的条件牌子错开摆:两条线并排走同一段走廊时(比如同一对步骤之间的「通过」和「未通过」),
40
+ * 牌子原本落在同一个位置、一块压住另一块。按 id 依次摆,叠上了就沿着自己的走廊往两边挪,
41
+ * 挪到走廊尽头都放不下就留在原处。返回每块牌子中心的 x。
42
+ */
43
+ export declare function placeChips(chips: readonly Chip[]): Map<string, number>;