@lokvis/ui-react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/components/AssetPanel.d.ts +12 -0
  2. package/dist/components/AssetPanel.d.ts.map +1 -0
  3. package/dist/components/AssetPanel.js +69 -0
  4. package/dist/components/AssetPanel.js.map +1 -0
  5. package/dist/components/Canvas.d.ts +12 -0
  6. package/dist/components/Canvas.d.ts.map +1 -0
  7. package/dist/components/Canvas.js +35 -0
  8. package/dist/components/Canvas.js.map +1 -0
  9. package/dist/components/HistoryPanel.d.ts +14 -0
  10. package/dist/components/HistoryPanel.d.ts.map +1 -0
  11. package/dist/components/HistoryPanel.js +68 -0
  12. package/dist/components/HistoryPanel.js.map +1 -0
  13. package/dist/components/Inspector.d.ts +12 -0
  14. package/dist/components/Inspector.d.ts.map +1 -0
  15. package/dist/components/Inspector.js +46 -0
  16. package/dist/components/Inspector.js.map +1 -0
  17. package/dist/components/ParamForm.d.ts +14 -0
  18. package/dist/components/ParamForm.d.ts.map +1 -0
  19. package/dist/components/ParamForm.js +28 -0
  20. package/dist/components/ParamForm.js.map +1 -0
  21. package/dist/components/PipelineBar.d.ts +12 -0
  22. package/dist/components/PipelineBar.d.ts.map +1 -0
  23. package/dist/components/PipelineBar.js +44 -0
  24. package/dist/components/PipelineBar.js.map +1 -0
  25. package/dist/components/StatusBar.d.ts +10 -0
  26. package/dist/components/StatusBar.d.ts.map +1 -0
  27. package/dist/components/StatusBar.js +22 -0
  28. package/dist/components/StatusBar.js.map +1 -0
  29. package/dist/components/Toolbar.d.ts +14 -0
  30. package/dist/components/Toolbar.d.ts.map +1 -0
  31. package/dist/components/Toolbar.js +36 -0
  32. package/dist/components/Toolbar.js.map +1 -0
  33. package/dist/components/Workspace.d.ts +24 -0
  34. package/dist/components/Workspace.d.ts.map +1 -0
  35. package/dist/components/Workspace.js +33 -0
  36. package/dist/components/Workspace.js.map +1 -0
  37. package/dist/hooks/useLokvis.d.ts +32 -0
  38. package/dist/hooks/useLokvis.d.ts.map +1 -0
  39. package/dist/hooks/useLokvis.js +62 -0
  40. package/dist/hooks/useLokvis.js.map +1 -0
  41. package/dist/index.d.ts +27 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +26 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/store/assets-slice.d.ts +11 -0
  46. package/dist/store/assets-slice.d.ts.map +1 -0
  47. package/dist/store/assets-slice.js +39 -0
  48. package/dist/store/assets-slice.js.map +1 -0
  49. package/dist/store/capabilities-slice.d.ts +11 -0
  50. package/dist/store/capabilities-slice.d.ts.map +1 -0
  51. package/dist/store/capabilities-slice.js +15 -0
  52. package/dist/store/capabilities-slice.js.map +1 -0
  53. package/dist/store/index.d.ts +4 -0
  54. package/dist/store/index.d.ts.map +1 -0
  55. package/dist/store/index.js +24 -0
  56. package/dist/store/index.js.map +1 -0
  57. package/dist/store/runtime-slice.d.ts +13 -0
  58. package/dist/store/runtime-slice.d.ts.map +1 -0
  59. package/dist/store/runtime-slice.js +29 -0
  60. package/dist/store/runtime-slice.js.map +1 -0
  61. package/dist/store/types.d.ts +77 -0
  62. package/dist/store/types.d.ts.map +1 -0
  63. package/dist/store/types.js +5 -0
  64. package/dist/store/types.js.map +1 -0
  65. package/dist/store/workflow-slice.d.ts +18 -0
  66. package/dist/store/workflow-slice.d.ts.map +1 -0
  67. package/dist/store/workflow-slice.js +133 -0
  68. package/dist/store/workflow-slice.js.map +1 -0
  69. package/dist/types.d.ts +33 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +5 -0
  72. package/dist/types.js.map +1 -0
  73. package/package.json +57 -0
  74. package/src/components/AssetPanel.tsx +151 -0
  75. package/src/components/Canvas.tsx +123 -0
  76. package/src/components/HistoryPanel.tsx +127 -0
  77. package/src/components/Inspector.tsx +158 -0
  78. package/src/components/ParamForm.tsx +163 -0
  79. package/src/components/PipelineBar.tsx +125 -0
  80. package/src/components/StatusBar.tsx +63 -0
  81. package/src/components/Toolbar.tsx +87 -0
  82. package/src/components/Workspace.tsx +90 -0
  83. package/src/hooks/useLokvis.ts +78 -0
  84. package/src/index.ts +32 -0
  85. package/src/store/assets-slice.ts +57 -0
  86. package/src/store/capabilities-slice.ts +29 -0
  87. package/src/store/index.ts +27 -0
  88. package/src/store/runtime-slice.ts +53 -0
  89. package/src/store/types.ts +88 -0
  90. package/src/store/workflow-slice.ts +178 -0
  91. package/src/types.ts +46 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * AssetPanel - 左侧资产面板
