@lokvis/ui-react 0.2.1 → 0.4.1

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 (165) hide show
  1. package/dist/components/AssetPanel.d.ts.map +1 -1
  2. package/dist/components/AssetPanel.js +18 -62
  3. package/dist/components/AssetPanel.js.map +1 -1
  4. package/dist/components/Canvas.d.ts +4 -4
  5. package/dist/components/Canvas.d.ts.map +1 -1
  6. package/dist/components/Canvas.js +9 -9
  7. package/dist/components/Canvas.js.map +1 -1
  8. package/dist/components/CommandPalette.d.ts +7 -7
  9. package/dist/components/CommandPalette.d.ts.map +1 -1
  10. package/dist/components/CommandPalette.js +10 -10
  11. package/dist/components/CommandPalette.js.map +1 -1
  12. package/dist/components/CompareSlider.d.ts +9 -8
  13. package/dist/components/CompareSlider.d.ts.map +1 -1
  14. package/dist/components/CompareSlider.js +10 -9
  15. package/dist/components/CompareSlider.js.map +1 -1
  16. package/dist/components/DownloadPanel.d.ts +3 -3
  17. package/dist/components/DownloadPanel.d.ts.map +1 -1
  18. package/dist/components/DownloadPanel.js +10 -17
  19. package/dist/components/DownloadPanel.js.map +1 -1
  20. package/dist/components/ErrorBanner.d.ts +2 -2
  21. package/dist/components/ErrorBanner.d.ts.map +1 -1
  22. package/dist/components/ErrorBanner.js +3 -3
  23. package/dist/components/ErrorBanner.js.map +1 -1
  24. package/dist/components/ErrorBoundary.d.ts +40 -0
  25. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  26. package/dist/components/ErrorBoundary.js +52 -0
  27. package/dist/components/ErrorBoundary.js.map +1 -0
  28. package/dist/components/ExifPanel.d.ts +1 -1
  29. package/dist/components/ExifPanel.d.ts.map +1 -1
  30. package/dist/components/ExifPanel.js +2 -2
  31. package/dist/components/ExifPanel.js.map +1 -1
  32. package/dist/components/GlobalDropzone.d.ts +5 -5
  33. package/dist/components/GlobalDropzone.d.ts.map +1 -1
  34. package/dist/components/GlobalDropzone.js +15 -8
  35. package/dist/components/GlobalDropzone.js.map +1 -1
  36. package/dist/components/HistoryPanel.d.ts +2 -2
  37. package/dist/components/HistoryPanel.d.ts.map +1 -1
  38. package/dist/components/HistoryPanel.js +23 -23
  39. package/dist/components/HistoryPanel.js.map +1 -1
  40. package/dist/components/Inspector.d.ts.map +1 -1
  41. package/dist/components/Inspector.js +13 -10
  42. package/dist/components/Inspector.js.map +1 -1
  43. package/dist/components/ParamForm.d.ts.map +1 -1
  44. package/dist/components/ParamForm.js +10 -7
  45. package/dist/components/ParamForm.js.map +1 -1
  46. package/dist/components/PipelineBar.d.ts.map +1 -1
  47. package/dist/components/PipelineBar.js +19 -28
  48. package/dist/components/PipelineBar.js.map +1 -1
  49. package/dist/components/ProgressBar.d.ts +4 -4
  50. package/dist/components/ProgressBar.d.ts.map +1 -1
  51. package/dist/components/ProgressBar.js +8 -8
  52. package/dist/components/ProgressBar.js.map +1 -1
  53. package/dist/components/StatusBar.d.ts +3 -3
  54. package/dist/components/StatusBar.d.ts.map +1 -1
  55. package/dist/components/StatusBar.js +12 -21
  56. package/dist/components/StatusBar.js.map +1 -1
  57. package/dist/components/StatusDot.d.ts +12 -0
  58. package/dist/components/StatusDot.d.ts.map +1 -0
  59. package/dist/components/StatusDot.js +15 -0
  60. package/dist/components/StatusDot.js.map +1 -0
  61. package/dist/components/ThemeToggle.d.ts +4 -4
  62. package/dist/components/ThemeToggle.d.ts.map +1 -1
  63. package/dist/components/ThemeToggle.js +7 -7
  64. package/dist/components/ThemeToggle.js.map +1 -1
  65. package/dist/components/ToolRunner.d.ts +53 -0
  66. package/dist/components/ToolRunner.d.ts.map +1 -0
  67. package/dist/components/ToolRunner.js +142 -0
  68. package/dist/components/ToolRunner.js.map +1 -0
  69. package/dist/components/Toolbar.d.ts.map +1 -1
  70. package/dist/components/Toolbar.js +3 -3
  71. package/dist/components/Toolbar.js.map +1 -1
  72. package/dist/components/WorkflowEditor.d.ts +6 -6
  73. package/dist/components/WorkflowEditor.d.ts.map +1 -1
  74. package/dist/components/WorkflowEditor.js +40 -49
  75. package/dist/components/WorkflowEditor.js.map +1 -1
  76. package/dist/components/WorkflowTemplates.d.ts +2 -2
  77. package/dist/components/WorkflowTemplates.d.ts.map +1 -1
  78. package/dist/components/WorkflowTemplates.js +17 -7
  79. package/dist/components/WorkflowTemplates.js.map +1 -1
  80. package/dist/components/Workspace.d.ts +45 -23
  81. package/dist/components/Workspace.d.ts.map +1 -1
  82. package/dist/components/Workspace.js +87 -40
  83. package/dist/components/Workspace.js.map +1 -1
  84. package/dist/hooks/useCustomPresets.d.ts +98 -0
  85. package/dist/hooks/useCustomPresets.d.ts.map +1 -0
  86. package/dist/hooks/useCustomPresets.js +210 -0
  87. package/dist/hooks/useCustomPresets.js.map +1 -0
  88. package/dist/hooks/useLokvis.d.ts +19 -1
  89. package/dist/hooks/useLokvis.d.ts.map +1 -1
  90. package/dist/hooks/useLokvis.js +30 -9
  91. package/dist/hooks/useLokvis.js.map +1 -1
  92. package/dist/index.d.ts +4 -0
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +6 -0
  95. package/dist/index.js.map +1 -1
  96. package/dist/store/assets-slice.d.ts +8 -1
  97. package/dist/store/assets-slice.d.ts.map +1 -1
  98. package/dist/store/assets-slice.js +101 -54
  99. package/dist/store/assets-slice.js.map +1 -1
  100. package/dist/store/capabilities-slice.d.ts +1 -1
  101. package/dist/store/capabilities-slice.d.ts.map +1 -1
  102. package/dist/store/capabilities-slice.js +8 -1
  103. package/dist/store/capabilities-slice.js.map +1 -1
  104. package/dist/store/index.d.ts +1 -1
  105. package/dist/store/index.d.ts.map +1 -1
  106. package/dist/store/index.js +1 -1
  107. package/dist/store/index.js.map +1 -1
  108. package/dist/store/runtime-slice.d.ts.map +1 -1
  109. package/dist/store/runtime-slice.js +22 -16
  110. package/dist/store/runtime-slice.js.map +1 -1
  111. package/dist/store/subscribe-utils.d.ts +45 -0
  112. package/dist/store/subscribe-utils.d.ts.map +1 -0
  113. package/dist/store/subscribe-utils.js +69 -0
  114. package/dist/store/subscribe-utils.js.map +1 -0
  115. package/dist/store/types.d.ts +19 -11
  116. package/dist/store/types.d.ts.map +1 -1
  117. package/dist/store/types.js +0 -10
  118. package/dist/store/types.js.map +1 -1
  119. package/dist/store/workflow-slice.d.ts +1 -1
  120. package/dist/store/workflow-slice.d.ts.map +1 -1
  121. package/dist/store/workflow-slice.js +19 -51
  122. package/dist/store/workflow-slice.js.map +1 -1
  123. package/dist/utils.d.ts +24 -0
  124. package/dist/utils.d.ts.map +1 -0
  125. package/dist/utils.js +31 -0
  126. package/dist/utils.js.map +1 -0
  127. package/package.json +7 -6
  128. package/src/components/AssetPanel.tsx +224 -264
  129. package/src/components/Canvas.tsx +178 -174
  130. package/src/components/CommandPalette.tsx +242 -242
  131. package/src/components/CompareSlider.tsx +168 -165
  132. package/src/components/DownloadPanel.tsx +201 -207
  133. package/src/components/ErrorBanner.tsx +64 -64
  134. package/src/components/ErrorBoundary.tsx +101 -0
  135. package/src/components/ExifPanel.tsx +154 -154
  136. package/src/components/GlobalDropzone.tsx +175 -170
  137. package/src/components/HistoryPanel.tsx +219 -219
  138. package/src/components/Inspector.tsx +145 -137
  139. package/src/components/ParamForm.tsx +140 -137
  140. package/src/components/PipelineBar.tsx +97 -104
  141. package/src/components/ProgressBar.tsx +78 -78
  142. package/src/components/StatusBar.tsx +145 -152
  143. package/src/components/StatusDot.tsx +27 -0
  144. package/src/components/ThemeToggle.tsx +98 -98
  145. package/src/components/ToolRunner.tsx +352 -0
  146. package/src/components/Toolbar.tsx +65 -65
  147. package/src/components/WorkflowEditor.tsx +333 -326
  148. package/src/components/WorkflowTemplates.tsx +101 -78
  149. package/src/components/Workspace.tsx +310 -223
  150. package/src/css-modules.d.ts +3 -0
  151. package/src/hooks/useCustomPresets.ts +284 -0
  152. package/src/hooks/useLokvis.ts +43 -10
  153. package/src/index.ts +7 -0
  154. package/src/store/assets-slice.ts +106 -52
  155. package/src/store/capabilities-slice.ts +10 -2
  156. package/src/store/index.ts +1 -1
  157. package/src/store/runtime-slice.ts +20 -15
  158. package/src/store/subscribe-utils.ts +82 -0
  159. package/src/store/types.ts +19 -12
  160. package/src/store/workflow-slice.ts +19 -53
  161. package/src/utils.ts +41 -0
  162. package/dist/store.d.ts +0 -76
  163. package/dist/store.d.ts.map +0 -1
  164. package/dist/store.js +0 -217
  165. package/dist/store.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusDot.js","sourceRoot":"","sources":["../../src/components/StatusDot.tsx"],"names":[],"mappings":";AAWA,MAAM,UAAU,SAAS,CAAC,EAAE,MAAM,EAAkB;IAClD,MAAM,KAAK,GACT,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,4BAA4B;QAC9B,CAAC,CAAC,MAAM,KAAK,SAAS;YACtB,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,MAAM,KAAK,QAAQ;gBACrB,CAAC,CAAC,2BAA2B;gBAC7B,CAAC,CAAC,MAAM,KAAK,SAAS;oBACtB,CAAC,CAAC,8BAA8B;oBAChC,CAAC,CAAC,8BAA8B,CAAC;IAErC,MAAM,OAAO,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5D,OAAO,eAAM,SAAS,EAAE,qCAAqC,KAAK,IAAI,OAAO,EAAE,GAAI,CAAC;AACtF,CAAC"}
