@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.
- package/LICENSE +24 -0
- package/README.en.md +84 -0
- package/README.md +83 -2
- package/THIRD_PARTY_NOTICES.md +762 -0
- package/assets/icon-full.webp +0 -0
- package/assets/icon.webp +0 -0
- package/assets/wordmark.png +0 -0
- package/cordis.patch.yml +3 -0
- package/lib/client.js +127442 -0
- package/lib/index.mjs +9613 -0
- package/lib/types/client/app/addStep.d.ts +25 -0
- package/lib/types/client/app/desktop.d.ts +52 -0
- package/lib/types/client/app/host.d.ts +29 -0
- package/lib/types/client/app/sessions.d.ts +117 -0
- package/lib/types/client/app/theme.d.ts +27 -0
- package/lib/types/client/app/usePluginConfig.d.ts +59 -0
- package/lib/types/client/app/useRunFile.d.ts +24 -0
- package/lib/types/client/app/useRunGraph.d.ts +51 -0
- package/lib/types/client/app/useRunHistory.d.ts +21 -0
- package/lib/types/client/app/useRuns.d.ts +84 -0
- package/lib/types/client/app/useVersions.d.ts +50 -0
- package/lib/types/client/app/useWorkflow.d.ts +67 -0
- package/lib/types/client/app/viewport.d.ts +14 -0
- package/lib/types/client/i18n.d.ts +930 -0
- package/lib/types/client/index.d.ts +18 -0
- package/lib/types/client/model/connect.d.ts +44 -0
- package/lib/types/client/model/editor.d.ts +252 -0
- package/lib/types/client/model/fileKind.d.ts +15 -0
- package/lib/types/client/model/hostPath.d.ts +15 -0
- package/lib/types/client/model/htmlPreview.d.ts +24 -0
- package/lib/types/client/model/hubRuns.d.ts +45 -0
- package/lib/types/client/model/layout.d.ts +83 -0
- package/lib/types/client/model/library.d.ts +109 -0
- package/lib/types/client/model/nudge.d.ts +43 -0
- package/lib/types/client/model/pathSample.d.ts +26 -0
- package/lib/types/client/model/route.d.ts +121 -0
- package/lib/types/client/model/runDraft.d.ts +68 -0
- package/lib/types/client/model/runGraph.d.ts +15 -0
- package/lib/types/client/model/runHistory.d.ts +40 -0
- package/lib/types/client/model/themes.d.ts +87 -0
- package/lib/types/client/model/time.d.ts +7 -0
- package/lib/types/client/rpc.d.ts +42 -0
- package/lib/types/client/ui/AppearancePicker.d.ts +23 -0
- package/lib/types/client/ui/Canvas.d.ts +76 -0
- package/lib/types/client/ui/Confirm.d.ts +42 -0
- package/lib/types/client/ui/DocViewer.d.ts +67 -0
- package/lib/types/client/ui/Dock.d.ts +13 -0
- package/lib/types/client/ui/FileTag.d.ts +9 -0
- package/lib/types/client/ui/FileViewer.d.ts +30 -0
- package/lib/types/client/ui/FlowStreaks.d.ts +40 -0
- package/lib/types/client/ui/Handoff.d.ts +30 -0
- package/lib/types/client/ui/HostPicker.d.ts +31 -0
- package/lib/types/client/ui/HubDialog.d.ts +38 -0
- package/lib/types/client/ui/HubRunRow.d.ts +22 -0
- package/lib/types/client/ui/HubRuns.d.ts +19 -0
- package/lib/types/client/ui/HubSettings.d.ts +20 -0
- package/lib/types/client/ui/HubStorage.d.ts +18 -0
- package/lib/types/client/ui/HubWorkflowList.d.ts +21 -0
- package/lib/types/client/ui/HubWorkflowRow.d.ts +33 -0
- package/lib/types/client/ui/HubWorkflows.d.ts +26 -0
- package/lib/types/client/ui/HubWorkspacePicker.d.ts +16 -0
- package/lib/types/client/ui/Icon.d.ts +83 -0
- package/lib/types/client/ui/InputPanel.d.ts +37 -0
- package/lib/types/client/ui/InputsDialog.d.ts +22 -0
- package/lib/types/client/ui/Inspector.d.ts +51 -0
- package/lib/types/client/ui/Issues.d.ts +15 -0
- package/lib/types/client/ui/Launch.d.ts +30 -0
- package/lib/types/client/ui/Library.d.ts +23 -0
- package/lib/types/client/ui/LinkRow.d.ts +31 -0
- package/lib/types/client/ui/Markdown.d.ts +21 -0
- package/lib/types/client/ui/NodeHeads.d.ts +47 -0
- package/lib/types/client/ui/NoteDrawer.d.ts +21 -0
- package/lib/types/client/ui/OpenWith.d.ts +21 -0
- package/lib/types/client/ui/Outputs.d.ts +61 -0
- package/lib/types/client/ui/PanelHead.d.ts +21 -0
- package/lib/types/client/ui/PlanDialog.d.ts +18 -0
- package/lib/types/client/ui/PreviewCard.d.ts +38 -0
- package/lib/types/client/ui/QuickAdd.d.ts +30 -0
- package/lib/types/client/ui/ResourceItemDialog.d.ts +33 -0
- package/lib/types/client/ui/ResourceItems.d.ts +30 -0
- package/lib/types/client/ui/ResourcePanel.d.ts +26 -0
- package/lib/types/client/ui/Resources.d.ts +43 -0
- package/lib/types/client/ui/RunDraftBar.d.ts +35 -0
- package/lib/types/client/ui/RunEdge.d.ts +29 -0
- package/lib/types/client/ui/RunFiles.d.ts +24 -0
- package/lib/types/client/ui/RunInput.d.ts +26 -0
- package/lib/types/client/ui/RunItemDialog.d.ts +43 -0
- package/lib/types/client/ui/RunModeSwitch.d.ts +14 -0
- package/lib/types/client/ui/RunNav.d.ts +22 -0
- package/lib/types/client/ui/RunNodeState.d.ts +42 -0
- package/lib/types/client/ui/RunOverview.d.ts +27 -0
- package/lib/types/client/ui/RunPosition.d.ts +24 -0
- package/lib/types/client/ui/RunResource.d.ts +40 -0
- package/lib/types/client/ui/RunStatusMenu.d.ts +28 -0
- package/lib/types/client/ui/RunStep.d.ts +45 -0
- package/lib/types/client/ui/RunTopBar.d.ts +42 -0
- package/lib/types/client/ui/RunView.d.ts +43 -0
- package/lib/types/client/ui/SettingsDialog.d.ts +25 -0
- package/lib/types/client/ui/SettingsFields.d.ts +37 -0
- package/lib/types/client/ui/SkillPicker.d.ts +25 -0
- package/lib/types/client/ui/SkillPreview.d.ts +27 -0
- package/lib/types/client/ui/StepMark.d.ts +16 -0
- package/lib/types/client/ui/StepPanel.d.ts +26 -0
- package/lib/types/client/ui/ThemePicker.d.ts +13 -0
- package/lib/types/client/ui/TipLayer.d.ts +17 -0
- package/lib/types/client/ui/TopBar.d.ts +32 -0
- package/lib/types/client/ui/VersionList.d.ts +19 -0
- package/lib/types/client/ui/VersionRow.d.ts +19 -0
- package/lib/types/client/ui/VersionsDialog.d.ts +18 -0
- package/lib/types/client/ui/WorkflowRow.d.ts +32 -0
- package/lib/types/client/ui/WorkflowSwitcher.d.ts +20 -0
- package/lib/types/client/ui/WorkflowView.d.ts +27 -0
- package/lib/types/client/ui/lines.d.ts +13 -0
- package/lib/types/client/ui/primitives.d.ts +119 -0
- package/lib/types/client/ui/resourceUi.d.ts +49 -0
- package/lib/types/client/ui/stepIcons.d.ts +10 -0
- package/lib/types/host/authoringSkill.d.ts +17 -0
- package/lib/types/host/config.d.ts +54 -0
- package/lib/types/host/hostFs.d.ts +69 -0
- package/lib/types/host/plan.d.ts +68 -0
- package/lib/types/host/pluginConfig.d.ts +57 -0
- package/lib/types/host/rpc.d.ts +45 -0
- package/lib/types/host/runs/files.d.ts +37 -0
- package/lib/types/host/runs/notice.d.ts +21 -0
- package/lib/types/host/runs/service.d.ts +258 -0
- package/lib/types/host/runs/skill.d.ts +16 -0
- package/lib/types/host/runs/storage.d.ts +16 -0
- package/lib/types/host/runs/store.d.ts +56 -0
- package/lib/types/host/skillView.d.ts +22 -0
- package/lib/types/host/store/atomic.d.ts +34 -0
- package/lib/types/host/store/materialize.d.ts +19 -0
- package/lib/types/host/store/merge.d.ts +25 -0
- package/lib/types/host/store/paths.d.ts +86 -0
- package/lib/types/host/store/repository.d.ts +217 -0
- package/lib/types/host/store/versions.d.ts +38 -0
- package/lib/types/host/tool/tool.d.ts +432 -0
- package/lib/types/index.d.ts +35 -0
- package/lib/types/shared/appearance.d.ts +49 -0
- package/lib/types/shared/compile.d.ts +71 -0
- package/lib/types/shared/graph.d.ts +54 -0
- package/lib/types/shared/graphDiff.d.ts +29 -0
- package/lib/types/shared/inputs.d.ts +46 -0
- package/lib/types/shared/limits.d.ts +77 -0
- package/lib/types/shared/model.d.ts +122 -0
- package/lib/types/shared/naming.d.ts +59 -0
- package/lib/types/shared/outputPaths.d.ts +49 -0
- package/lib/types/shared/resources.d.ts +98 -0
- package/lib/types/shared/runCursor.d.ts +54 -0
- package/lib/types/shared/runState.d.ts +221 -0
- package/lib/types/shared/runSync.d.ts +24 -0
- package/lib/types/shared/types.d.ts +488 -0
- package/lib/types/shared/validate.d.ts +54 -0
- package/lib/types/shared/wire.d.ts +600 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +144 -4
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 沿一条 SVG 路径等距取点(纯计算,不碰 DOM)。
|
|
3
|
+
*
|
|
4
|
+
* 光带(FlowStreaks)每次线变了都要沿线重新取点;拖卡片时线每帧都在变。以前是把路径塞进一个
|
|
5
|
+
* 隐形的 `<path>` 再调 `getTotalLength` / `getPointAtLength`,每次都要浏览器重新解析、量一遍,
|
|
6
|
+
* 是拖动时主线程上最大的开销之一。这里直接按画布自己生成的路径算:把曲线压成细折线,按弧长取点。
|
|
7
|
+
*
|
|
8
|
+
* 只认画布会生成的绝对坐标命令:`M` `L` `H` `V` `Q` `C` `Z`(React Flow 的贝塞尔用逗号分隔,也认)。
|
|
9
|
+
* 碰到别的命令返回 `null`,调用方自己退回 DOM 测量。
|
|
10
|
+
*
|
|
11
|
+
* @module @xiaoso/dsh-workflow-lite/client/model/pathSample
|
|
12
|
+
*/
|
|
13
|
+
export interface MeasuredPath {
|
|
14
|
+
/** 整条路径的长度。 */
|
|
15
|
+
length: number;
|
|
16
|
+
/** 从起点到终点等距取 `count` 个点(含两头),每个点带它离起点的弧长。 */
|
|
17
|
+
sample(count: number): {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
at: number;
|
|
21
|
+
}[];
|
|
22
|
+
}
|
|
23
|
+
/** 把路径压成折线(相邻的重复点去掉)。不认识的命令 → `null`。 */
|
|
24
|
+
export declare function flattenPath(d: string): [number, number][] | null;
|
|
25
|
+
/** 量一条路径。路径为空、长度为零或认不出来时返回 `null`。 */
|
|
26
|
+
export declare function measurePath(d: string): MeasuredPath | null;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 读写线挂在哪两个连接点上、怎么走。
|
|
3
|
+
*
|
|
4
|
+
* 画布的版式语法是「左右走流程,上下走文件」:步骤左右两侧只接步骤之间的线,读写线一律挂在
|
|
5
|
+
* 步骤的上下边。文件卡和步骤卡一样「左进右出」:左边的空心圈接写入,右边的实心点拖出去是读取。
|
|
6
|
+
* 每条线**都落在一个真实的连接点上**(点画在哪,线就接在哪),只是按两张卡当下的位置挑用哪一个:
|
|
7
|
+
* - 写:文件在下方 = 步骤底边 `file` → 文件左边 `in`;文件在上方 = 步骤上边 `fileUp` → 文件左边 `in`;
|
|
8
|
+
* - 读:文件右边 `out` 出发,步骤在上方落到它底边的 `read`,在下方落到上边的 `readTop`。
|
|
9
|
+
*
|
|
10
|
+
* 写线是直角折线:从步骤的写点竖着落下(升起)、拐个弯横着进文件卡的左边。一个步骤写的几份文件
|
|
11
|
+
* 竖着挂在它下面,几条写线共用一根"树干"、各自分叉进自己的文件——像文件树,不会穿过别的卡片。
|
|
12
|
+
*
|
|
13
|
+
* 连接点在卡片边上的位置也定在这里(`STEP_SPOTS` / `FILE_SPOTS`),卡片组件照着摆,
|
|
14
|
+
* 拖线预览照着算,三处永远一致。
|
|
15
|
+
*
|
|
16
|
+
* @module @xiaoso/dsh-workflow-lite/client/model/route
|
|
17
|
+
*/
|
|
18
|
+
export type Side = 'top' | 'right' | 'bottom' | 'left';
|
|
19
|
+
export interface Rect {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
w: number;
|
|
23
|
+
h: number;
|
|
24
|
+
}
|
|
25
|
+
export interface Anchor {
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
side: Side;
|
|
29
|
+
}
|
|
30
|
+
/** 一个连接点在卡片上的位置:在哪条边上、沿这条边走到几成处。 */
|
|
31
|
+
export interface Spot {
|
|
32
|
+
side: Side;
|
|
33
|
+
at: number;
|
|
34
|
+
}
|
|
35
|
+
/** 步骤上挂读写线的连接点(左 `in` / 右 `out` 是流程线的,不在这里)。 */
|
|
36
|
+
export type StepFileHandle = 'file' | 'fileUp' | 'read' | 'readTop';
|
|
37
|
+
/** 文件卡上的连接点:左进(被写)右出(被读)。 */
|
|
38
|
+
export type FileHandle = 'in' | 'out';
|
|
39
|
+
/**
|
|
40
|
+
* 读点贴着左下角(读的文件多半来自左边的上游,从左边进来不用跨过自己的文件树),
|
|
41
|
+
* 写点在它右边一点:那是文件树的树干,挂在下面的文件卡往右缩进、左边对着树干。
|
|
42
|
+
* 上边的写点比底边的再靠右一点:同一列里下面的步骤往上写上面那个步骤的文件时,
|
|
43
|
+
* 它的树干和上面那个步骤的树干错开,不会连成一根、看着像两个步骤连在了一起。
|
|
44
|
+
*/
|
|
45
|
+
export declare const STEP_SPOTS: Record<StepFileHandle, Spot>;
|
|
46
|
+
export declare const FILE_SPOTS: Record<FileHandle, Spot>;
|
|
47
|
+
/** 写线从写点伸出去多远才拐弯 / 横着进文件卡前留多长。 */
|
|
48
|
+
export declare const WRITE_REACH = 22;
|
|
49
|
+
/** 连接点在画布上的坐标。 */
|
|
50
|
+
export declare function spotOf(rect: Rect, spot: Spot): Anchor;
|
|
51
|
+
/**
|
|
52
|
+
* 一条读写线挂在哪两个连接点上。
|
|
53
|
+
* @param kind `'write'` 步骤 → 文件;`'read'` 文件 → 步骤。
|
|
54
|
+
*/
|
|
55
|
+
export declare function routeFileLink(kind: 'write' | 'read', step: Rect, file: Rect): {
|
|
56
|
+
step: StepFileHandle;
|
|
57
|
+
file: FileHandle;
|
|
58
|
+
};
|
|
59
|
+
/** 读写线两头的坐标(`from` 是线的起点:写 = 步骤,读 = 文件卡)——拖线预览用。 */
|
|
60
|
+
export declare function fileLinkEnds(kind: 'write' | 'read', step: Rect, file: Rect): {
|
|
61
|
+
from: Anchor;
|
|
62
|
+
to: Anchor;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 写线的折点:从步骤的写点竖着出去,横着从左边进文件卡。
|
|
66
|
+
*
|
|
67
|
+
* - 常见的情形(文件挂在步骤下方 / 上方、左边在树干右侧):一个直角——竖着到文件那一行,横着进去;
|
|
68
|
+
* - 否则绕一下:先竖着出去一小段,横着走到文件左边外侧,再竖着对齐入口、从左边进去;
|
|
69
|
+
* 横走的那段若会穿过文件卡,就改从文件卡的另一侧绕过去。
|
|
70
|
+
*
|
|
71
|
+
* @param from 步骤上的写点(`side` 是 `bottom` 或 `top`)。
|
|
72
|
+
* @param to 文件卡左边的入口。
|
|
73
|
+
* @param fileH 文件卡的高度(绕行时要避开它)。
|
|
74
|
+
*/
|
|
75
|
+
export declare function writePoints(from: Anchor, to: {
|
|
76
|
+
x: number;
|
|
77
|
+
y: number;
|
|
78
|
+
}, fileH: number): [number, number][];
|
|
79
|
+
/**
|
|
80
|
+
* 往右走的流程线:一条三次贝塞尔。出口那头的控制柄拉得比入口那头长——线先横着走出一截、
|
|
81
|
+
* 走到两列之间的空当里再拐下去(上来),不会斜着擦过出口下面挂着的那串文件卡(它们比步骤卡
|
|
82
|
+
* 往右多伸出一截)。
|
|
83
|
+
* @returns `[路径, 标签 x, 标签 y]`(曲线正中)。
|
|
84
|
+
*/
|
|
85
|
+
export declare function flowPath(sx: number, sy: number, tx: number, ty: number): [string, number, number];
|
|
86
|
+
/** 往回走的线:右边那条竖段离出口多远(要让过出口下面那串文件卡多伸出来的一截)。 */
|
|
87
|
+
export declare const LOOP_REACH = 64;
|
|
88
|
+
/**
|
|
89
|
+
* 往回走的线横着走回来的"走廊"放在哪:从 `from` 往下找第一条横穿 `[x1, x2]` 时不压到任何卡片的 y。
|
|
90
|
+
* @param boxes 画布上的卡片(含文件卡)。
|
|
91
|
+
*/
|
|
92
|
+
export declare function freeLane(boxes: readonly Rect[], x1: number, x2: number, from: number): number;
|
|
93
|
+
/** 贝塞尔流程线(`flowPath` 的那条)会不会压到哪张卡片(不算两头自己的卡)。 */
|
|
94
|
+
export declare function flowBlocked(boxes: readonly Rect[], sx: number, sy: number, tx: number, ty: number): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* 横穿 `[x1, x2]` 时不压到任何卡片、又离 `around` 最近的 y(往上往下都找)。
|
|
97
|
+
* 候选就是 `around` 本身和每张挡路的卡片的上沿之上、下沿之下。
|
|
98
|
+
*/
|
|
99
|
+
export declare function nearestLane(boxes: readonly Rect[], x1: number, x2: number, around: number): number;
|
|
100
|
+
type Point2 = [number, number];
|
|
101
|
+
/** 一条绕开卡片的直角走线:折点(含两头)与代价(长度 + 拐弯)。 */
|
|
102
|
+
export interface OrthoRoute {
|
|
103
|
+
points: Point2[];
|
|
104
|
+
cost: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 从 `start` 到 `end` 找一条不压到任何卡片的直角折线:两头都先垂直于所在的边伸出一小段,
|
|
108
|
+
* 中间最多再拐三次,走在卡片之间的缝里。候选的竖道 / 横道取自附近卡片的四边外侧,
|
|
109
|
+
* 按"长度 + 拐弯"从便宜到贵逐条检查,第一条走得通的就是答案;一条都走不通返回 `null`。
|
|
110
|
+
* @param boxes 画布上所有卡片(含两头自己的卡片)。
|
|
111
|
+
* @param startBox / endBox 两头自己的卡片:伸出去的那一小段本来就贴着它们。
|
|
112
|
+
*/
|
|
113
|
+
export declare function orthoRoute(start: Anchor, end: Anchor, boxes: readonly Rect[], startBox: Rect, endBox: Rect): OrthoRoute | null;
|
|
114
|
+
/** 一串直角折点压没压到哪张卡片(不算 `skip` 里的)。 */
|
|
115
|
+
export declare function pointsBlocked(points: readonly Point2[], boxes: readonly Rect[], skip: readonly Rect[]): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* React Flow 的贝塞尔(`getBezierPath`,曲率 0.25)压没压到哪张卡片(不算 `skip` 里的):
|
|
118
|
+
* 读线平时就用它画,只有压到卡片时才改走直角。
|
|
119
|
+
*/
|
|
120
|
+
export declare function bezierBlocked(from: Anchor, to: Anchor, boxes: readonly Rect[], skip: readonly Rect[]): boolean;
|
|
121
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 实例视图里用户攒的状态改动(草稿)。
|
|
3
|
+
*
|
|
4
|
+
* 改动不实时落盘:先记成"字段 → 改前 / 改后"的清单,用户确认后一次交给 host(`run/save`)。
|
|
5
|
+
* 草稿期间状态文件照常刷新:模型改了别的字段,画布跟着变;模型改了用户也改过的**同一个**字段,
|
|
6
|
+
* 那条就是冲突,让用户选(见 {@link rebase})。
|
|
7
|
+
*
|
|
8
|
+
* 全是纯函数:实例视图只负责把它们接到界面上。
|
|
9
|
+
*
|
|
10
|
+
* @module @xiaoso/dsh-workflow-lite/client/model/runDraft
|
|
11
|
+
*/
|
|
12
|
+
import { type EditValue, type NodeStatus, type RunState, type StateEdit } from '../../shared/runState.ts';
|
|
13
|
+
/** 草稿里的一条冲突:用户以为的旧值、用户要的新值、文件里现在的值。 */
|
|
14
|
+
export interface DraftConflict {
|
|
15
|
+
path: string[];
|
|
16
|
+
from: EditValue;
|
|
17
|
+
to: EditValue;
|
|
18
|
+
disk: EditValue;
|
|
19
|
+
}
|
|
20
|
+
export declare function samePath(a: readonly string[], b: readonly string[]): boolean;
|
|
21
|
+
export declare function sameValue(a: EditValue, b: EditValue): boolean;
|
|
22
|
+
/** 状态里某个字段的值(没有 = `null`)。 */
|
|
23
|
+
export declare function valueAt(state: RunState, path: readonly string[]): EditValue;
|
|
24
|
+
/**
|
|
25
|
+
* 记一处改动。`base` 是文件里现在的状态:同一个字段第一次改时记下它的值当"改前";
|
|
26
|
+
* 改回和"改前"一样就从草稿里撤掉。
|
|
27
|
+
*/
|
|
28
|
+
export declare function setField(draft: readonly StateEdit[], base: RunState, path: readonly string[], to: EditValue): StateEdit[];
|
|
29
|
+
/** 把草稿叠到状态上(画布显示的就是叠完的样子)。 */
|
|
30
|
+
export declare function applyDraft(state: RunState, draft: readonly StateEdit[]): RunState;
|
|
31
|
+
/**
|
|
32
|
+
* 把一个步骤改成某个状态(连带的字段一起改,见 `statusFields`)。
|
|
33
|
+
* `base` 是文件里的状态,`now` 是这一刻的时间(ISO 8601)。
|
|
34
|
+
*/
|
|
35
|
+
export declare function setNodeStatus(draft: readonly StateEdit[], base: RunState, id: string, status: NodeStatus, now: string): StateEdit[];
|
|
36
|
+
/**
|
|
37
|
+
* "重跑这一步":它和它下游已经做过的步骤一起改回 `pending`。
|
|
38
|
+
* `downstream` 由调用方按图算好(含它自己)。
|
|
39
|
+
*/
|
|
40
|
+
export declare function rerun(draft: readonly StateEdit[], base: RunState, ids: readonly string[], now: string): StateEdit[];
|
|
41
|
+
/**
|
|
42
|
+
* 文件刷新之后重新对一遍草稿:
|
|
43
|
+
* - 文件里已经是用户要的值(模型也这么改了)→ 这条不用再存,撤掉;
|
|
44
|
+
* - 文件里的值和"改前"对不上 → 冲突;
|
|
45
|
+
* - 其余照旧。
|
|
46
|
+
*/
|
|
47
|
+
export declare function rebase(draft: readonly StateEdit[], disk: RunState): {
|
|
48
|
+
draft: StateEdit[];
|
|
49
|
+
conflicts: DraftConflict[];
|
|
50
|
+
};
|
|
51
|
+
/** 冲突的两种了结:以我的为准(改前换成文件里的值),或用文件里的(撤掉这条)。 */
|
|
52
|
+
export declare function resolve(draft: readonly StateEdit[], conflict: DraftConflict, keep: 'mine' | 'theirs'): StateEdit[];
|
|
53
|
+
/** 改了几处:按对象算(整体一处、每个步骤一处),连带改的字段不另算。 */
|
|
54
|
+
export declare function changeCount(draft: readonly StateEdit[]): number;
|
|
55
|
+
/** 一个步骤在草稿里有没有改动(卡片上挂小圆点)。 */
|
|
56
|
+
export declare function editedNodes(draft: readonly StateEdit[]): Set<string>;
|
|
57
|
+
/**
|
|
58
|
+
* 草稿存下去时流水会多出来的那几条(每个改过的步骤一条,指定下一步再一条,顺序同 `run/save`),叠在 `state` 后面。
|
|
59
|
+
* 只给推「最后执行 / 下一步」用:位置看流水先后,不补这几条,草稿里的改动在位置上看不出来。
|
|
60
|
+
*/
|
|
61
|
+
export declare function withDraftLog(state: RunState, draft: readonly StateEdit[]): RunState;
|
|
62
|
+
/** 用户指定的下一步里加上 / 去掉一步(去光了就删掉这个字段)。 */
|
|
63
|
+
export declare function togglePin(pinned: readonly string[], id: string): string[] | null;
|
|
64
|
+
/** 从某个步骤往下(沿步骤之间的线,含回边)能走到的步骤,含它自己。 */
|
|
65
|
+
export declare function downstreamOf(edges: readonly {
|
|
66
|
+
source: string;
|
|
67
|
+
target: string;
|
|
68
|
+
}[], steps: ReadonlySet<string>, start: string): string[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 实例视图里改图:单独撤回一处改动、哪些步骤不能删。
|
|
3
|
+
*
|
|
4
|
+
* 「已改 x 处」的清单按 `shared/graphDiff.ts` 数;这里把清单里的一行还原成改之前的样子
|
|
5
|
+
* (其余改动不动),交给编辑器整张换上(进撤销历史)。
|
|
6
|
+
*
|
|
7
|
+
* @module @xiaoso/dsh-workflow-lite/client/model/runGraph
|
|
8
|
+
*/
|
|
9
|
+
import type { GraphChange } from '../../shared/graphDiff.ts';
|
|
10
|
+
import type { RunState } from '../../shared/runState.ts';
|
|
11
|
+
import type { WorkflowDocument } from '../../shared/types.ts';
|
|
12
|
+
/** 把 `doc` 里的这一处改动还原成 `base` 里的样子。 */
|
|
13
|
+
export declare function revertChange(base: WorkflowDocument, doc: WorkflowDocument, change: GraphChange): WorkflowDocument;
|
|
14
|
+
/** 删不得的步骤:执行过的(状态不是待执行,或流水里有它)。不记状态的实例没有限制。 */
|
|
15
|
+
export declare function lockedSteps(state: RunState | null): (id: string) => boolean;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 实例视图的撤销 / 重做:图的改动和状态的改动排成一条。
|
|
3
|
+
*
|
|
4
|
+
* 两边各有自己的撤销栈(图:编辑器状态机;状态:草稿)。这里只记"每一步是哪一边的",
|
|
5
|
+
* 撤销时弹出最后一步、交给那一边撤;两边的栈有了变化(新的一步、到上限挤掉最早的、存完 / 放弃后清空),
|
|
6
|
+
* 用 {@link reconcileOrder} 把这条顺序对齐回去。
|
|
7
|
+
*
|
|
8
|
+
* 新的一步之后不能再重做:哪一边有了新的一步,另一边的重做栈也要丢掉(`dropFuture` 告诉调用方丢哪边)。
|
|
9
|
+
*
|
|
10
|
+
* @module @xiaoso/dsh-workflow-lite/client/model/runHistory
|
|
11
|
+
*/
|
|
12
|
+
export type HistorySide = 'graph' | 'state';
|
|
13
|
+
export declare const HISTORY_SIDES: readonly HistorySide[];
|
|
14
|
+
/** 一边的撤销栈:能撤几步、能重做几步、一共压过几步(只增不减)。 */
|
|
15
|
+
export interface SideHistory {
|
|
16
|
+
past: number;
|
|
17
|
+
future: number;
|
|
18
|
+
seq: number;
|
|
19
|
+
}
|
|
20
|
+
/** 排成一条的顺序:`past` 的最后一项是下一次撤销的那一边,`future` 的最后一项是下一次重做的那一边。 */
|
|
21
|
+
export interface HistoryOrder {
|
|
22
|
+
past: HistorySide[];
|
|
23
|
+
future: HistorySide[];
|
|
24
|
+
}
|
|
25
|
+
export declare const EMPTY_ORDER: HistoryOrder;
|
|
26
|
+
/** 两边的栈从 `before` 变成 `after` 之后,对齐这条顺序。 */
|
|
27
|
+
export declare function reconcileOrder(order: HistoryOrder, before: Record<HistorySide, SideHistory>, after: Record<HistorySide, SideHistory>): {
|
|
28
|
+
order: HistoryOrder;
|
|
29
|
+
dropFuture: HistorySide[];
|
|
30
|
+
};
|
|
31
|
+
/** 撤一步:弹出最后一步交给那一边(顺序空了但某一边还能撤,就撤那一边)。 */
|
|
32
|
+
export declare function undoStep(order: HistoryOrder, sides: Record<HistorySide, SideHistory>): {
|
|
33
|
+
order: HistoryOrder;
|
|
34
|
+
side: HistorySide;
|
|
35
|
+
} | null;
|
|
36
|
+
/** 重做一步:弹出最近撤掉的那一步。 */
|
|
37
|
+
export declare function redoStep(order: HistoryOrder, sides: Record<HistorySide, SideHistory>): {
|
|
38
|
+
order: HistoryOrder;
|
|
39
|
+
side: HistorySide;
|
|
40
|
+
} | null;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 画布的配色主题:亮色、暗色各四套。
|
|
3
|
+
*
|
|
4
|
+
* 亮 / 暗跟着宿主设在 `<html>` 上的 `color-scheme` 走;人只挑「亮的时候用哪套、暗的时候用哪套」
|
|
5
|
+
* (工作流中心「设置」页)。每套主题给出一份完整的基础色,视图根节点按选中的两套写成
|
|
6
|
+
* `--wl-l-*`、`--wl-d-*` 两组变量,shell.module.css 再用 `light-dark()` 拼成界面用的 `--wl-*`。
|
|
7
|
+
* 浅色的「淡」档(选中底、标签底)由基础色按固定比例调出来,这里不重复写。
|
|
8
|
+
*
|
|
9
|
+
* 主题不只是换底色:线色(也是光带、图例、线上牌子的颜色)、强调色、步骤图标色、状态色都是一整套。
|
|
10
|
+
* 除了两套默认和晴白,每套照着一份成熟的配色方案来配:雾蓝 = Nord、林间 = Everforest、墨黑 = Geist 式高对比、
|
|
11
|
+
* 深海 = Tokyo Night、暖夜 = Gruvbox;保留它们的色相和饱和,只按面板把亮度调到读得清。
|
|
12
|
+
* 主干线(「总是」)就用强调色,选中框、按钮、主干线、上面跑的光带是同一个颜色,整套主题一个基调。
|
|
13
|
+
*
|
|
14
|
+
* 每套都要过同一套检查(tests/client/themes.spec.ts):三级文字、强调色文字、语义色、
|
|
15
|
+
* 七种线色、步骤图标色在面板上过 4.5:1,线色在画布上过 3:1,七种线两两的 OKLab 色差不小于 8。
|
|
16
|
+
*
|
|
17
|
+
* @module @xiaoso/dsh-workflow-lite/client/model/themes
|
|
18
|
+
*/
|
|
19
|
+
export type ThemeMode = 'light' | 'dark';
|
|
20
|
+
export declare const LIGHT_THEME_IDS: readonly ["paper", "white", "mist", "sage"];
|
|
21
|
+
export declare const DARK_THEME_IDS: readonly ["slate", "ink", "ocean", "umber"];
|
|
22
|
+
export type LightThemeId = (typeof LIGHT_THEME_IDS)[number];
|
|
23
|
+
export type DarkThemeId = (typeof DARK_THEME_IDS)[number];
|
|
24
|
+
export type ThemeId = LightThemeId | DarkThemeId;
|
|
25
|
+
export declare const DEFAULT_LIGHT: LightThemeId;
|
|
26
|
+
export declare const DEFAULT_DARK: DarkThemeId;
|
|
27
|
+
export interface ThemeTokens {
|
|
28
|
+
/** 面:画布、浮在上面的面板与卡片、输入框底、更深一档的底。 */
|
|
29
|
+
canvas: string;
|
|
30
|
+
panel: string;
|
|
31
|
+
fill: string;
|
|
32
|
+
fillStrong: string;
|
|
33
|
+
/** 网格点、悬停底、描边用的墨色(`R G B`),各自配一档透明度(百分数)。 */
|
|
34
|
+
ink: string;
|
|
35
|
+
dotAlpha: number;
|
|
36
|
+
hoverAlpha: number;
|
|
37
|
+
lineAlpha: number;
|
|
38
|
+
lineStrongAlpha: number;
|
|
39
|
+
/** 阴影的颜色(`R G B`);透明度按亮 / 暗写在 CSS 里。 */
|
|
40
|
+
shade: string;
|
|
41
|
+
scrim: string;
|
|
42
|
+
text: string;
|
|
43
|
+
text2: string;
|
|
44
|
+
text3: string;
|
|
45
|
+
accent: string;
|
|
46
|
+
accentStrong: string;
|
|
47
|
+
accentOn: string;
|
|
48
|
+
accentText: string;
|
|
49
|
+
danger: string;
|
|
50
|
+
warn: string;
|
|
51
|
+
ok: string;
|
|
52
|
+
/** 七种线:流程线按条件,读写线按读写(见 ui/lines.ts)。 */
|
|
53
|
+
always: string;
|
|
54
|
+
pass: string;
|
|
55
|
+
fail: string;
|
|
56
|
+
custom: string;
|
|
57
|
+
produce: string;
|
|
58
|
+
update: string;
|
|
59
|
+
read: string;
|
|
60
|
+
/** 资源卡。 */
|
|
61
|
+
file: string;
|
|
62
|
+
fileSurface: string;
|
|
63
|
+
fileBorder: string;
|
|
64
|
+
fileTab: string;
|
|
65
|
+
fileBack: string;
|
|
66
|
+
/** 步骤图标的色板(shared/appearance.ts 的 STEP_COLORS)。 */
|
|
67
|
+
cBlue: string;
|
|
68
|
+
cGreen: string;
|
|
69
|
+
cAmber: string;
|
|
70
|
+
cCoral: string;
|
|
71
|
+
cTeal: string;
|
|
72
|
+
cPink: string;
|
|
73
|
+
cOlive: string;
|
|
74
|
+
cViolet: string;
|
|
75
|
+
cSlate: string;
|
|
76
|
+
/** 输入节点(交回答的线)的中性墨色。 */
|
|
77
|
+
ask: string;
|
|
78
|
+
tip: string;
|
|
79
|
+
tipOn: string;
|
|
80
|
+
}
|
|
81
|
+
export declare const THEMES: Record<ThemeId, ThemeTokens>;
|
|
82
|
+
export declare function isLightTheme(id: unknown): id is LightThemeId;
|
|
83
|
+
export declare function isDarkTheme(id: unknown): id is DarkThemeId;
|
|
84
|
+
/** 一套主题写成一组 CSS 变量:亮色档写 `--wl-l-*`,暗色档写 `--wl-d-*`。 */
|
|
85
|
+
export declare function themeVars(mode: ThemeMode, id: ThemeId): Record<string, string>;
|
|
86
|
+
/** 视图根节点的内联样式:亮、暗各一套。 */
|
|
87
|
+
export declare function themeStyle(light: LightThemeId, dark: DarkThemeId): Record<string, string>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 画布的 typed RPC 调用器。
|
|
3
|
+
*
|
|
4
|
+
* 走共享 Connection 的 `/api` 通道(与 host 侧 one-route-per-endpoint 对齐)。
|
|
5
|
+
*
|
|
6
|
+
* 这里定义自己的载体接口而不直接用 `ConnectionHandle`:`dsh-client-connection` 的宿主半与
|
|
7
|
+
* 客户端半各自给 cordis 的 `Context` 声明了 `connection`,两半同进一个 TS 工程时类型冲突。
|
|
8
|
+
* 所以只按**形状**收窄出要用的那一小块(一个 `rpc.call`),运行时校验、不对就响亮报错。
|
|
9
|
+
*
|
|
10
|
+
* @module @xiaoso/dsh-workflow-lite/client/rpc
|
|
11
|
+
*/
|
|
12
|
+
import type { ConnectionRpcResult } from '@deepseek-ai/dsh-client-connection';
|
|
13
|
+
import { type WorkflowLiteEndpoint, type WorkflowLiteRpcMap } from '../shared/wire.ts';
|
|
14
|
+
/** 我们真正需要的那一小块 Connection 面。 */
|
|
15
|
+
export interface RpcCarrier {
|
|
16
|
+
rpc: {
|
|
17
|
+
call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<ConnectionRpcResult<unknown>>;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** 画布需要的调用面。 */
|
|
21
|
+
export interface WorkflowLiteRpc {
|
|
22
|
+
call<K extends WorkflowLiteEndpoint>(endpoint: K, args: WorkflowLiteRpcMap[K]['args']): Promise<WorkflowLiteRpcMap[K]['result']>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 按形状收窄出一个 RPC 载体。
|
|
26
|
+
* @param service - `ctx.get('connection')` 拿到的值。
|
|
27
|
+
* @throws 服务缺失或形状不对——宁可注册时就炸,也不要第一次保存时才炸。
|
|
28
|
+
*/
|
|
29
|
+
export declare function requireRpcCarrier(service: unknown): RpcCarrier;
|
|
30
|
+
/** 端点失败——带 host 给的 `code` 与结构化 `details`(`conflict` 的冲突清单就在里面)。 */
|
|
31
|
+
export declare class WorkflowLiteRpcError extends Error {
|
|
32
|
+
/** host 的失败码(`not_found` / `invalid_args` / `blocked` / `conflict` / `io_error`)。 */
|
|
33
|
+
readonly code: string;
|
|
34
|
+
readonly details: ReadonlyMap<string, unknown>;
|
|
35
|
+
constructor(code: string, message: string, details: unknown);
|
|
36
|
+
}
|
|
37
|
+
/** 错误的失败码;不是端点失败就给 `undefined`。 */
|
|
38
|
+
export declare function errorCode(error: unknown): string | undefined;
|
|
39
|
+
/** 错误的人话说明。 */
|
|
40
|
+
export declare function errorMessage(error: unknown): string;
|
|
41
|
+
/** 建一个调用器。 */
|
|
42
|
+
export declare function createWorkflowLiteRpc(carrier: RpcCarrier): WorkflowLiteRpc;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 选步骤的图标与颜色:点面板标题左边的图标块,弹出色板与图标库。
|
|
3
|
+
*
|
|
4
|
+
* 画布上的步骤(属性面板)与「我的步骤」(步骤库详情)共用。选了就改,不用确认;
|
|
5
|
+
* 「恢复默认」清掉两项,回到按 id 猜的样子。
|
|
6
|
+
*
|
|
7
|
+
* @module @xiaoso/dsh-workflow-lite/client/ui/AppearancePicker
|
|
8
|
+
*/
|
|
9
|
+
import { type Appearance, type StepColor, type StepIcon } from '../../shared/appearance.ts';
|
|
10
|
+
import type { T } from '../i18n.ts';
|
|
11
|
+
/** `undefined` = 清掉这一项(回到按 id 猜)。 */
|
|
12
|
+
export interface AppearancePatch {
|
|
13
|
+
icon?: StepIcon | undefined;
|
|
14
|
+
color?: StepColor | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare function AppearancePicker(props: {
|
|
17
|
+
t: T;
|
|
18
|
+
look: Appearance;
|
|
19
|
+
/** 存了样子(不是猜的):才有「恢复默认」。 */
|
|
20
|
+
custom: boolean;
|
|
21
|
+
size?: number;
|
|
22
|
+
onChange(patch: AppearancePatch): void;
|
|
23
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 画布:把文档画成步骤卡与连线,把指针操作翻译成编辑动作。
|
|
3
|
+
*
|
|
4
|
+
* 文档是事实源,React Flow 只负责渲染与手势:
|
|
5
|
+
* - 节点对象按"文档里的那个节点 + 选中/语气"缓存,没变的节点保持同一个引用,React Flow
|
|
6
|
+
* 就不会重建它的内部状态(尺寸、连接点位置);
|
|
7
|
+
* - 拖动过程中的坐标只放在本组件的局部状态里,**松手才写进文档**——一次拖拽 = 一次改动、
|
|
8
|
+
* 一条撤销步、一次保存;
|
|
9
|
+
* - 选中态由文档这边说了算,单向告诉 React Flow。
|
|
10
|
+
*
|
|
11
|
+
* @module @xiaoso/dsh-workflow-lite/client/ui/Canvas
|
|
12
|
+
*/
|
|
13
|
+
import '@xyflow/react/dist/base.css';
|
|
14
|
+
import type { GraphAnalysis } from '../../shared/graph.ts';
|
|
15
|
+
import type { NodeStatus } from '../../shared/runState.ts';
|
|
16
|
+
import type { Point, ValidationProblem, WorkflowDocument } from '../../shared/types.ts';
|
|
17
|
+
import type { LocaleKey, T } from '../i18n.ts';
|
|
18
|
+
import { type Edit, type Selection } from '../model/editor.ts';
|
|
19
|
+
import { type StepSource } from '../model/library.ts';
|
|
20
|
+
import type { FocusFile } from './Handoff.tsx';
|
|
21
|
+
/** 「在这里加一个步骤」的请求:屏幕坐标用来摆菜单,画布坐标用来落节点。 */
|
|
22
|
+
export interface AddRequest {
|
|
23
|
+
client: Point;
|
|
24
|
+
flow: Point;
|
|
25
|
+
/** 顺手从这个节点连过来(步骤 = 接一步;资源 = 新步骤读它)。 */
|
|
26
|
+
from?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface CanvasProps {
|
|
29
|
+
t: T;
|
|
30
|
+
doc: WorkflowDocument;
|
|
31
|
+
analysis: GraphAnalysis;
|
|
32
|
+
/** 换了一份基线(打开 / 重新加载)就变:据此重新定视口。 */
|
|
33
|
+
loadKey: string;
|
|
34
|
+
/** 图名:给了就把人动过的视口记在浏览器里(见 `app/viewport.ts`),下次打开接着看;不写进图文件。 */
|
|
35
|
+
viewKey?: string;
|
|
36
|
+
selection: Selection;
|
|
37
|
+
problems: readonly ValidationProblem[];
|
|
38
|
+
/** 自动看全图时四周要让开的浮层宽度。 */
|
|
39
|
+
insets: {
|
|
40
|
+
left: number;
|
|
41
|
+
right: number;
|
|
42
|
+
};
|
|
43
|
+
onEdit(edit: Edit): void;
|
|
44
|
+
onSelect(selection: Selection): void;
|
|
45
|
+
onRequestAdd(request: AddRequest): void;
|
|
46
|
+
onDropSource(source: StepSource, flow: Point): void;
|
|
47
|
+
onStarter(): void;
|
|
48
|
+
/** 正在悬停的资源卡 id:用到它的步骤标出角色,其余的淡下去。 */
|
|
49
|
+
focusFile: string | null;
|
|
50
|
+
onFocusFile: FocusFile;
|
|
51
|
+
/** 工作流实例视图:每张步骤卡挂上运行状态,走过的线亮、没走过的淡。缺省 = 模板编辑。 */
|
|
52
|
+
run?: RunDecor;
|
|
53
|
+
}
|
|
54
|
+
/** 实例视图给画布的装饰。 */
|
|
55
|
+
export interface RunDecor {
|
|
56
|
+
/**
|
|
57
|
+
* 每个步骤此刻的状态(已经叠上草稿);`mark` = 执行位置:最后执行的、接下来要做的
|
|
58
|
+
* (见 `shared/runCursor.ts`)。
|
|
59
|
+
*/
|
|
60
|
+
nodes: Readonly<Record<string, RunNodeDecor>>;
|
|
61
|
+
/** 走过的线。 */
|
|
62
|
+
taken: ReadonlySet<string>;
|
|
63
|
+
/** 资源里每个文件、文件夹在不在(资源 id → 按项;不是路径的项为 `null`)。 */
|
|
64
|
+
files: Readonly<Record<string, readonly (boolean | null)[]>>;
|
|
65
|
+
/** 点卡片上的状态小标:在它旁边弹出改状态的菜单。 */
|
|
66
|
+
onStatus(id: string, anchor: Element): void;
|
|
67
|
+
}
|
|
68
|
+
export interface RunNodeDecor {
|
|
69
|
+
status: NodeStatus;
|
|
70
|
+
round: number;
|
|
71
|
+
edited: boolean;
|
|
72
|
+
mark?: RunMark | undefined;
|
|
73
|
+
}
|
|
74
|
+
export type RunMark = 'last' | 'next';
|
|
75
|
+
export declare const RUN_TEXT: Record<NodeStatus, LocaleKey>;
|
|
76
|
+
export declare function Canvas(props: CanvasProps): React.JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 二次确认:点了删除 / 放弃这类收不回的按钮,在按钮旁边浮出一张小卡问一句。
|
|
3
|
+
*
|
|
4
|
+
* 不在原地换出「取消 / 确认」:那样同一行的东西会被挤开,用户正要点的地方跟着挪。
|
|
5
|
+
* 小卡浮在视图根上(摆位、收起规则同 {@link useFloat}),按钮原地不动、旁边的东西也不动:
|
|
6
|
+
*
|
|
7
|
+
* - 触发器在视图右半边就右边对齐,免得卡片离按钮太远;下面放不下翻到上方;
|
|
8
|
+
* - 再点一下触发器、点别处、滚动、Esc 都等于取消;焦点先落在「取消」上,关掉后回到触发器
|
|
9
|
+
* (确认后若触发器在对话框里,交给对话框——触发器多半跟着被删的东西一起没了);
|
|
10
|
+
* - 卡片里的按键不往外冒(不会删到画布上选中的步骤)。
|
|
11
|
+
*
|
|
12
|
+
* 用法:`const confirm = useConfirm<HTMLButtonElement>()`,触发器挂 `ref={confirm.anchorRef}`、
|
|
13
|
+
* `onClick={confirm.toggle}`,再在旁边放 `{confirm.render({...})}`。
|
|
14
|
+
*
|
|
15
|
+
* @module @xiaoso/dsh-workflow-lite/client/ui/Confirm
|
|
16
|
+
*/
|
|
17
|
+
import type { T } from '../i18n.ts';
|
|
18
|
+
export interface ConfirmOptions {
|
|
19
|
+
t: T;
|
|
20
|
+
/** 问的那句话:「删除这个实例?」 */
|
|
21
|
+
title: string;
|
|
22
|
+
/** 补一句后果(可选)。 */
|
|
23
|
+
desc?: string;
|
|
24
|
+
/** 标题下面额外的东西(比如「连同状态文件」勾选框)。 */
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
/** 确认按钮上的字:「删除」「放弃」。 */
|
|
27
|
+
confirmText: string;
|
|
28
|
+
/** 确认按钮的 `data-testid`;整张卡是 `${testId}-pop`。 */
|
|
29
|
+
testId?: string;
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
/** 确认按钮是红的(删除、放弃);`false` = 主色(切换这类收得回来的)。缺省红。 */
|
|
32
|
+
danger?: boolean;
|
|
33
|
+
onConfirm(): void;
|
|
34
|
+
}
|
|
35
|
+
export declare function useConfirm<A extends HTMLElement>(): {
|
|
36
|
+
anchorRef: React.RefObject<A>;
|
|
37
|
+
open: boolean;
|
|
38
|
+
show(): void;
|
|
39
|
+
hide(): void;
|
|
40
|
+
toggle(): void;
|
|
41
|
+
render(options: ConfirmOptions): React.ReactNode;
|
|
42
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 看一份文档的模态框(产出文件、SKILL.md 共用)。
|
|
3
|
+
*
|
|
4
|
+
* 标题行:图标、名字、一行元信息,右边「排版 / 源码」(Markdown、HTML 才有)、复制路径、
|
|
5
|
+
* 用其他程序打开(含在文件管理器中显示)、关闭。正文:Markdown 默认排版,HTML 默认在沙箱框里渲染
|
|
6
|
+
* (能跑脚本,但是独立的源:碰不到画布、拿不到登录态),其余原样;读不了的只说明原因。
|
|
7
|
+
* 有说明(`note`)时标题行多一个「说明」开关,点开从右边滑出一栏,不占正文的地方。
|
|
8
|
+
* 调用方可以在正文前插一段(`lead`),在底部放操作条(`footer`)。
|
|
9
|
+
* 给了 `edit` 就多一个「编辑」:整块文字在这里改(提示词、摘要这类大段文字都在弹窗里改)。
|
|
10
|
+
*
|
|
11
|
+
* @module @xiaoso/dsh-workflow-lite/client/ui/DocViewer
|
|
12
|
+
*/
|
|
13
|
+
import type { Desktop } from '../app/desktop.ts';
|
|
14
|
+
import type { T } from '../i18n.ts';
|
|
15
|
+
import { type IconName } from './Icon.tsx';
|
|
16
|
+
/** 弹窗里能改的那段文字怎么交出去。 */
|
|
17
|
+
export interface DocEdit {
|
|
18
|
+
onChange(text: string): void;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
maxLength?: number;
|
|
21
|
+
testId?: string;
|
|
22
|
+
/** 一打开就在「编辑」。 */
|
|
23
|
+
start?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** 正文是什么:还在读、读不了(说明原因)、读到了一段文字。 */
|
|
26
|
+
export type DocBody = {
|
|
27
|
+
kind: 'loading';
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'state';
|
|
30
|
+
icon: IconName;
|
|
31
|
+
text: string;
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'text';
|
|
34
|
+
text: string;
|
|
35
|
+
format: 'plain' | 'markdown' | 'html';
|
|
36
|
+
}
|
|
37
|
+
/** 调用方自己画的正文(文件夹里有什么、网址的说明)。 */
|
|
38
|
+
| {
|
|
39
|
+
kind: 'node';
|
|
40
|
+
node: React.ReactNode;
|
|
41
|
+
};
|
|
42
|
+
export declare function DocViewer(props: {
|
|
43
|
+
t: T;
|
|
44
|
+
/** 标题(也是对话框的无障碍名)。 */
|
|
45
|
+
name: string;
|
|
46
|
+
/** 标题左边的图标块。 */
|
|
47
|
+
badge: React.ReactNode;
|
|
48
|
+
/** 标题下面的一行(路径、大小……)。 */
|
|
49
|
+
meta: React.ReactNode;
|
|
50
|
+
body: DocBody;
|
|
51
|
+
/** 「复制路径」复制什么;`null` 时按钮禁用。 */
|
|
52
|
+
copyPath: string | null;
|
|
53
|
+
/** 复制按钮的说明(缺省「复制路径」:网址、自定义文字复制的不是路径)。 */
|
|
54
|
+
copyLabel?: string;
|
|
55
|
+
/** 「用其他程序打开」打开什么;`null`(文件还不在、没有文件)时不出现。 */
|
|
56
|
+
openPath: string | null;
|
|
57
|
+
desktop: Desktop | undefined;
|
|
58
|
+
testId: string;
|
|
59
|
+
lead?: React.ReactNode;
|
|
60
|
+
/** 这一项的说明(产出文件的生成要求、步骤的描述):收在标题行的「说明」开关里。 */
|
|
61
|
+
note?: string;
|
|
62
|
+
footer?: React.ReactNode;
|
|
63
|
+
className?: string;
|
|
64
|
+
/** 能改:正文就是这段文字,「编辑」里改了直接交出去。 */
|
|
65
|
+
edit?: DocEdit;
|
|
66
|
+
onClose(): void;
|
|
67
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-workflow-lite — 左下角的缩放条:缩放、看全图、快捷键说明,加上线条图例
|
|
3
|
+
* (放不下时收成一个「图例」按钮)。模板编辑与实例视图共用。
|
|
4
|
+
*
|
|
5
|
+
* @module @xiaoso/dsh-workflow-lite/client/ui/Dock
|
|
6
|
+
*/
|
|
7
|
+
import type { T } from '../i18n.ts';
|
|
8
|
+
export declare function ZoomDock(props: {
|
|
9
|
+
t: T;
|
|
10
|
+
keysOpen: boolean;
|
|
11
|
+
setKeysOpen: (open: boolean) => void;
|
|
12
|
+
onFit: () => void;
|
|
13
|
+
}): React.JSX.Element;
|