3
+ *
4
+ * 紧凑布局:section header + 上传按钮 + 资产列表。
5
+ * 支持拖拽导入、点击选择、缩略图预览。
6
+ */
7
+ import * as React from 'react';
8
+ export interface AssetPanelProps {
9
+ className?: string;
10
+ }
11
+ export declare function AssetPanel({ className }: AssetPanelProps): React.JSX.Element;
12
+ //# sourceMappingURL=AssetPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetPanel.d.ts","sourceRoot":"","sources":["../../src/components/AssetPanel.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EAAE,SAAc,EAAE,EAAE,eAAe,qBAwI7D"}
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * AssetPanel - 左侧资产面板
4
+ *
5
+ * 紧凑布局:section header + 上传按钮 + 资产列表。
6
+ * 支持拖拽导入、点击选择、缩略图预览。
7
+ */
8
+ import * as React from 'react';
9
+ import { useWorkspaceStore } from '../store/index.js';
10
+ export function AssetPanel({ className = '' }) {
11
+ const assets = useWorkspaceStore((s) => s.assets);
12
+ const selectedAssetId = useWorkspaceStore((s) => s.selectedAssetId);
13
+ const thumbnails = useWorkspaceStore((s) => s.thumbnails);
14
+ const importFiles = useWorkspaceStore((s) => s.importFiles);
15
+ const selectAsset = useWorkspaceStore((s) => s.selectAsset);
16
+ const removeAsset = useWorkspaceStore((s) => s.removeAsset);
17
+ const setThumbnail = useWorkspaceStore((s) => s.setThumbnail);
18
+ const runtime = useWorkspaceStore((s) => s.runtime);
19
+ const [dragging, setDragging] = React.useState(false);
20
+ async function handleFiles(files) {
21
+ if (!files)
22
+ return;
23
+ const arr = Array.from(files);
24
+ if (arr.length > 0)
25
+ await importFiles(arr);
26
+ }
27
+ // 自动生成缩略图
28
+ React.useEffect(() => {
29
+ if (!runtime)
30
+ return;
31
+ for (const asset of assets) {
32
+ if (thumbnails[asset.id])
33
+ continue;
34
+ if (asset.type !== 'image')
35
+ continue;
36
+ (async () => {
37
+ try {
38
+ const blob = await runtime.exportAsset(asset.id);
39
+ const url = URL.createObjectURL(blob);
40
+ setThumbnail(asset.id, url);
41
+ }
42
+ catch {
43
+ // ignore
44
+ }
45
+ })();
46
+ }
47
+ // eslint-disable-next-line react-hooks/exhaustive-deps
48
+ }, [assets, runtime]);
49
+ return (_jsxs("aside", { className: `flex w-56 shrink-0 flex-col border-r border-zinc-200 dark:border-zinc-800 ${className}`, onDragOver: (e) => {
50
+ e.preventDefault();
51
+ setDragging(true);
52
+ }, onDragLeave: () => setDragging(false), onDrop: (e) => {
53
+ e.preventDefault();
54
+ setDragging(false);
55
+ void handleFiles(e.dataTransfer.files);
56
+ }, children: [_jsxs("div", { className: "flex items-center justify-between px-3 h-10 shrink-0 border-b border-zinc-200 dark:border-zinc-800", children: [_jsx("span", { className: "text-[11px] font-semibold uppercase tracking-wider text-zinc-400", children: "Assets" }), _jsx("span", { className: "text-[11px] tabular-nums text-zinc-400", children: assets.length })] }), _jsxs("label", { className: `m-2 block cursor-pointer rounded-lg border border-dashed px-2 py-3 text-center transition-all ${dragging
57
+ ? 'border-indigo-400 bg-indigo-50 text-indigo-600 dark:bg-indigo-950/30'
58
+ : 'border-zinc-200 text-zinc-400 hover:border-indigo-300 hover:bg-indigo-50/50 hover:text-indigo-500 dark:border-zinc-700 dark:hover:border-indigo-800 dark:hover:bg-indigo-950/20'}`, children: [_jsx("input", { type: "file", multiple: true, className: "hidden", onChange: (e) => handleFiles(e.target.files) }), _jsx("svg", { className: "mx-auto h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 4.5v15m7.5-7.5h-15" }) }), _jsx("span", { className: "mt-1 block text-[10px] font-medium", children: dragging ? 'Drop here' : 'Add files' })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: assets.length === 0 ? (_jsx("p", { className: "px-1 py-4 text-center text-[10px] text-zinc-400", children: "No assets imported" })) : (_jsx("ul", { className: "space-y-1", children: assets.map((asset) => {
59
+ const selected = asset.id === selectedAssetId;
60
+ const thumb = thumbnails[asset.id];
61
+ return (_jsxs("li", { onClick: () => selectAsset(asset.id), className: `group flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-xs transition-all ${selected
62
+ ? 'bg-indigo-50 ring-1 ring-indigo-200 dark:bg-indigo-950/30 dark:ring-indigo-800'
63
+ : 'hover:bg-zinc-50 dark:hover:bg-zinc-800'}`, children: [_jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded bg-zinc-100 dark:bg-zinc-800", children: thumb ? (_jsx("img", { src: thumb, alt: "", className: "h-full w-full object-cover" })) : (_jsx("span", { className: "text-[10px] font-medium text-zinc-400", children: asset.metadata.format.slice(0, 3).toUpperCase() })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-[11px] font-medium", children: asset.metadata.format }), _jsxs("div", { className: "text-[10px] text-zinc-400", children: [(asset.metadata.size / 1024).toFixed(1), " KB"] })] }), _jsx("button", { type: "button", onClick: (e) => {
64
+ e.stopPropagation();
65
+ void removeAsset(asset.id);
66
+ }, className: "shrink-0 rounded p-0.5 text-zinc-300 opacity-0 transition-all hover:bg-red-50 hover:text-red-500 group-hover:opacity-100 dark:text-zinc-600 dark:hover:bg-red-950/30", "aria-label": "Remove asset", children: _jsx("svg", { className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) })] }, asset.id));
67
+ }) })) })] }));
68
+ }
69
+ //# sourceMappingURL=AssetPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetPanel.js","sourceRoot":"","sources":["../../src/components/AssetPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Canvas - 中央画布(纯预览)
3
+ *
4
+ * 只负责展示当前选中资产的预览,以及空状态引导。
5
+ * 工作流节点链已移至独立的 PipelineBar 组件。
6
+ */
7
+ import * as React from 'react';
8
+ export interface CanvasProps {
9
+ className?: string;
10
+ }
11
+ export declare function Canvas({ className }: CanvasProps): React.JSX.Element;
12
+ //# sourceMappingURL=Canvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../src/components/Canvas.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EAAE,SAAc,EAAE,EAAE,WAAW,qBA4GrD"}
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * Canvas - 中央画布(纯预览)
4
+ *
5
+ * 只负责展示当前选中资产的预览,以及空状态引导。
6
+ * 工作流节点链已移至独立的 PipelineBar 组件。
7
+ */
8
+ import * as React from 'react';
9
+ import { useWorkspaceStore } from '../store/index.js';
10
+ export function Canvas({ className = '' }) {
11
+ const selectedAssetId = useWorkspaceStore((s) => s.selectedAssetId);
12
+ const assets = useWorkspaceStore((s) => s.assets);
13
+ const thumbnails = useWorkspaceStore((s) => s.thumbnails);
14
+ const importFiles = useWorkspaceStore((s) => s.importFiles);
15
+ const selected = assets.find((a) => a.id === selectedAssetId);
16
+ const preview = selected ? thumbnails[selected.id] : undefined;
17
+ // 全局拖拽支持(直接拖到画布区)
18
+ const [dragOver, setDragOver] = React.useState(false);
19
+ return (_jsx("main", { className: `relative flex flex-1 flex-col overflow-hidden ${className}`, onDragOver: (e) => { e.preventDefault(); setDragOver(true); }, onDragLeave: () => setDragOver(false), onDrop: (e) => {
20
+ e.preventDefault();
21
+ setDragOver(false);
22
+ if (e.dataTransfer.files.length > 0) {
23
+ void importFiles(Array.from(e.dataTransfer.files));
24
+ }
25
+ }, children: _jsxs("div", { className: "relative flex flex-1 items-center justify-center bg-zinc-50 dark:bg-zinc-950", children: [_jsx("div", { className: "absolute inset-0 opacity-[0.35]", style: {
26
+ backgroundImage: 'radial-gradient(circle, #d4d4d8 1px, transparent 1px)',
27
+ backgroundSize: '20px 20px',
28
+ } }), dragOver && (_jsx("div", { className: "absolute inset-4 z-10 rounded-xl border-2 border-dashed border-indigo-400 bg-indigo-50/80 flex items-center justify-center dark:border-indigo-600 dark:bg-indigo-950/60", children: _jsxs("div", { className: "text-center", children: [_jsx("svg", { className: "mx-auto h-8 w-8 text-indigo-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5m-13.5-9L12 3m0 0 4.5 4.5M12 3v13.5" }) }), _jsx("p", { className: "mt-2 text-sm font-medium text-indigo-600 dark:text-indigo-400", children: "Drop files to import" })] }) })), selected ? (preview ? (_jsxs("div", { className: "relative", children: [_jsx("img", { src: preview, alt: selected.metadata.format, className: "max-h-[calc(100%-4rem)] max-w-[calc(100%-4rem)] rounded-lg object-contain shadow-2xl shadow-black/10 ring-1 ring-black/5 dark:shadow-black/30" }), _jsx("div", { className: "absolute bottom-2 left-2 rounded-lg bg-white/90 px-2.5 py-1 text-[11px] text-zinc-600 shadow-sm backdrop-blur-sm dark:bg-zinc-900/90 dark:text-zinc-300", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium", children: selected.metadata.format.toUpperCase() }), selected.metadata.dimensions && (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-zinc-300", children: "\u00B7" }), _jsxs("span", { children: [selected.metadata.dimensions.width, " x ", selected.metadata.dimensions.height] })] })), _jsx("span", { className: "text-zinc-300", children: "\u00B7" }), _jsxs("span", { children: [(selected.metadata.size / 1024).toFixed(1), " KB"] })] }) })] })) : (_jsxs("div", { className: "flex flex-col items-center gap-3", children: [_jsx("div", { className: "h-28 w-28 animate-pulse rounded-xl bg-zinc-200 dark:bg-zinc-800" }), _jsx("span", { className: "text-xs text-zinc-400", children: "Loading preview..." })] }))) : (_jsxs("div", { className: "relative flex flex-col items-center gap-5 px-6 text-center", children: [_jsx("div", { className: "flex h-20 w-20 items-center justify-center rounded-2xl bg-white shadow-sm ring-1 ring-zinc-200/80 dark:bg-zinc-800 dark:ring-zinc-700", children: _jsx("svg", { className: "h-9 w-9 text-zinc-300 dark:text-zinc-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" }) }) }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-zinc-500 dark:text-zinc-400", children: "No asset selected" }), _jsx("p", { className: "mt-1.5 text-xs text-zinc-400 dark:text-zinc-500", children: assets.length === 0
29
+ ? 'Import files to get started, or drag them here'
30
+ : 'Select an asset from the left panel' })] }), assets.length === 0 && (_jsxs("label", { className: "mt-2 inline-flex items-center gap-1.5 rounded-lg bg-indigo-600 px-4 py-2 text-xs font-medium text-white shadow-sm cursor-pointer transition-colors hover:bg-indigo-500", children: [_jsx("svg", { className: "h-3.5 w-3.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 4.5v15m7.5-7.5h-15" }) }), "Import Files", _jsx("input", { type: "file", multiple: true, className: "hidden", onChange: (e) => {
31
+ if (e.target.files)
32
+ void importFiles(Array.from(e.target.files));
33
+ } })] }))] }))] }) }));
34
+ }
35
+ //# sourceMappingURL=Canvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvas.js","sourceRoot":"","sources":["../../src/components/Canvas.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * HistoryPanel - 处理历史面板
3
+ *
4
+ * 监听 Runtime 事件,记录最近处理过的资产与工作流执行。
5
+ * MVP 仅做只读展示,撤销/重做通过 Runtime API(已留接口)。
6
+ */
7
+ import * as React from 'react';
8
+ export interface HistoryPanelProps {
9
+ className?: string;
10
+ /** 最大记录数 */
11
+ maxItems?: number;
12
+ }
13
+ export declare function HistoryPanel({ className, maxItems }: HistoryPanelProps): React.JSX.Element;
14
+ //# sourceMappingURL=HistoryPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistoryPanel.d.ts","sourceRoot":"","sources":["../../src/components/HistoryPanel.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAc,EAAE,QAAa,EAAE,EAAE,iBAAiB,qBAmEhF"}
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * HistoryPanel - 处理历史面板
4
+ *
5
+ * 监听 Runtime 事件,记录最近处理过的资产与工作流执行。
6
+ * MVP 仅做只读展示,撤销/重做通过 Runtime API(已留接口)。
7
+ */
8
+ import * as React from 'react';
9
+ import { useWorkspaceStore } from '../store/index.js';
10
+ export function HistoryPanel({ className = '', maxItems = 50 }) {
11
+ const runtime = useWorkspaceStore((s) => s.runtime);
12
+ const [items, setItems] = React.useState([]);
13
+ React.useEffect(() => {
14
+ if (!runtime)
15
+ return;
16
+ const push = (e) => {
17
+ const item = {
18
+ id: `${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,
19
+ type: e.type,
20
+ message: formatEvent(e),
21
+ timestamp: Date.now(),
22
+ };
23
+ setItems((prev) => [item, ...prev].slice(0, maxItems));
24
+ };
25
+ // 使用 onAny 订阅所有事件,避免枚举所有类型
26
+ const off = runtime.eventBus.onAny(push);
27
+ return () => {
28
+ off();
29
+ };
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
+ }, [runtime]);
32
+ return (_jsxs("aside", { className: `flex h-32 flex-col border-t border-zinc-200 bg-zinc-50/50 dark:border-zinc-800 dark:bg-zinc-950/50 ${className}`, children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 px-4 py-1.5 dark:border-zinc-800", children: [_jsx("h3", { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500", children: "History" }), items.length > 0 && (_jsx("button", { type: "button", onClick: () => setItems([]), className: "text-xs text-zinc-400 hover:text-zinc-600", children: "Clear" }))] }), _jsx("div", { className: "flex-1 overflow-x-auto overflow-y-hidden px-2 py-1.5", children: items.length === 0 ? (_jsx("p", { className: "px-2 text-xs text-zinc-400", children: "No history yet" })) : (_jsx("ul", { className: "flex h-full items-stretch gap-1.5", children: items.map((item) => (_jsxs("li", { className: "flex w-56 flex-none flex-col justify-between rounded border border-zinc-200 bg-white px-2 py-1 text-xs dark:border-zinc-800 dark:bg-zinc-900", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "font-mono text-[10px] text-zinc-400", children: new Date(item.timestamp).toLocaleTimeString() }), _jsx("span", { className: "font-mono text-[10px] text-zinc-400", children: item.type })] }), _jsx("div", { className: "truncate text-zinc-600 dark:text-zinc-300", title: item.message, children: item.message })] }, item.id))) })) })] }));
33
+ }
34
+ function formatEvent(e) {
35
+ switch (e.type) {
36
+ case 'asset:imported':
37
+ return `Imported ${e.metadata.mimeType}`;
38
+ case 'asset:removed':
39
+ return `Removed asset ${e.assetId.slice(0, 8)}`;
40
+ case 'workflow:started':
41
+ return `Workflow started: ${e.workflowId.slice(0, 8)}`;
42
+ case 'workflow:completed':
43
+ return `Workflow ${e.result.status} in ${e.result.duration}ms`;
44
+ case 'workflow:cancelled':
45
+ return 'Workflow cancelled';
46
+ case 'workflow:paused':
47
+ return 'Workflow paused';
48
+ case 'workflow:resumed':
49
+ return 'Workflow resumed';
50
+ case 'node:started':
51
+ return `Node started: ${e.nodeId.slice(0, 8)}`;
52
+ case 'node:finished':
53
+ return `Node finished: ${e.nodeId.slice(0, 8)} (${e.duration}ms)`;
54
+ case 'node:failed':
55
+ return `Node failed: ${e.error.message}`;
56
+ case 'plugin:loaded':
57
+ return `Plugin loaded: ${e.name}@${e.version}`;
58
+ case 'export:completed':
59
+ return `Exported ${e.format} (${(e.size / 1024).toFixed(1)} KB)`;
60
+ case 'capability:registered':
61
+ return `Capability registered: ${e.capability} (${e.engine})`;
62
+ case 'history:changed':
63
+ return `History changed (${e.entries.length} entries)`;
64
+ default:
65
+ return e.type;
66
+ }
67
+ }
68
+ //# sourceMappingURL=HistoryPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistoryPanel.js","sourceRoot":"","sources":["../../src/components/HistoryPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Inspector - 右侧面板
3
+ *
4
+ * 上半部分:当前选中节点的参数配置(Configure)
5
+ * 下半部分:可用 Capabilities 列表(点击添加到工作流)
6
+ */
7
+ import * as React from 'react';
8
+ export interface InspectorProps {
9
+ className?: string;
10
+ }
11
+ export declare function Inspector({ className }: InspectorProps): React.JSX.Element;
12
+ //# sourceMappingURL=Inspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Inspector.d.ts","sourceRoot":"","sources":["../../src/components/Inspector.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,SAAc,EAAE,EAAE,cAAc,qBA8I3D"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Inspector - 右侧面板
4
+ *
5
+ * 上半部分:当前选中节点的参数配置(Configure)
6
+ * 下半部分:可用 Capabilities 列表(点击添加到工作流)
7
+ */
8
+ import * as React from 'react';
9
+ import { useWorkspaceStore } from '../store/index.js';
10
+ import { ParamForm } from './ParamForm.js';
11
+ export function Inspector({ className = '' }) {
12
+ const capabilities = useWorkspaceStore((s) => s.capabilities);
13
+ const nodes = useWorkspaceStore((s) => s.nodes);
14
+ const selectedNodeId = useWorkspaceStore((s) => s.selectedNodeId);
15
+ const capabilityMap = useWorkspaceStore((s) => s.capabilityMap);
16
+ const addNode = useWorkspaceStore((s) => s.addNode);
17
+ const updateNodeParams = useWorkspaceStore((s) => s.updateNodeParams);
18
+ const selectedNode = nodes.find((n) => n.id === selectedNodeId);
19
+ const [filter, setFilter] = React.useState('');
20
+ const [configureOpen, setConfigureOpen] = React.useState(true);
21
+ const filtered = capabilities.filter((c) => c.name.toLowerCase().includes(filter.toLowerCase()) ||
22
+ c.description.toLowerCase().includes(filter.toLowerCase()));
23
+ // 按域分组
24
+ const grouped = React.useMemo(() => {
25
+ const map = new Map();
26
+ for (const cap of filtered) {
27
+ const domain = cap.name.split('.')[0] ?? 'other';
28
+ if (!map.has(domain))
29
+ map.set(domain, []);
30
+ map.get(domain).push(cap);
31
+ }
32
+ return map;
33
+ }, [filtered]);
34
+ const showConfigure = selectedNode && capabilityMap[selectedNode.capability];
35
+ return (_jsxs("aside", { className: `flex w-72 shrink-0 flex-col border-l border-zinc-200 dark:border-zinc-800 ${className}`, children: [showConfigure && (_jsxs("div", { className: "shrink-0 border-b border-zinc-200 dark:border-zinc-800", children: [_jsxs("button", { type: "button", onClick: () => setConfigureOpen(!configureOpen), className: "flex w-full items-center justify-between px-3 h-10 text-left transition-colors hover:bg-zinc-50 dark:hover:bg-zinc-800/50", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("svg", { className: `h-3 w-3 text-zinc-400 transition-transform ${configureOpen ? 'rotate-90' : ''}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m9 5 7 7-7 7" }) }), _jsx("span", { className: "text-[11px] font-semibold uppercase tracking-wider text-zinc-400", children: "Configure" })] }), _jsx("span", { className: "font-mono text-[10px] text-indigo-500 bg-indigo-50 dark:bg-indigo-950/30 px-1.5 py-0.5 rounded", children: selectedNode.capability })] }), configureOpen && (_jsx("div", { className: "px-3 pb-3 max-h-60 overflow-y-auto", children: _jsx(ParamForm, { capability: capabilityMap[selectedNode.capability], values: selectedNode.params, onChange: (params) => updateNodeParams(selectedNode.id, params) }) }))] })), _jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between px-3 h-10 shrink-0 border-b border-zinc-200 dark:border-zinc-800", children: [_jsx("span", { className: "text-[11px] font-semibold uppercase tracking-wider text-zinc-400", children: "Capabilities" }), _jsx("span", { className: "text-[11px] tabular-nums text-zinc-400", children: filtered.length })] }), _jsx("div", { className: "px-2 py-2 border-b border-zinc-100 dark:border-zinc-800/50", children: _jsxs("div", { className: "relative", children: [_jsxs("svg", { className: "absolute left-2 top-1/2 -translate-y-1/2 h-3 w-3 text-zinc-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: [_jsx("circle", { cx: "11", cy: "11", r: "8" }), _jsx("path", { d: "m21 21-4.3-4.3" })] }), _jsx("input", { type: "text", placeholder: "Search capabilities...", value: filter, onChange: (e) => setFilter(e.target.value), className: "w-full rounded-md border border-zinc-200 bg-white py-1 pl-7 pr-2 text-[11px] placeholder-zinc-400 focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400 dark:border-zinc-700 dark:bg-zinc-900" })] }) }), _jsx("div", { className: "flex-1 overflow-y-auto p-2", children: capabilities.length === 0 ? (_jsxs("div", { className: "px-2 py-8 text-center", children: [_jsx("p", { className: "text-[11px] text-zinc-400", children: "No capabilities loaded" }), _jsx("p", { className: "mt-1 text-[10px] text-zinc-500", children: "Load a plugin to get started" })] })) : filtered.length === 0 ? (_jsx("p", { className: "px-2 py-4 text-[11px] text-zinc-400", children: "No matching capabilities" })) : (_jsx("div", { className: "space-y-3", children: Array.from(grouped.entries()).map(([domain, caps]) => (_jsxs("div", { children: [_jsx("div", { className: "px-2 py-1 text-[10px] font-semibold uppercase tracking-wider text-zinc-400", children: domain }), _jsx("ul", { className: "space-y-0.5", children: caps.map((cap) => {
36
+ const isInPipeline = nodes.some((n) => n.capability === cap.name);
37
+ return (_jsx("li", { children: _jsxs("button", { type: "button", onClick: () => addNode(cap.name), className: `group w-full rounded-md px-2 py-1.5 text-left transition-all ${isInPipeline
38
+ ? 'bg-indigo-50/50 ring-1 ring-indigo-200 dark:bg-indigo-950/20 dark:ring-indigo-800'
39
+ : 'hover:bg-zinc-50 dark:hover:bg-zinc-800'}`, children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "truncate font-mono text-[11px] font-medium", children: cap.name }), _jsx("span", { className: `shrink-0 rounded px-1 py-0.5 text-[9px] font-medium uppercase ${cap.performance === 'fast'
40
+ ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400'
41
+ : cap.performance === 'medium'
42
+ ? 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400'
43
+ : 'bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400'}`, children: cap.performance })] }), _jsx("p", { className: "mt-0.5 truncate text-[10px] text-zinc-500 dark:text-zinc-400", children: cap.description })] }) }, cap.name));
44
+ }) })] }, domain))) })) })] })] }));
45
+ }
46
+ //# sourceMappingURL=Inspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Inspector.js","sourceRoot":"","sources":["../../src/components/Inspector.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAM3C,MAAM,UAAU,SAAS,CAAC,EAAE,SAAS,GAAG,EAAE,EAAkB;IAC1D,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAEtE,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC;IAChE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE/D,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACnD,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAC7D,CAAC;IAEF,OAAO;IACP,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAA2B,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC1C,GAAG,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,aAAa,GAAG,YAAY,IAAI,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IAE7E,OAAO,CACL,iBACE,SAAS,EAAE,6EAA6E,SAAS,EAAE,aAGlG,aAAa,IAAI,CAChB,eAAK,SAAS,EAAC,wDAAwD,aACrE,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,aAAa,CAAC,EAC/C,SAAS,EAAC,2HAA2H,aAErI,eAAK,SAAS,EAAC,yBAAyB,aACtC,cAAK,SAAS,EAAE,8CAA8C,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAC,MAAM,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAE,CAAC,YAAE,eAAM,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,EAAC,CAAC,EAAC,cAAc,GAAE,GAAM,EACnP,eAAM,SAAS,EAAC,kEAAkE,0BAAiB,IAC/F,EACN,eAAM,SAAS,EAAC,gGAAgG,YAC7G,YAAY,CAAC,UAAU,GACnB,IACA,EACR,aAAa,IAAI,CAChB,cAAK,SAAS,EAAC,oCAAoC,YACjD,KAAC,SAAS,IACR,UAAU,EAAE,aAAa,CAAC,YAAY,CAAC,UAAU,CAAE,EACnD,MAAM,EAAE,YAAY,CAAC,MAAM,EAC3B,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,GAC/D,GACE,CACP,IACG,CACP,EAGD,eAAK,SAAS,EAAC,sCAAsC,aACnD,eAAK,SAAS,EAAC,oGAAoG,aACjH,eAAM,SAAS,EAAC,kEAAkE,6BAE3E,EACP,eAAM,SAAS,EAAC,wCAAwC,YAAE,QAAQ,CAAC,MAAM,GAAQ,IAC7E,EAGN,cAAK,SAAS,EAAC,4DAA4D,YACzE,eAAK,SAAS,EAAC,UAAU,aACvB,eAAK,SAAS,EAAC,gEAAgE,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAC,WAAW,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAE,CAAC,aAAE,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,GAAG,GAAE,EAAA,eAAM,CAAC,EAAC,gBAAgB,GAAE,IAAM,EACrN,gBACE,IAAI,EAAC,MAAM,EACX,WAAW,EAAC,wBAAwB,EACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC1C,SAAS,EAAC,uNAAuN,GACjO,IACE,GACF,EAGN,cAAK,SAAS,EAAC,4BAA4B,YACxC,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC3B,eAAK,SAAS,EAAC,uBAAuB,aACpC,YAAG,SAAS,EAAC,2BAA2B,uCAA2B,EACnE,YAAG,SAAS,EAAC,gCAAgC,6CAAiC,IAC1E,CACP,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC1B,YAAG,SAAS,EAAC,qCAAqC,yCAA6B,CAChF,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAC,WAAW,YACvB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CACrD,0BACE,cAAK,SAAS,EAAC,4EAA4E,YACxF,MAAM,GACH,EACN,aAAI,SAAS,EAAC,aAAa,YACxB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;4CAChB,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;4CAClE,OAAO,CACL,uBACE,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAChC,SAAS,EAAE,gEACT,YAAY;wDACV,CAAC,CAAC,mFAAmF;wDACrF,CAAC,CAAC,yCACN,EAAE,aAEF,eAAK,SAAS,EAAC,yCAAyC,aACtD,eAAM,SAAS,EAAC,4CAA4C,YAAE,GAAG,CAAC,IAAI,GAAQ,EAC9E,eAAM,SAAS,EAAE,iEACf,GAAG,CAAC,WAAW,KAAK,MAAM;wEACxB,CAAC,CAAC,8EAA8E;wEAChF,CAAC,CAAC,GAAG,CAAC,WAAW,KAAK,QAAQ;4EAC9B,CAAC,CAAC,sEAAsE;4EACxE,CAAC,CAAC,+DACN,EAAE,YACC,GAAG,CAAC,WAAW,GACX,IACH,EACN,YAAG,SAAS,EAAC,8DAA8D,YAAE,GAAG,CAAC,WAAW,GAAK,IAC1F,IAvBF,GAAG,CAAC,IAAI,CAwBZ,CACN,CAAC;wCACJ,CAAC,CAAC,GACC,KAnCG,MAAM,CAoCV,CACP,CAAC,GACE,CACP,GACG,IACF,IACA,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * ParamForm - 能力参数表单
3
+ *
4
+ * 根据 Capability 的 params Schema 自动生成表单。
5
+ * 紧凑行内布局,适配 Inspector 面板。
6
+ */
7
+ import type { Capability } from '@lokvis/schema';
8
+ export interface ParamFormProps {
9
+ capability: Capability;
10
+ values: Record<string, unknown>;
11
+ onChange: (values: Record<string, unknown>) => void;
12
+ }
13
+ export declare function ParamForm({ capability, values, onChange }: ParamFormProps): import("react").JSX.Element;
14
+ //# sourceMappingURL=ParamForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamForm.d.ts","sourceRoot":"","sources":["../../src/components/ParamForm.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,gBAAgB,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACrD;AAED,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,cAAc,+BAyBzE"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function ParamForm({ capability, values, onChange }) {
3
+ const set = (name, value) => {
4
+ onChange({ ...values, [name]: value });
5
+ };
6
+ if (capability.params.length === 0) {
7
+ return (_jsx("p", { className: "py-3 text-center text-[11px] text-zinc-400 italic", children: "This capability has no configurable parameters." }));
8
+ }
9
+ return (_jsx("div", { className: "space-y-2.5", children: capability.params.map((p) => (_jsx(ParamField, { param: p, value: values[p.name], onChange: (v) => set(p.name, v) }, p.name))) }));
10
+ }
11
+ const inputBase = 'w-full rounded-md border border-zinc-200 bg-white px-2.5 py-1.5 text-[11px] transition-colors focus:border-indigo-400 focus:outline-none focus:ring-1 focus:ring-indigo-400 dark:border-zinc-700 dark:bg-zinc-900';
12
+ function ParamField({ param, value, onChange, }) {
13
+ if (param.type === 'boolean') {
14
+ return (_jsxs("label", { className: "flex cursor-pointer items-center gap-2 rounded-md px-1 py-1 transition-colors hover:bg-zinc-50 dark:hover:bg-zinc-800/50", children: [_jsx("input", { type: "checkbox", checked: Boolean(value ?? param.default), onChange: (e) => onChange(e.target.checked), className: "h-3.5 w-3.5 rounded border-zinc-300 text-indigo-600 focus:ring-indigo-500" }), _jsx("span", { className: "flex-1 text-[11px] text-zinc-700 dark:text-zinc-300", children: param.name }), param.description && (_jsx("span", { className: "shrink-0 text-[10px] text-zinc-400", children: param.description }))] }));
15
+ }
16
+ if (param.type === 'enum' && param.values) {
17
+ return (_jsxs("div", { children: [_jsxs("label", { className: "mb-1 block text-[11px] font-medium text-zinc-600 dark:text-zinc-300", children: [param.name, param.required && _jsx("span", { className: "ml-0.5 text-red-500", children: "*" })] }), _jsx("select", { value: value ?? param.default ?? '', onChange: (e) => onChange(e.target.value), className: inputBase, children: param.values.map((v) => (_jsx("option", { value: v, children: v }, v))) })] }));
18
+ }
19
+ if (param.type === 'color') {
20
+ return (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-[11px] font-medium text-zinc-600 dark:text-zinc-300", children: param.name }), _jsxs("div", { className: "flex gap-2", children: [_jsx("input", { type: "color", value: value ?? param.default ?? '#ffffff', onChange: (e) => onChange(e.target.value), className: "h-7 w-7 shrink-0 cursor-pointer rounded border border-zinc-200 dark:border-zinc-700" }), _jsx("input", { type: "text", value: value ?? param.default ?? '#ffffff', onChange: (e) => onChange(e.target.value), className: inputBase })] })] }));
21
+ }
22
+ if (param.type === 'number') {
23
+ return (_jsxs("div", { children: [_jsxs("div", { className: "mb-1 flex items-center justify-between", children: [_jsxs("label", { className: "text-[11px] font-medium text-zinc-600 dark:text-zinc-300", children: [param.name, param.required && _jsx("span", { className: "ml-0.5 text-red-500", children: "*" })] }), (param.min !== undefined || param.max !== undefined) && (_jsxs("span", { className: "text-[10px] text-zinc-400", children: [param.min !== undefined ? param.min : '-', ' — ', param.max !== undefined ? param.max : '∞'] }))] }), _jsx("input", { type: "number", value: value === undefined ? param.default ?? '' : value, min: param.min, max: param.max, onChange: (e) => onChange(e.target.value === '' ? undefined : Number(e.target.value)), className: inputBase })] }));
24
+ }
25
+ // string / file / array / object → text input
26
+ return (_jsxs("div", { children: [_jsxs("label", { className: "mb-1 block text-[11px] font-medium text-zinc-600 dark:text-zinc-300", children: [param.name, param.required && _jsx("span", { className: "ml-0.5 text-red-500", children: "*" }), param.description && (_jsx("span", { className: "ml-1 font-normal text-zinc-400", children: param.description }))] }), _jsx("input", { type: "text", value: value ?? param.default ?? '', onChange: (e) => onChange(e.target.value), placeholder: param.type === 'file' ? 'data URL or path' : '', className: inputBase })] }));
27
+ }
28
+ //# sourceMappingURL=ParamForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParamForm.js","sourceRoot":"","sources":["../../src/components/ParamForm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * PipelineBar - 工作流管道条
3
+ *
4
+ * 显示当前工作流的节点序列,支持选中、删除节点。
5
+ * 位于 Canvas 下方、StatusBar 上方。
6
+ */
7
+ import * as React from 'react';
8
+ export interface PipelineBarProps {
9
+ className?: string;
10
+ }
11
+ export declare function PipelineBar({ className }: PipelineBarProps): React.JSX.Element;
12
+ //# sourceMappingURL=PipelineBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PipelineBar.d.ts","sourceRoot":"","sources":["../../src/components/PipelineBar.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,SAAc,EAAE,EAAE,gBAAgB,qBA6F/D"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * PipelineBar - 工作流管道条
4
+ *
5
+ * 显示当前工作流的节点序列,支持选中、删除节点。
6
+ * 位于 Canvas 下方、StatusBar 上方。
7
+ */
8
+ import * as React from 'react';
9
+ import { useWorkspaceStore } from '../store/index.js';
10
+ export function PipelineBar({ className = '' }) {
11
+ const nodes = useWorkspaceStore((s) => s.nodes);
12
+ const selectedNodeId = useWorkspaceStore((s) => s.selectedNodeId);
13
+ const selectNode = useWorkspaceStore((s) => s.selectNode);
14
+ const removeNode = useWorkspaceStore((s) => s.removeNode);
15
+ return (_jsxs("div", { className: `flex h-10 shrink-0 items-center gap-2 border-t border-zinc-200 bg-white px-3 dark:border-zinc-800 dark:bg-zinc-900 ${className}`, children: [_jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-zinc-400 shrink-0", children: "Pipeline" }), nodes.length === 0 ? (_jsx("span", { className: "text-[11px] text-zinc-400", children: "Empty \u2014 add capabilities from the right panel" })) : (_jsxs("div", { className: "flex flex-1 items-center gap-1 overflow-x-auto min-w-0", children: [_jsxs("div", { className: "flex 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 shrink-0", children: [_jsx("svg", { className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 4.5v15m7.5-7.5h-15" }) }), "Source"] }), _jsx("svg", { className: "h-3 w-3 shrink-0 text-zinc-300 dark:text-zinc-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m9 5 7 7-7 7" }) }), nodes.map((node, i) => {
16
+ const selected = node.id === selectedNodeId;
17
+ return (_jsxs(React.Fragment, { children: [_jsxs("button", { type: "button", onClick: () => selectNode(node.id), className: `group flex shrink-0 items-center gap-1.5 rounded-md px-2.5 py-1 text-[11px] font-medium transition-all ${selected
18
+ ? 'bg-indigo-100 text-indigo-700 ring-1 ring-indigo-300 dark:bg-indigo-950/50 dark:text-indigo-300 dark:ring-indigo-700'
19
+ : node.status === 'running'
20
+ ? 'bg-amber-100 text-amber-700 dark:bg-amber-950/30 dark:text-amber-400'
21
+ : node.status === 'success'
22
+ ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-950/30 dark:text-emerald-400'
23
+ : node.status === 'failed'
24
+ ? 'bg-red-100 text-red-700 dark:bg-red-950/30 dark:text-red-400'
25
+ : 'bg-zinc-100 text-zinc-700 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-700'}`, children: [_jsx("span", { className: "font-mono", children: node.capability }), _jsx(StatusDot, { status: node.status }), _jsx("span", { onClick: (e) => {
26
+ e.stopPropagation();
27
+ removeNode(node.id);
28
+ }, className: "ml-0.5 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", role: "button", "aria-label": "Remove step", children: _jsx("svg", { className: "h-2.5 w-2.5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 3, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) })] }), i < nodes.length - 1 && (_jsx("svg", { className: "h-3 w-3 shrink-0 text-zinc-300 dark:text-zinc-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m9 5 7 7-7 7" }) }))] }, node.id));
29
+ }), _jsx("svg", { className: "h-3 w-3 shrink-0 text-zinc-300 dark:text-zinc-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m9 5 7 7-7 7" }) }), _jsxs("div", { className: "flex 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 shrink-0", children: [_jsx("svg", { className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", 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("span", { className: "shrink-0 text-[10px] tabular-nums text-zinc-400", children: [nodes.length, " step", nodes.length !== 1 ? 's' : ''] }))] }));
30
+ }
31
+ function StatusDot({ status }) {
32
+ const color = status === 'running'
33
+ ? 'bg-amber-500'
34
+ : status === 'success'
35
+ ? 'bg-emerald-500'
36
+ : status === 'failed'
37
+ ? 'bg-red-500'
38
+ : status === 'pending'
39
+ ? 'bg-zinc-400 dark:bg-zinc-500'
40
+ : 'bg-zinc-300 dark:bg-zinc-600';
41
+ const animate = status === 'running' ? 'animate-pulse' : '';
42
+ return _jsx("span", { className: `h-1.5 w-1.5 rounded-full shrink-0 ${color} ${animate}` });
43
+ }
44
+ //# sourceMappingURL=PipelineBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PipelineBar.js","sourceRoot":"","sources":["../../src/components/PipelineBar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * StatusBar - 底部状态栏
3
+ *
4
+ * 紧凑单行:左侧状态指示,右侧资源统计。
5
+ */
6
+ export interface StatusBarProps {
7
+ className?: string;
8
+ }
9
+ export declare function StatusBar({ className }: StatusBarProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=StatusBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,SAAc,EAAE,EAAE,cAAc,+BAkD3D"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * StatusBar - 底部状态栏
4
+ *
5
+ * 紧凑单行:左侧状态指示,右侧资源统计。
6
+ */
7
+ import { useWorkspaceStore } from '../store/index.js';
8
+ export function StatusBar({ className = '' }) {
9
+ const statusMessage = useWorkspaceStore((s) => s.statusMessage);
10
+ const error = useWorkspaceStore((s) => s.error);
11
+ const running = useWorkspaceStore((s) => s.running);
12
+ const assets = useWorkspaceStore((s) => s.assets);
13
+ const capabilities = useWorkspaceStore((s) => s.capabilities);
14
+ const nodes = useWorkspaceStore((s) => s.nodes);
15
+ const setError = useWorkspaceStore((s) => s.setError);
16
+ return (_jsxs("footer", { className: `flex h-7 shrink-0 items-center justify-between border-t border-zinc-200 bg-zinc-50 px-3 dark:border-zinc-800 dark:bg-zinc-950 ${className}`, children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: `h-1.5 w-1.5 rounded-full shrink-0 ${error
17
+ ? 'bg-red-500'
18
+ : running
19
+ ? 'bg-amber-500 animate-pulse'
20
+ : 'bg-emerald-500'}` }), _jsx("span", { className: `truncate text-[10px] ${error ? 'text-red-500' : 'text-zinc-500'}`, children: statusMessage })] }), error && (_jsx("button", { type: "button", onClick: () => setError(null), className: "shrink-0 text-[10px] text-red-500 underline decoration-red-300 hover:text-red-600 dark:decoration-red-800", children: "dismiss" }))] }), _jsxs("div", { className: "flex items-center gap-3 shrink-0 text-[10px] text-zinc-400 tabular-nums", children: [_jsxs("span", { children: [assets.length, " asset", assets.length !== 1 ? 's' : ''] }), _jsx("span", { className: "text-zinc-300 dark:text-zinc-700", children: "|" }), _jsxs("span", { children: [capabilities.length, " cap", capabilities.length !== 1 ? 's' : ''] }), _jsx("span", { className: "text-zinc-300 dark:text-zinc-700", children: "|" }), _jsxs("span", { children: [nodes.length, " step", nodes.length !== 1 ? 's' : ''] })] })] }));
21
+ }
22
+ //# sourceMappingURL=StatusBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAMtD,MAAM,UAAU,SAAS,CAAC,EAAE,SAAS,GAAG,EAAE,EAAkB;IAC1D,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,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEtD,OAAO,CACL,kBACE,SAAS,EAAE,iIAAiI,SAAS,EAAE,aAGvJ,eAAK,SAAS,EAAC,iCAAiC,aAC9C,gBAAM,SAAS,EAAC,2BAA2B,aACzC,eACE,SAAS,EAAE,qCACT,KAAK;oCACH,CAAC,CAAC,YAAY;oCACd,CAAC,CAAC,OAAO;wCACT,CAAC,CAAC,4BAA4B;wCAC9B,CAAC,CAAC,gBACN,EAAE,GACF,EACF,eAAM,SAAS,EAAE,wBAAwB,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,EAAE,YAChF,aAAa,GACT,IACF,EACN,KAAK,IAAI,CACR,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC7B,SAAS,EAAC,2GAA2G,wBAG9G,CACV,IACG,EAGN,eAAK,SAAS,EAAC,yEAAyE,aACtF,2BAAO,MAAM,CAAC,MAAM,YAAQ,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAQ,EAClE,eAAM,SAAS,EAAC,kCAAkC,kBAAS,EAC3D,2BAAO,YAAY,CAAC,MAAM,UAAM,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAQ,EAC5E,eAAM,SAAS,EAAC,kCAAkC,kBAAS,EAC3D,2BAAO,KAAK,CAAC,MAAM,WAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAQ,IAC3D,IACC,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Toolbar - 工作台顶部工具栏
3
+ *
4
+ * 左:Logo + 标题
5
+ * 中:状态消息
6
+ * 右:操作按钮组
7
+ */
8
+ import * as React from 'react';
9
+ export interface ToolbarProps {
10
+ title?: string;
11
+ rightExtra?: React.ReactNode;
12
+ }
13
+ export declare function Toolbar({ title, rightExtra }: ToolbarProps): React.JSX.Element;
14
+ //# sourceMappingURL=Toolbar.d.ts.map
@@ -0,0 +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"}