@@ -5,10 +5,10 @@
5
5
  * 与 `tokens.css` 的 `.dark` / `.light` 类双触发机制对齐。
6
6
  *
7
7
  * 交互:
8
- * - 左键单击:在 light / dark 之间切换(基于当前 resolvedTheme 决定下一态)
9
- * - 右键单击:弹出菜单(light / dark / system 三态)
10
- * - ESC:关闭菜单
11
- * - 点击菜单外部:关闭菜单
8
+ * - 左键单击:在 light / dark 之间切换(基于当前 resolvedTheme 决定下一态)
9
+ * - 右键单击:弹出菜单(light / dark / system 三态)
10
+ * - ESC:关闭菜单
11
+ * - 点击菜单外部:关闭菜单
12
12
  */
13
13
  import * as React from 'react';
14
14
  export interface ThemeToggleProps {
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../src/components/ThemeToggle.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAAE,SAAc,EAAE,SAAiB,EAAE,EAAE,gBAAgB,qBAkGlF"}
1
+ {"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../src/components/ThemeToggle.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,gBAAgB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,SAAc,EAAE,SAAiB,EAAE,EAAE,gBAAgB,qBAkGlF"}
@@ -6,10 +6,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  * 与 `tokens.css` 的 `.dark` / `.light` 类双触发机制对齐。
7
7
  *
8
8
  * 交互:
9
- * - 左键单击:在 light / dark 之间切换(基于当前 resolvedTheme 决定下一态)
10
- * - 右键单击:弹出菜单(light / dark / system 三态)
11
- * - ESC:关闭菜单
12
- * - 点击菜单外部:关闭菜单
9
+ * - 左键单击:在 light / dark 之间切换(基于当前 resolvedTheme 决定下一态)
10
+ * - 右键单击:弹出菜单(light / dark / system 三态)
11
+ * - ESC:关闭菜单
12
+ * - 点击菜单外部:关闭菜单
13
13
  */
14
14
  import * as React from 'react';
15
15
  import { Icon } from '@lokvis/ui-core';
@@ -46,15 +46,15 @@ export function ThemeToggle({ className = '', showLabel = false }) {
46
46
  return (_jsxs("div", { className: `relative ${className}`, children: [_jsxs("button", { ref: btnRef, type: "button", "aria-haspopup": "menu", "aria-expanded": menuOpen, onClick: () => toggleTheme(), onContextMenu: (e) => {
47
47
  e.preventDefault();
48
48
  setMenuOpen((v) => !v);
49
- }, "aria-label": `Theme: ${label}. Click to toggle, right-click for options.`, title: `Theme: ${label} (right-click for options)`, className: "flex h-8 w-8 items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800 dark:hover:text-zinc-200", children: [icon, showLabel && _jsx("span", { className: "ml-1 text-xs", children: label })] }), menuOpen && (_jsx("div", { role: "menu", className: "absolute right-0 top-full z-50 mt-1 w-32 overflow-hidden rounded-md border border-zinc-200 bg-white py-1 shadow-lg dark:border-zinc-800 dark:bg-zinc-900", children: ['light', 'dark', null].map((mode) => {
49
+ }, "aria-label": `Theme: ${label}. Click to toggle, right-click for options.`, title: `Theme: ${label} (right-click for options)`, className: "flex h-8 w-8 items-center justify-center rounded-md text-[var(--lokvis-fg-muted)] transition-colors hover:bg-[var(--lokvis-surface-muted)] hover:text-[var(--lokvis-fg-muted)]", children: [icon, showLabel && _jsx("span", { className: "ml-1 text-xs", children: label })] }), menuOpen && (_jsx("div", { role: "menu", className: "absolute right-0 top-full z-50 mt-1 w-32 overflow-hidden rounded-md border border-[var(--lokvis-border)] bg-[var(--lokvis-surface)] py-1 shadow-[var(--lokvis-elevation-2)]", children: ['light', 'dark', null].map((mode) => {
50
50
  const isActive = theme === mode;
51
51
  const text = mode === null ? 'System' : mode === 'dark' ? 'Dark' : 'Light';
52
52
  return (_jsxs("button", { type: "button", role: "menuitemradio", "aria-checked": isActive, onClick: () => {
53
53
  setTheme(mode);
54
54
  setMenuOpen(false);
55
55
  }, className: `flex w-full items-center justify-between px-3 py-1.5 text-left text-xs transition-colors ${isActive
56
- ? 'bg-indigo-50 text-indigo-700 dark:bg-indigo-950/30 dark:text-indigo-300'
57
- : 'text-zinc-700 hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800'}`, children: [_jsx("span", { children: text }), isActive && (_jsx(Icon, { size: 12, strokeWidth: 3, children: _jsx("path", { d: "M5 13l4 4L19 7" }) }))] }, mode ?? 'system'));
56
+ ? 'bg-[var(--lokvis-primary)]/10 text-[var(--lokvis-primary)]'
57
+ : 'text-[var(--lokvis-fg-muted)] hover:bg-[var(--lokvis-surface-muted)]'}`, children: [_jsx("span", { children: text }), isActive && (_jsx(Icon, { size: 12, strokeWidth: 3, children: _jsx("path", { d: "M5 13l4 4L19 7" }) }))] }, mode ?? 'system'));
58
58
  }) }))] }));
59
59
  }
60
60
  //# sourceMappingURL=ThemeToggle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeToggle.js","sourceRoot":"","sources":["../../src/components/ThemeToggle.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ThemeToggle.js","sourceRoot":"","sources":["../../src/components/ThemeToggle.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * ToolRunner - 单工具页组合组件
3
+ *
4
+ * 为单工具操作场景(压缩、裁剪、格式转换等)提供一站式 UI:
5
+ * 上传 → 调参 → 处理 → 对比 → 下载。
6
+ *
7
+ * 不依赖 Workspace Store(zustand),通过 engine prop 注入处理函数,
8
+ * 可在任何 React 应用中独立使用。
9
+ *
10
+ * 五层架构:UI 层不直接依赖 Engine 层,engine 函数由消费方传入。
11
+ * 消费方需自行实现按 capability.name 路由到对应 Blob↔Blob 操作的 wrapper
12
+ * (engine-image 已不再提供 runTool 统一入口,各 operation 需直接组合调用)。
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * import { ToolRunner } from '@lokvis/ui-react';
17
+ * import { IMAGE_COMPRESS, compress } from '@lokvis/engine-image';
18
+ *
19
+ * <ToolRunner
20
+ * capability={IMAGE_COMPRESS}
21
+ * engine={(name, input, params, opts) => compress(input, params, opts?.signal)}
22
+ * onOpenInWorkspace={(state) => { ... }}
23
+ * />
24
+ * ```
25
+ */
26
+ import * as React from 'react';
27
+ import type { Capability } from '@lokvis/schema';
28
+ type EngineFn = (toolName: string, input: Blob, params: Record<string, unknown>, options?: {
29
+ signal?: AbortSignal;
30
+ onProgress?: (p: number) => void;
31
+ }) => Promise<Blob>;
32
+ export interface ToolRunnerProps {
33
+ /** 工具能力定义(决定参数表单和输入类型) */
34
+ capability: Capability;
35
+ /** 处理函数(按 capability.name 路由到对应 Blob↔Blob 操作的 wrapper) */
36
+ engine: EngineFn;
37
+ /** 在 Workspace 中打开的回调(携带当前状态) */
38
+ onOpenInWorkspace?: (state: {
39
+ inputBlob: Blob;
40
+ outputBlob: Blob | null;
41
+ params: Record<string, unknown>;
42
+ }) => void;
43
+ className?: string;
44
+ }
45
+ /**
46
+ * ToolRunner - 单工具操作组件。
47
+ *
48
+ * 内部组合:上传区 + 参数表单 + 预览/对比 + 进度 + 下载。
49
+ * 所有状态自管理,不依赖外部 store。
50
+ */
51
+ export declare function ToolRunner({ capability, engine, onOpenInWorkspace, className, }: ToolRunnerProps): React.JSX.Element;
52
+ export {};
53
+ //# sourceMappingURL=ToolRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolRunner.d.ts","sourceRoot":"","sources":["../../src/components/ToolRunner.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjD,KAAK,QAAQ,GAAG,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,KAChE,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,WAAW,eAAe;IAC/B,0BAA0B;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,0DAA0D;IACzD,MAAM,EAAE,QAAQ,CAAC;IAClB,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;QAC3B,SAAS,EAAE,IAAI,CAAC;QAChB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAChC,KAAK,IAAI,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAC1B,UAAU,EACV,MAAM,EACN,iBAAiB,EACjB,SAAc,GACd,EAAE,eAAe,qBAgSjB"}
@@ -0,0 +1,142 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ToolRunner - 单工具页组合组件
4
+ *
5
+ * 为单工具操作场景(压缩、裁剪、格式转换等)提供一站式 UI:
6
+ * 上传 → 调参 → 处理 → 对比 → 下载。
7
+ *
8
+ * 不依赖 Workspace Store(zustand),通过 engine prop 注入处理函数,
9
+ * 可在任何 React 应用中独立使用。
10
+ *
11
+ * 五层架构:UI 层不直接依赖 Engine 层,engine 函数由消费方传入。
12
+ * 消费方需自行实现按 capability.name 路由到对应 Blob↔Blob 操作的 wrapper
13
+ * (engine-image 已不再提供 runTool 统一入口,各 operation 需直接组合调用)。
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * import { ToolRunner } from '@lokvis/ui-react';
18
+ * import { IMAGE_COMPRESS, compress } from '@lokvis/engine-image';
19
+ *
20
+ * <ToolRunner
21
+ * capability={IMAGE_COMPRESS}
22
+ * engine={(name, input, params, opts) => compress(input, params, opts?.signal)}
23
+ * onOpenInWorkspace={(state) => { ... }}
24
+ * />
25
+ * ```
26
+ */
27
+ import * as React from 'react';
28
+ import { Button, Card } from '@lokvis/ui-core';
29
+ import { ParamForm } from './ParamForm.js';
30
+ /**
31
+ * ToolRunner - 单工具操作组件。
32
+ *
33
+ * 内部组合:上传区 + 参数表单 + 预览/对比 + 进度 + 下载。
34
+ * 所有状态自管理,不依赖外部 store。
35
+ */
36
+ export function ToolRunner({ capability, engine, onOpenInWorkspace, className = '', }) {
37
+ const [inputBlob, setInputBlob] = React.useState(null);
38
+ const [inputUrl, setInputUrl] = React.useState(null);
39
+ const [outputBlob, setOutputBlob] = React.useState(null);
40
+ const [outputUrl, setOutputUrl] = React.useState(null);
41
+ const [params, setParams] = React.useState(() => {
42
+ const defaults = {};
43
+ for (const p of capability.params) {
44
+ if (p.default !== undefined)
45
+ defaults[p.name] = p.default;
46
+ }
47
+ return defaults;
48
+ });
49
+ const [progress, setProgress] = React.useState(0);
50
+ const [processing, setProcessing] = React.useState(false);
51
+ const [error, setError] = React.useState(null);
52
+ const [dragging, setDragging] = React.useState(false);
53
+ const abortRef = React.useRef(null);
54
+ // 清理 ObjectURL
55
+ React.useEffect(() => {
56
+ return () => {
57
+ if (inputUrl)
58
+ URL.revokeObjectURL(inputUrl);
59
+ if (outputUrl)
60
+ URL.revokeObjectURL(outputUrl);
61
+ };
62
+ }, [inputUrl, outputUrl]);
63
+ // W21.6: unmount 时 abort 进行中的处理,防止后台泄漏
64
+ // (engine 函数持有 Worker/Canvas 资源,卸载后继续运行是浪费 + 潜在内存泄漏)
65
+ React.useEffect(() => {
66
+ return () => {
67
+ if (abortRef.current) {
68
+ abortRef.current.abort();
69
+ abortRef.current = null;
70
+ }
71
+ };
72
+ }, []);
73
+ const accept = capability.inputTypes.join(',');
74
+ function handleFiles(files) {
75
+ if (!files || files.length === 0)
76
+ return;
77
+ const file = files[0];
78
+ if (!file)
79
+ return;
80
+ setInputBlob(file);
81
+ if (inputUrl)
82
+ URL.revokeObjectURL(inputUrl);
83
+ setInputUrl(URL.createObjectURL(file));
84
+ // 重置输出
85
+ setOutputBlob(null);
86
+ if (outputUrl) {
87
+ URL.revokeObjectURL(outputUrl);
88
+ setOutputUrl(null);
89
+ }
90
+ }
91
+ async function handleProcess() {
92
+ if (!inputBlob)
93
+ return;
94
+ setProcessing(true);
95
+ setProgress(0);
96
+ setError(null);
97
+ abortRef.current = new AbortController();
98
+ try {
99
+ const result = await engine(capability.name, inputBlob, params, {
100
+ signal: abortRef.current.signal,
101
+ onProgress: setProgress,
102
+ });
103
+ setOutputBlob(result);
104
+ if (outputUrl)
105
+ URL.revokeObjectURL(outputUrl);
106
+ setOutputUrl(URL.createObjectURL(result));
107
+ }
108
+ catch (err) {
109
+ if (err instanceof Error && err.name === 'AbortError')
110
+ return;
111
+ setError(err instanceof Error ? err.message : String(err));
112
+ }
113
+ finally {
114
+ setProcessing(false);
115
+ abortRef.current = null;
116
+ }
117
+ }
118
+ function handleCancel() {
119
+ abortRef.current?.abort();
120
+ }
121
+ const downloadName = outputBlob
122
+ ? `output.${outputBlob.type.split('/')[1] ?? 'bin'}`
123
+ : 'output';
124
+ return (_jsxs("div", { className: `flex flex-col gap-6 ${className}`, children: [!inputBlob && (_jsxs("label", { className: `block cursor-pointer rounded-xl border-2 border-dashed p-10 text-center transition-all ${dragging
125
+ ? 'border-[var(--lokvis-primary)] bg-[var(--lokvis-primary)]/10'
126
+ : 'border-[var(--lokvis-border)] hover:border-[var(--lokvis-primary)]/50 hover:bg-[var(--lokvis-surface-muted)]'}`, onDragOver: (e) => { e.preventDefault(); setDragging(true); }, onDragLeave: () => setDragging(false), onDrop: (e) => {
127
+ e.preventDefault();
128
+ setDragging(false);
129
+ handleFiles(e.dataTransfer.files);
130
+ }, children: [_jsx("input", { type: "file", accept: accept, className: "hidden", onChange: (e) => handleFiles(e.target.files) }), _jsxs("div", { className: "flex flex-col items-center gap-3", children: [_jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-xl bg-[var(--lokvis-surface-muted)]", children: _jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-[var(--lokvis-fg-subtle)]", children: [_jsx("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" }), _jsx("polyline", { points: "17 8 12 3 7 8" }), _jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })] }) }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-[var(--lokvis-fg)]", children: "Drop file here or click to upload" }), _jsxs("p", { className: "mt-1 text-xs text-[var(--lokvis-fg-subtle)]", children: ["Accepted: ", accept || 'any file'] })] })] })] })), inputBlob && (_jsxs("div", { className: "grid gap-6 md:grid-cols-2", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs(Card, { children: [_jsxs("div", { className: "mb-3 flex items-center justify-between", children: [_jsx("h3", { className: "text-sm font-semibold text-[var(--lokvis-fg)]", children: "Parameters" }), _jsx("span", { className: "rounded bg-[var(--lokvis-surface-muted)] px-2 py-0.5 font-mono text-xs text-[var(--lokvis-primary)]", children: capability.name })] }), _jsx(ParamForm, { capability: capability, values: params, onChange: setParams })] }), _jsxs("div", { className: "flex gap-3", children: [_jsx(Button, { variant: "primary", size: "md", onClick: handleProcess, loading: processing, disabled: !inputBlob, children: processing ? 'Processing...' : 'Process' }), _jsx(Button, { variant: "secondary", size: "md", onClick: () => {
131
+ setInputBlob(null);
132
+ if (inputUrl)
133
+ URL.revokeObjectURL(inputUrl);
134
+ setInputUrl(null);
135
+ setOutputBlob(null);
136
+ if (outputUrl) {
137
+ URL.revokeObjectURL(outputUrl);
138
+ setOutputUrl(null);
139
+ }
140
+ }, children: "Change file" }), onOpenInWorkspace && (_jsx(Button, { variant: "ghost", size: "md", onClick: () => onOpenInWorkspace({ inputBlob, outputBlob, params }), children: "Open in Workspace \u2192" }))] }), processing && (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between text-xs text-[var(--lokvis-fg-muted)]", children: [_jsx("span", { children: "Processing..." }), _jsxs("span", { className: "tabular-nums", children: [Math.round(progress), "%"] })] }), _jsx("div", { className: "h-1.5 overflow-hidden rounded-full bg-[var(--lokvis-border)]", children: _jsx("div", { className: "h-full rounded-full bg-[var(--lokvis-primary)] transition-all duration-200", style: { width: `${progress}%` } }) }), _jsx("button", { type: "button", onClick: handleCancel, className: "text-xs text-[var(--lokvis-danger)] hover:underline", children: "Cancel" })] })), error && (_jsx("div", { className: "rounded-lg border border-[var(--lokvis-danger)]/30 bg-[var(--lokvis-danger)]/10 px-4 py-3 text-sm text-[var(--lokvis-danger)]", children: error })), outputBlob && outputUrl && (_jsx(Card, { children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-[var(--lokvis-fg)]", children: "Ready to download" }), _jsxs("p", { className: "mt-1 text-xs text-[var(--lokvis-fg-muted)]", children: [(outputBlob.size / 1024).toFixed(1), " KB \u00B7 ", outputBlob.type.split('/')[1] ?? 'file'] })] }), _jsxs("a", { href: outputUrl, download: downloadName, className: "inline-flex items-center gap-1.5 rounded-lg bg-[var(--lokvis-primary)] px-4 py-2 text-sm font-medium text-[var(--lokvis-primary-fg)] transition-colors hover:bg-[var(--lokvis-primary-hover)]", children: [_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" }), _jsx("polyline", { points: "7 10 12 15 17 10" }), _jsx("line", { x1: "12", y1: "15", x2: "12", y2: "3" })] }), "Download"] })] }) }))] }), _jsxs("div", { className: "space-y-4", children: [inputUrl && (_jsxs(Card, { children: [_jsx("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wider text-[var(--lokvis-fg-subtle)]", children: "Input" }), _jsx("img", { src: inputUrl, alt: "Input preview", className: "max-h-80 w-full rounded-lg object-contain" }), _jsxs("p", { className: "mt-2 text-xs text-[var(--lokvis-fg-muted)]", children: [(inputBlob.size / 1024).toFixed(1), " KB \u00B7 ", inputBlob.type.split('/')[1] ?? 'file'] })] })), outputUrl && (_jsxs(Card, { children: [_jsx("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wider text-[var(--lokvis-fg-subtle)]", children: "Output" }), _jsx("img", { src: outputUrl, alt: "Output preview", className: "max-h-80 w-full rounded-lg object-contain" }), _jsxs("p", { className: "mt-2 text-xs text-[var(--lokvis-fg-muted)]", children: [(outputBlob.size / 1024).toFixed(1), " KB \u00B7 ", outputBlob.type.split('/')[1] ?? 'file'] })] }))] })] }))] }));
141
+ }
142
+ //# sourceMappingURL=ToolRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolRunner.js","sourceRoot":"","sources":["../../src/components/ToolRunner.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAuB3C;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAC1B,UAAU,EACV,MAAM,EACN,iBAAiB,EACjB,SAAS,GAAG,EAAE,GACG;IACjB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAc,IAAI,CAAC,CAAC;IACpE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACpE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAc,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAA0B,GAAG,EAAE;QACxE,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;gBAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;QAC3D,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAC9D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAyB,IAAI,CAAC,CAAC;IAE5D,eAAe;IACf,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,OAAO,GAAG,EAAE;YACX,IAAI,QAAQ;gBAAE,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,SAAS;gBAAE,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IAE1B,uCAAuC;IACvC,qDAAqD;IACrD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,OAAO,GAAG,EAAE;YACX,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACzB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;YACzB,CAAC;QACF,CAAC,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/C,SAAS,WAAW,CAAC,KAA+B;QACnD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,IAAI,QAAQ;YAAE,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC5C,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QAEvC,OAAO;QACP,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,IAAI,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAC/B,YAAY,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAED,KAAK,UAAU,aAAa;QAC3B,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,WAAW,CAAC,CAAC,CAAC,CAAC;QACf,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,QAAQ,CAAC,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE;gBAC/D,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM;gBAC/B,UAAU,EAAE,WAAW;aACvB,CAAC,CAAC;YACH,aAAa,CAAC,MAAM,CAAC,CAAC;YACtB,IAAI,SAAS;gBAAE,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAC9C,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;gBAAE,OAAO;YAC9D,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5D,CAAC;gBAAS,CAAC;YACV,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,CAAC;IACF,CAAC;IAED,SAAS,YAAY;QACpB,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,YAAY,GAAG,UAAU;QAC9B,CAAC,CAAC,UAAU,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE;QACpD,CAAC,CAAC,QAAQ,CAAC;IAEZ,OAAO,CACN,eAAK,SAAS,EAAE,uBAAuB,SAAS,EAAE,aAEhD,CAAC,SAAS,IAAI,CACd,iBACC,SAAS,EAAE,0FACV,QAAQ;oBACP,CAAC,CAAC,8DAA8D;oBAChE,CAAC,CAAC,8GACJ,EAAE,EACF,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAC7D,WAAW,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,EACrC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;oBACb,CAAC,CAAC,cAAc,EAAE,CAAC;oBACnB,WAAW,CAAC,KAAK,CAAC,CAAC;oBACnB,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBACnC,CAAC,aAED,gBACC,IAAI,EAAC,MAAM,EACX,MAAM,EAAE,MAAM,EACd,SAAS,EAAC,QAAQ,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAC3C,EACF,eAAK,SAAS,EAAC,kCAAkC,aAChD,cAAK,SAAS,EAAC,wFAAwF,YACtG,eAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,EAAC,SAAS,EAAC,gCAAgC,aACxL,eAAM,CAAC,EAAC,yCAAyC,GAAG,EACpD,mBAAU,MAAM,EAAC,eAAe,GAAG,EACnC,eAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,GAAG,IAClC,GACD,EACN,0BACC,YAAG,SAAS,EAAC,6CAA6C,kDAEtD,EACJ,aAAG,SAAS,EAAC,6CAA6C,2BAC9C,MAAM,IAAI,UAAU,IAC5B,IACC,IACD,IACC,CACR,EAGA,SAAS,IAAI,CACb,eAAK,SAAS,EAAC,2BAA2B,aAEzC,eAAK,SAAS,EAAC,WAAW,aACzB,MAAC,IAAI,eACJ,eAAK,SAAS,EAAC,wCAAwC,aACtD,aAAI,SAAS,EAAC,+CAA+C,2BAExD,EACL,eAAM,SAAS,EAAC,qGAAqG,YACnH,UAAU,CAAC,IAAI,GACV,IACF,EACN,KAAC,SAAS,IACT,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,GAClB,IACI,EAGP,eAAK,SAAS,EAAC,YAAY,aAC1B,KAAC,MAAM,IACN,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,CAAC,SAAS,YAEnB,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,GACjC,EACT,KAAC,MAAM,IACN,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE;4CACb,YAAY,CAAC,IAAI,CAAC,CAAC;4CACnB,IAAI,QAAQ;gDAAE,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;4CAC5C,WAAW,CAAC,IAAI,CAAC,CAAC;4CAClB,aAAa,CAAC,IAAI,CAAC,CAAC;4CACpB,IAAI,SAAS,EAAE,CAAC;gDACf,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;gDAC/B,YAAY,CAAC,IAAI,CAAC,CAAC;4CACpB,CAAC;wCACF,CAAC,4BAGO,EACR,iBAAiB,IAAI,CACrB,KAAC,MAAM,IACN,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,yCAG3D,CACT,IACI,EAGL,UAAU,IAAI,CACd,eAAK,SAAS,EAAC,WAAW,aACzB,eAAK,SAAS,EAAC,yEAAyE,aACvF,2CAA0B,EAC1B,gBAAM,SAAS,EAAC,cAAc,aAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,IACxD,EACN,cAAK,SAAS,EAAC,8DAA8D,YAC5E,cACC,SAAS,EAAC,4EAA4E,EACtF,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,QAAQ,GAAG,EAAE,GAC/B,GACG,EACN,iBACC,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,YAAY,EACrB,SAAS,EAAC,qDAAqD,uBAGvD,IACJ,CACN,EAGA,KAAK,IAAI,CACT,cAAK,SAAS,EAAC,+HAA+H,YAC5I,KAAK,GACD,CACN,EAGA,UAAU,IAAI,SAAS,IAAI,CAC3B,KAAC,IAAI,cACJ,eAAK,SAAS,EAAC,mCAAmC,aACjD,0BACC,YAAG,SAAS,EAAC,6CAA6C,kCAAsB,EAChF,aAAG,SAAS,EAAC,4CAA4C,aACvD,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAQ,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,IAChF,IACC,EACN,aACC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAC,+LAA+L,aAEzM,eAAK,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,aAC7I,eAAM,CAAC,EAAC,yCAAyC,GAAG,EACpD,mBAAU,MAAM,EAAC,kBAAkB,GAAG,EACtC,eAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,GAAG,IAClC,gBAEH,IACC,GACA,CACP,IACI,EAGN,eAAK,SAAS,EAAC,WAAW,aAExB,QAAQ,IAAI,CACZ,MAAC,IAAI,eACJ,aAAI,SAAS,EAAC,oFAAoF,sBAE7F,EACL,cACC,GAAG,EAAE,QAAQ,EACb,GAAG,EAAC,eAAe,EACnB,SAAS,EAAC,2CAA2C,GACpD,EACF,aAAG,SAAS,EAAC,4CAA4C,aACvD,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAQ,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,IAC9E,IACE,CACP,EAGA,SAAS,IAAI,CACb,MAAC,IAAI,eACJ,aAAI,SAAS,EAAC,oFAAoF,uBAE7F,EACL,cACC,GAAG,EAAE,SAAS,EACd,GAAG,EAAC,gBAAgB,EACpB,SAAS,EAAC,2CAA2C,GACpD,EACF,aAAG,SAAS,EAAC,4CAA4C,aACvD,CAAC,UAAW,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAQ,UAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,IAClF,IACE,CACP,IACI,IACD,CACN,IACI,CACN,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,OAAO,CAAC,EAAE,KAA0B,EAAE,UAAU,EAAE,EAAE,YAAY,qBAqE/E"}
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,YAAY;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED,wBAAgB,OAAO,CAAC,EAAE,KAA0B,EAAE,UAAU,EAAE,EAAE,YAAY,qBAqE/E"}
@@ -27,10 +27,10 @@ export function Toolbar({ title = 'Lokvis Workspace', rightExtra }) {
27
27
  setError(err instanceof Error ? err.message : String(err));
28
28
  }
29
29
  }
30
- return (_jsxs("header", { className: "flex h-12 shrink-0 items-center justify-between border-b border-zinc-200 bg-white px-4 dark:border-zinc-800 dark:bg-zinc-900", children: [_jsxs("div", { className: "flex items-center gap-2.5 min-w-0", children: [_jsx("span", { className: "shrink-0 text-base font-bold leading-none", style: {
31
- background: 'linear-gradient(135deg, #6366f1, #a855f7)',
30
+ return (_jsxs("header", { className: "flex h-[var(--lokvis-toolbar-h)] shrink-0 items-center justify-between border-b border-[var(--lokvis-border)] bg-[var(--lokvis-surface)] px-4", children: [_jsxs("div", { className: "flex items-center gap-2.5 min-w-0", children: [_jsx("span", { className: "shrink-0 text-base font-bold leading-none", style: {
31
+ background: 'linear-gradient(135deg, var(--lokvis-primary), var(--lokvis-info))',
32
32
  WebkitBackgroundClip: 'text',
33
33
  WebkitTextFillColor: 'transparent',
34
- }, children: "\u25C6" }), _jsx("span", { className: "truncate text-sm font-semibold tracking-tight", children: title })] }), _jsx("div", { className: "flex flex-1 items-center justify-center px-4 min-w-0", children: _jsx("span", { className: `truncate text-xs ${error ? 'text-red-500' : 'text-zinc-400'}`, children: statusMessage }) }), _jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [rightExtra, nodes.length > 0 && (_jsx(Button, { variant: "ghost", size: "sm", onClick: clearWorkflow, disabled: running, children: "Clear" })), _jsx(Button, { variant: "primary", size: "sm", onClick: handleRun, loading: running, disabled: !canRun, children: "Run" })] })] }));
34
+ }, children: "\u25C6" }), _jsx("span", { className: "truncate text-sm font-semibold tracking-tight", children: title })] }), _jsx("div", { className: "flex flex-1 items-center justify-center px-4 min-w-0", children: _jsx("span", { className: `truncate text-xs ${error ? 'text-[var(--lokvis-danger)]' : 'text-[var(--lokvis-fg-subtle)]'}`, children: statusMessage }) }), _jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [rightExtra, nodes.length > 0 && (_jsx(Button, { variant: "ghost", size: "sm", onClick: clearWorkflow, disabled: running, children: "Clear" })), _jsx(Button, { variant: "primary", size: "sm", onClick: handleRun, loading: running, disabled: !canRun, children: "Run" })] })] }));
35
35
  }
36
36
  //# sourceMappingURL=Toolbar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.js","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOtD,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,GAAG,kBAAkB,EAAE,UAAU,EAAgB;IAC9E,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC;IAEjE,KAAK,UAAU,SAAS;QACtB,IAAI,CAAC;YACH,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,CACL,kBAAQ,SAAS,EAAC,8HAA8H,aAE9I,eAAK,SAAS,EAAC,mCAAmC,aAChD,eACE,SAAS,EAAC,2CAA2C,EACrD,KAAK,EAAE;4BACL,UAAU,EAAE,2CAA2C;4BACvD,oBAAoB,EAAE,MAAM;4BAC5B,mBAAmB,EAAE,aAAa;yBACnC,uBAGI,EACP,eAAM,SAAS,EAAC,+CAA+C,YAAE,KAAK,GAAQ,IAC1E,EAGN,cAAK,SAAS,EAAC,sDAAsD,YACnE,eAAM,SAAS,EAAE,oBAAoB,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,EAAE,YAC5E,aAAa,GACT,GACH,EAGN,eAAK,SAAS,EAAC,oCAAoC,aAChD,UAAU,EACV,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CACnB,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,OAAO,sBAGV,CACV,EACD,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,MAAM,oBAGV,IACL,IACC,CACV,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Toolbar.js","sourceRoot":"","sources":["../../src/components/Toolbar.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOtD,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,GAAG,kBAAkB,EAAE,UAAU,EAAgB;IAC/E,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC;IAEjE,KAAK,UAAU,SAAS;QACxB,IAAI,CAAC;YACL,MAAM,GAAG,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACf,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;IACD,CAAC;IAED,OAAO,CACP,kBAAQ,SAAS,EAAC,+IAA+I,aAEjK,eAAK,SAAS,EAAC,mCAAmC,aAClD,eACA,SAAS,EAAC,2CAA2C,EACrD,KAAK,EAAE;4BACP,UAAU,EAAE,oEAAoE;4BAChF,oBAAoB,EAAE,MAAM;4BAC5B,mBAAmB,EAAE,aAAa;yBACjC,uBAGM,EACP,eAAM,SAAS,EAAC,+CAA+C,YAAE,KAAK,GAAQ,IACxE,EAGN,cAAK,SAAS,EAAC,sDAAsD,YACrE,eAAM,SAAS,EAAE,oBAAoB,KAAK,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,gCAAgC,EAAE,YAC9G,aAAa,GACP,GACD,EAGN,eAAK,SAAS,EAAC,oCAAoC,aAClD,UAAU,EACV,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CACrB,KAAC,MAAM,IACP,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,OAAO,sBAGR,CACR,EACD,KAAC,MAAM,IACP,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,MAAM,oBAGR,IACH,IACG,CACR,CAAC;AACH,CAAC"}
@@ -2,14 +2,14 @@
2
2
  * WorkflowEditor - 拖拽式工作流编辑器(W10.4)
3
3
  *
4
4
  * 增强 PipelineBar,提供节点拖拽重排能力:
5
- * - 拖拽节点到任意位置重排线性链
6
- * - 拖拽时显示插入指示器
7
- * - 键盘支持:选中节点后 ← → 移动(无障碍)
8
- * - 节点数上限 MAX_WORKFLOW_STEPS=5(M1 MVP 约束,UI 层常量)
5
+ * - 拖拽节点到任意位置重排线性链
6
+ * - 拖拽时显示插入指示器
7
+ * - 键盘支持:选中节点后 ← → 移动(无障碍)
8
+ * - 节点数上限 MAX_WORKFLOW_STEPS=5(M1 MVP 约束,UI 层常量)
9
9
  *
10
10
  * 与 PipelineBar 区别:
11
- * - PipelineBar:只读 + 选中/删除(快速预览)
12
- * - WorkflowEditor:可编辑 + 拖拽重排(编辑模式)
11
+ * - PipelineBar:只读 + 选中/删除(快速预览)
12
+ * - WorkflowEditor:可编辑 + 拖拽重排(编辑模式)
13
13
  *
14
14
  * 使用原生 HTML5 Drag and Drop API,无额外依赖。
15
15
  * 触摸设备降级为按钮上下移动(HTML5 DnD 在移动端支持不佳)。
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowEditor.d.ts","sourceRoot":"","sources":["../../src/components/WorkflowEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAc,EAAE,EAAE,mBAAmB,qBAsNrE"}
1
+ {"version":3,"file":"WorkflowEditor.d.ts","sourceRoot":"","sources":["../../src/components/WorkflowEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,MAAM,WAAW,mBAAmB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAc,EAAE,EAAE,mBAAmB,qBAmOrE"}
@@ -3,14 +3,14 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  * WorkflowEditor - 拖拽式工作流编辑器(W10.4)
4
4
  *
5
5
  * 增强 PipelineBar,提供节点拖拽重排能力:
6
- * - 拖拽节点到任意位置重排线性链
7
- * - 拖拽时显示插入指示器
8
- * - 键盘支持:选中节点后 ← → 移动(无障碍)
9
- * - 节点数上限 MAX_WORKFLOW_STEPS=5(M1 MVP 约束,UI 层常量)
6
+ * - 拖拽节点到任意位置重排线性链
7
+ * - 拖拽时显示插入指示器
8
+ * - 键盘支持:选中节点后 ← → 移动(无障碍)
9
+ * - 节点数上限 MAX_WORKFLOW_STEPS=5(M1 MVP 约束,UI 层常量)
10
10
  *
11
11
  * 与 PipelineBar 区别:
12
- * - PipelineBar:只读 + 选中/删除(快速预览)
13
- * - WorkflowEditor:可编辑 + 拖拽重排(编辑模式)
12
+ * - PipelineBar:只读 + 选中/删除(快速预览)
13
+ * - WorkflowEditor:可编辑 + 拖拽重排(编辑模式)
14
14
  *
15
15
  * 使用原生 HTML5 Drag and Drop API,无额外依赖。
16
16
  * 触摸设备降级为按钮上下移动(HTML5 DnD 在移动端支持不佳)。
@@ -18,8 +18,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
18
18
  * @module WorkflowEditor
19
19
  */
20
20
  import * as React from 'react';
21
- import { Icon } from '@lokvis/ui-core';
21
+ import { ConfirmDialog, Icon, Input } from '@lokvis/ui-core';
22
22
  import { useWorkspaceStore, MAX_WORKFLOW_STEPS } from '../store/index.js';
23
+ import { filterCapabilities } from '../utils.js';
24
+ import { StatusDot } from './StatusDot.js';
23
25
  export function WorkflowEditor({ className = '' }) {
24
26
  const nodes = useWorkspaceStore((s) => s.nodes);
25
27
  const selectedNodeId = useWorkspaceStore((s) => s.selectedNodeId);
@@ -28,10 +30,13 @@ export function WorkflowEditor({ className = '' }) {
28
30
  const moveNode = useWorkspaceStore((s) => s.moveNode);
29
31
  const insertNodeAt = useWorkspaceStore((s) => s.insertNodeAt);
30
32
  const capabilities = useWorkspaceStore((s) => s.capabilities);
33
+ const stubCapabilities = useWorkspaceStore((s) => s.stubCapabilities);
31
34
  const clearWorkflow = useWorkspaceStore((s) => s.clearWorkflow);
32
35
  // 拖拽状态:被拖拽的节点索引 + 当前 hover 的插入位置
33
36
  const [dragIndex, setDragIndex] = React.useState(null);
34
37
  const [hoverIndex, setHoverIndex] = React.useState(null);
38
+ // 清空确认对话框
39
+ const [clearOpen, setClearOpen] = React.useState(false);
35
40
  const handleDragStart = (e, index) => {
36
41
  setDragIndex(index);
37
42
  e.dataTransfer.effectAllowed = 'move';
@@ -77,46 +82,29 @@ export function WorkflowEditor({ className = '' }) {
77
82
  }
78
83
  };
79
84
  const canAddMore = nodes.length < MAX_WORKFLOW_STEPS;
80
- return (_jsxs("div", { className: `flex flex-col border-b border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900 ${className}`, role: "region", "aria-label": "\u5DE5\u4F5C\u6D41\u7F16\u8F91\u5668", children: [_jsxs("div", { className: "flex h-9 shrink-0 items-center justify-between border-b border-zinc-100 px-3 dark:border-zinc-800/50", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-zinc-400", children: "Workflow Editor" }), _jsxs("span", { className: `rounded px-1.5 py-0.5 text-[10px] tabular-nums ${canAddMore
81
- ? 'bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400'
82
- : 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400'}`, children: [nodes.length, "/", MAX_WORKFLOW_STEPS] })] }), nodes.length > 0 && (_jsx("button", { type: "button", onClick: () => {
83
- if (window.confirm('清空当前工作流?所有节点将被移除。')) {
84
- clearWorkflow();
85
- }
86
- }, className: "text-[10px] text-zinc-400 transition-colors hover:text-red-500", "aria-label": "\u6E05\u7A7A\u5DE5\u4F5C\u6D41", children: "Clear" }))] }), _jsx("div", { className: "flex min-h-[3rem] items-center gap-1 overflow-x-auto px-3 py-2", children: nodes.length === 0 ? (_jsx("div", { className: "flex flex-1 items-center justify-center py-2 text-center", children: _jsxs("p", { className: "text-[11px] text-zinc-400", children: ["\u7A7A\u5DE5\u4F5C\u6D41 \u2014 \u4ECE\u53F3\u4FA7 ", _jsx("span", { className: "font-mono", children: "Capabilities" }), " \u9762\u677F\u70B9\u51FB\u6DFB\u52A0\u8282\u70B9"] }) })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex shrink-0 items-center gap-1 rounded-md bg-zinc-100 px-2 py-1 text-[10px] font-medium text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400", children: [_jsx(Icon, { size: 12, children: _jsx("path", { d: "M12 4.5v15m7.5-7.5h-15" }) }), "Source"] }), _jsx(InsertConnector, { index: 0, capabilities: capabilities, onInsert: insertNodeAt, disabled: nodes.length >= MAX_WORKFLOW_STEPS }), nodes.map((node, i) => {
85
+ return (_jsxs("div", { className: `flex flex-col border-b border-[var(--lokvis-border)] bg-[var(--lokvis-surface)] ${className}`, role: "region", "aria-label": "\u5DE5\u4F5C\u6D41\u7F16\u8F91\u5668", children: [_jsxs("div", { className: "flex h-9 shrink-0 items-center justify-between border-b border-[var(--lokvis-border)] px-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-[var(--lokvis-fg-subtle)]", children: "Workflow Editor" }), _jsxs("span", { className: `rounded px-1.5 py-0.5 text-[10px] tabular-nums ${canAddMore
86
+ ? 'bg-[var(--lokvis-surface-muted)] text-[var(--lokvis-fg-muted)]'
87
+ : 'bg-[var(--lokvis-warning)]/15 text-[var(--lokvis-warning)]'}`, children: [nodes.length, "/", MAX_WORKFLOW_STEPS] })] }), nodes.length > 0 && (_jsx("button", { type: "button", onClick: () => setClearOpen(true), className: "text-[10px] text-[var(--lokvis-fg-subtle)] transition-colors hover:text-[var(--lokvis-danger)]", "aria-label": "\u6E05\u7A7A\u5DE5\u4F5C\u6D41", children: "Clear" }))] }), _jsx("div", { className: "flex min-h-[3rem] items-center gap-1 overflow-x-auto px-3 py-2", children: nodes.length === 0 ? (_jsx("div", { className: "flex flex-1 items-center justify-center py-2 text-center", children: _jsxs("p", { className: "text-[11px] text-[var(--lokvis-fg-subtle)]", children: ["\u7A7A\u5DE5\u4F5C\u6D41 \u2014 \u4ECE\u53F3\u4FA7 ", _jsx("span", { className: "font-mono", children: "Capabilities" }), " \u9762\u677F\u70B9\u51FB\u6DFB\u52A0\u8282\u70B9"] }) })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex shrink-0 items-center gap-1 rounded-md bg-[var(--lokvis-surface-muted)] px-2 py-1 text-[10px] font-medium text-[var(--lokvis-fg-muted)]", children: [_jsx(Icon, { size: 12, children: _jsx("path", { d: "M12 4.5v15m7.5-7.5h-15" }) }), "Source"] }), _jsx(InsertConnector, { index: 0, capabilities: capabilities, stubCapabilities: stubCapabilities, onInsert: insertNodeAt, disabled: nodes.length >= MAX_WORKFLOW_STEPS }), nodes.map((node, i) => {
87
88
  const selected = node.id === selectedNodeId;
88
89
  const isDragging = dragIndex === i;
89
90
  const isHoverTarget = hoverIndex === i && dragIndex !== null && dragIndex !== i;
90
- return (_jsxs(React.Fragment, { children: [_jsxs("button", { type: "button", draggable: true, onDragStart: (e) => handleDragStart(e, i), onDragOver: (e) => handleDragOver(e, i), onDragLeave: handleDragLeave, onDrop: (e) => handleDrop(e, i), onDragEnd: handleDragEnd, onClick: () => selectNode(node.id), onKeyDown: (e) => handleKeyDown(e, node.id, i), "aria-label": `节点 ${node.capability},位置 ${i + 1},拖拽或方向键重排,Delete 删除`, className: `group relative flex shrink-0 items-center gap-1.5 rounded-md px-2.5 py-1.5 text-[11px] font-medium transition-all ${isDragging
91
- ? 'opacity-40'
92
- : isHoverTarget
93
- ? 'ring-2 ring-indigo-400 ring-offset-1 dark:ring-offset-zinc-900'
94
- : selected
95
- ? 'bg-indigo-100 text-indigo-700 ring-1 ring-indigo-300 dark:bg-indigo-950/50 dark:text-indigo-300 dark:ring-indigo-700'
96
- : node.status === 'running'
97
- ? 'bg-amber-100 text-amber-700 dark:bg-amber-950/30 dark:text-amber-400'
98
- : node.status === 'success'
99
- ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-950/30 dark:text-emerald-400'
100
- : node.status === 'failed'
101
- ? 'bg-red-100 text-red-700 dark:bg-red-950/30 dark:text-red-400'
102
- : 'bg-zinc-100 text-zinc-700 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-700'} cursor-grab active:cursor-grabbing`, children: [_jsx("span", { className: "flex h-4 w-4 items-center justify-center rounded-full bg-black/5 text-[9px] tabular-nums dark:bg-white/10", children: i + 1 }), _jsx("span", { className: "font-mono", children: node.capability }), _jsx(StatusDot, { status: node.status }), _jsx("button", { type: "button", onClick: (e) => {
103
- e.stopPropagation();
104
- removeNode(node.id);
105
- }, "aria-label": "\u5220\u9664\u8282\u70B9", tabIndex: -1, className: "absolute -right-1 -top-1 rounded p-0.5 opacity-0 transition-opacity group-hover:opacity-100 hover:bg-red-100 hover:text-red-600 dark:hover:bg-red-900/40", children: _jsx(Icon, { size: 10, strokeWidth: 3, children: _jsx("path", { d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(InsertConnector, { index: i + 1, capabilities: capabilities, onInsert: insertNodeAt, disabled: nodes.length >= MAX_WORKFLOW_STEPS })] }, node.id));
106
- }), nodes.length > 0 && (_jsxs("div", { className: "flex shrink-0 items-center gap-1 rounded-md bg-zinc-100 px-2 py-1 text-[10px] font-medium text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400", children: [_jsx(Icon, { size: 12, children: _jsx("path", { d: "M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" }) }), "Output"] }))] })) }), nodes.length > 0 && (_jsxs("div", { className: "flex shrink-0 items-center gap-2 border-t border-zinc-100 px-3 py-1 text-[10px] text-zinc-400 dark:border-zinc-800/50", children: [_jsx(Icon, { size: 10, children: _jsx("path", { d: "M13 5.5a1 1 0 1 1 2 0 1-1 0 0 0-.5.86L16.5 9l1.5-.5a1 1 0 1 1 0 2l-1.5-.5-1 1.5a1 1 0 1 1-2 0l1-1.5-1-1.5a1 1 0 0 1 0-2z" }) }), _jsx("span", { children: "\u62D6\u62FD\u91CD\u6392 \u00B7 \u65B9\u5411\u952E\u79FB\u52A8 \u00B7 Delete \u5220\u9664 \u00B7 hover \u7BAD\u5934\u5904\u63D2\u5165\u8282\u70B9" })] }))] }));
107
- }
108
- function StatusDot({ status }) {
109
- const color = status === 'running'
110
- ? 'bg-amber-500'
111
- : status === 'success'
112
- ? 'bg-emerald-500'
113
- : status === 'failed'
114
- ? 'bg-red-500'
115
- : status === 'pending'
116
- ? 'bg-zinc-400 dark:bg-zinc-500'
117
- : 'bg-zinc-300 dark:bg-zinc-600';
118
- const animate = status === 'running' ? 'animate-pulse' : '';
119
- return _jsx("span", { className: `h-1.5 w-1.5 rounded-full shrink-0 ${color} ${animate}` });
91
+ return (_jsxs(React.Fragment, { children: [_jsxs("div", { className: "group relative flex shrink-0 items-center", children: [_jsxs("button", { type: "button", draggable: true, onDragStart: (e) => handleDragStart(e, i), onDragOver: (e) => handleDragOver(e, i), onDragLeave: handleDragLeave, onDrop: (e) => handleDrop(e, i), onDragEnd: handleDragEnd, onClick: () => selectNode(node.id), onKeyDown: (e) => handleKeyDown(e, node.id, i), "aria-label": `节点 ${node.capability},位置 ${i + 1},拖拽或方向键重排,Delete 删除`, className: `flex shrink-0 items-center gap-1.5 rounded-md px-2.5 py-1.5 text-[11px] font-medium transition-all ${isDragging
92
+ ? 'opacity-40'
93
+ : isHoverTarget
94
+ ? 'ring-2 ring-[var(--lokvis-primary)] ring-offset-1'
95
+ : selected
96
+ ? 'bg-[var(--lokvis-primary)]/15 text-[var(--lokvis-primary)] ring-1 ring-[var(--lokvis-primary)]/50'
97
+ : node.status === 'running'
98
+ ? 'bg-[var(--lokvis-warning)]/15 text-[var(--lokvis-warning)]'
99
+ : node.status === 'success'
100
+ ? 'bg-[var(--lokvis-success)]/15 text-[var(--lokvis-success)]'
101
+ : node.status === 'failed'
102
+ ? 'bg-[var(--lokvis-danger)]/15 text-[var(--lokvis-danger)]'
103
+ : 'bg-[var(--lokvis-surface-muted)] text-[var(--lokvis-fg-muted)] hover:bg-[var(--lokvis-border)]'} cursor-grab active:cursor-grabbing`, children: [_jsx("span", { className: "flex h-4 w-4 items-center justify-center rounded-full bg-[var(--lokvis-fg)]/5 text-[9px] tabular-nums", children: i + 1 }), _jsx("span", { className: "font-mono", children: node.capability }), _jsx(StatusDot, { status: node.status })] }), _jsx("button", { type: "button", onClick: () => removeNode(node.id), "aria-label": "\u5220\u9664\u8282\u70B9", tabIndex: -1, className: "absolute -right-1 -top-1 rounded p-0.5 opacity-0 transition-opacity group-hover:opacity-100 hover:bg-[var(--lokvis-danger)]/15 hover:text-[var(--lokvis-danger)]", children: _jsx(Icon, { size: 10, strokeWidth: 3, children: _jsx("path", { d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(InsertConnector, { index: i + 1, capabilities: capabilities, stubCapabilities: stubCapabilities, onInsert: insertNodeAt, disabled: nodes.length >= MAX_WORKFLOW_STEPS })] }, node.id));
104
+ }), nodes.length > 0 && (_jsxs("div", { className: "flex shrink-0 items-center gap-1 rounded-md bg-[var(--lokvis-surface-muted)] px-2 py-1 text-[10px] font-medium text-[var(--lokvis-fg-muted)]", children: [_jsx(Icon, { size: 12, children: _jsx("path", { d: "M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" }) }), "Output"] }))] })) }), nodes.length > 0 && (_jsxs("div", { className: "flex shrink-0 items-center gap-2 border-t border-[var(--lokvis-border)] px-3 py-1 text-[10px] text-[var(--lokvis-fg-subtle)]", children: [_jsx(Icon, { size: 10, children: _jsx("path", { d: "M13 5.5a1 1 0 1 1 2 0 1-1 0 0 0-.5.86L16.5 9l1.5-.5a1 1 0 1 1 0 2l-1.5-.5-1 1.5a1 1 0 1 1-2 0l1-1.5-1-1.5a1 1 0 0 1 0-2z" }) }), _jsx("span", { children: "\u62D6\u62FD\u91CD\u6392 \u00B7 \u65B9\u5411\u952E\u79FB\u52A8 \u00B7 Delete \u5220\u9664 \u00B7 hover \u7BAD\u5934\u5904\u63D2\u5165\u8282\u70B9" })] })), _jsx(ConfirmDialog, { open: clearOpen, title: "\u6E05\u7A7A\u5DE5\u4F5C\u6D41", message: "\u6E05\u7A7A\u5F53\u524D\u5DE5\u4F5C\u6D41?\u6240\u6709\u8282\u70B9\u5C06\u88AB\u79FB\u9664\u3002", confirmText: "\u6E05\u7A7A", variant: "danger", onConfirm: () => {
105
+ clearWorkflow();
106
+ setClearOpen(false);
107
+ }, onClose: () => setClearOpen(false) })] }));
120
108
  }
121
109
  /**
122
110
  * InsertConnector - 节点之间的连接器 + 插入按钮(W11.1)
@@ -124,7 +112,7 @@ function StatusDot({ status }) {
124
112
  * 默认显示箭头;hover 时变为 + 按钮,点击弹出 capability 选择菜单。
125
113
  * 选择后调用 onInsert(index, capability)。
126
114
  */
127
- function InsertConnector({ index, capabilities, onInsert, disabled, }) {
115
+ function InsertConnector({ index, capabilities, stubCapabilities, onInsert, disabled, }) {
128
116
  const [open, setOpen] = React.useState(false);
129
117
  const [filter, setFilter] = React.useState('');
130
118
  const ref = React.useRef(null);
@@ -144,8 +132,7 @@ function InsertConnector({ index, capabilities, onInsert, disabled, }) {
144
132
  document.addEventListener('mousedown', handler);
145
133
  return () => document.removeEventListener('mousedown', handler);
146
134
  }, [open]);
147
- const filtered = React.useMemo(() => capabilities.filter((c) => c.name.toLowerCase().includes(filter.toLowerCase()) ||
148
- c.description.toLowerCase().includes(filter.toLowerCase())), [capabilities, filter]);
135
+ const filtered = React.useMemo(() => filterCapabilities(capabilities, filter), [capabilities, filter]);
149
136
  const handleSelect = (capName) => {
150
137
  onInsert(index, capName);
151
138
  setOpen(false);
@@ -153,8 +140,12 @@ function InsertConnector({ index, capabilities, onInsert, disabled, }) {
153
140
  };
154
141
  if (disabled) {
155
142
  // 5 步上限时只显示箭头,不显示 +
156
- return (_jsx(Icon, { size: 12, className: "shrink-0 text-zinc-300 dark:text-zinc-600", children: _jsx("path", { d: "m9 5 7 7-7 7" }) }));
143
+ return (_jsx(Icon, { size: 12, className: "shrink-0 text-[var(--lokvis-fg-subtle)]", children: _jsx("path", { d: "m9 5 7 7-7 7" }) }));
157
144
  }
158
- return (_jsxs("div", { ref: ref, className: "relative flex shrink-0 items-center", children: [_jsxs("button", { type: "button", onClick: () => setOpen(!open), "aria-label": `在位置 ${index + 1} 插入节点`, title: "\u63D2\u5165\u8282\u70B9", className: "group flex h-5 w-5 items-center justify-center rounded text-zinc-300 transition-colors hover:bg-indigo-100 hover:text-indigo-500 dark:text-zinc-600 dark:hover:bg-indigo-950/40", children: [_jsx(Icon, { size: 12, className: "group-hover:hidden", children: _jsx("path", { d: "m9 5 7 7-7 7" }) }), _jsx(Icon, { size: 12, className: "hidden group-hover:block", strokeWidth: 2.5, children: _jsx("path", { d: "M12 5v14M5 12h14" }) })] }), open && (_jsxs("div", { className: "absolute top-full left-1/2 z-50 mt-1 w-56 -translate-x-1/2 rounded-lg border border-zinc-200 bg-white shadow-lg dark:border-zinc-700 dark:bg-zinc-900", children: [_jsx("div", { className: "border-b border-zinc-100 p-1.5 dark:border-zinc-800", children: _jsx("input", { type: "text", autoFocus: true, placeholder: "\u641C\u7D22 capability...", value: filter, onChange: (e) => setFilter(e.target.value), className: "w-full rounded border border-zinc-200 bg-white px-2 py-1 text-[11px] placeholder-zinc-400 focus:border-indigo-400 focus:outline-none dark:border-zinc-700 dark:bg-zinc-900" }) }), _jsx("div", { className: "max-h-48 overflow-y-auto p-1", children: filtered.length === 0 ? (_jsx("p", { className: "px-2 py-2 text-center text-[10px] text-zinc-400", children: "\u65E0\u5339\u914D capability" })) : (filtered.map((cap) => (_jsxs("button", { type: "button", onClick: () => handleSelect(cap.name), className: "block w-full rounded px-2 py-1 text-left transition-colors hover:bg-indigo-50 dark:hover:bg-indigo-950/30", children: [_jsx("span", { className: "block font-mono text-[10px] font-medium text-zinc-700 dark:text-zinc-300", children: cap.name }), _jsx("span", { className: "block truncate text-[9px] text-zinc-500 dark:text-zinc-400", children: cap.description })] }, cap.name)))) })] }))] }));
145
+ return (_jsxs("div", { ref: ref, className: "relative flex shrink-0 items-center", children: [_jsxs("button", { type: "button", onClick: () => setOpen(!open), "aria-label": `在位置 ${index + 1} 插入节点`, title: "\u63D2\u5165\u8282\u70B9", className: "group flex h-5 w-5 items-center justify-center rounded text-[var(--lokvis-fg-subtle)] transition-colors hover:bg-[var(--lokvis-primary)]/15 hover:text-[var(--lokvis-primary)]", children: [_jsx(Icon, { size: 12, className: "group-hover:hidden", children: _jsx("path", { d: "m9 5 7 7-7 7" }) }), _jsx(Icon, { size: 12, className: "hidden group-hover:block", strokeWidth: 2.5, children: _jsx("path", { d: "M12 5v14M5 12h14" }) })] }), open && (_jsxs("div", { className: "absolute top-full left-1/2 z-50 mt-1 w-56 -translate-x-1/2 rounded-lg border border-[var(--lokvis-border)] bg-[var(--lokvis-surface)] shadow-[var(--lokvis-elevation-2)]", children: [_jsx("div", { className: "border-b border-[var(--lokvis-border)] p-1.5", children: _jsx(Input, { type: "text", size: "sm", autoFocus: true, placeholder: "\u641C\u7D22 capability...", value: filter, onChange: (e) => setFilter(e.target.value) }) }), _jsx("div", { className: "max-h-48 overflow-y-auto p-1", children: filtered.length === 0 ? (_jsx("p", { className: "px-2 py-2 text-center text-[10px] text-[var(--lokvis-fg-subtle)]", children: "\u65E0\u5339\u914D capability" })) : (filtered.map((cap) => {
146
+ // A7: stub-only 能力显示 "Coming Soon" 标记
147
+ const isStubOnly = stubCapabilities.has(cap.name);
148
+ return (_jsxs("button", { type: "button", onClick: () => handleSelect(cap.name), title: isStubOnly ? 'Coming soon — no engine installed yet' : undefined, className: "block w-full rounded px-2 py-1 text-left transition-colors hover:bg-[var(--lokvis-primary)]/10", children: [_jsxs("span", { className: "flex items-center justify-between gap-1.5", children: [_jsx("span", { className: "block font-mono text-[10px] font-medium text-[var(--lokvis-fg-muted)]", children: cap.name }), isStubOnly && (_jsx("span", { className: "shrink-0 rounded px-1 py-0.5 text-[8px] font-medium uppercase bg-[var(--lokvis-warning)]/15 text-[var(--lokvis-warning)]", children: "Soon" }))] }), _jsx("span", { className: "block truncate text-[9px] text-[var(--lokvis-fg-muted)]", children: cap.description })] }, cap.name));
149
+ })) })] }))] }));
159
150
  }
160
151
  //# sourceMappingURL=WorkflowEditor.js.map