@geenius/ai-workflow 0.1.0 → 0.4.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 (159) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +69 -1
  3. package/package.json +60 -27
  4. package/packages/convex/dist/index.d.ts +363 -0
  5. package/packages/convex/dist/index.js +200 -0
  6. package/packages/convex/dist/index.js.map +1 -0
  7. package/packages/react/dist/index.d.ts +466 -0
  8. package/packages/react/dist/index.js +13914 -0
  9. package/packages/react/dist/index.js.map +1 -0
  10. package/packages/react-css/{src/styles.css → dist/index.css} +107 -253
  11. package/packages/react-css/dist/index.css.map +1 -0
  12. package/packages/react-css/dist/index.d.ts +495 -0
  13. package/packages/react-css/dist/index.js +13901 -0
  14. package/packages/react-css/dist/index.js.map +1 -0
  15. package/packages/shared/dist/index.d.ts +1368 -0
  16. package/packages/shared/dist/index.js +1681 -0
  17. package/packages/shared/dist/index.js.map +1 -0
  18. package/packages/solidjs/dist/index.d.ts +452 -0
  19. package/packages/solidjs/dist/index.js +13830 -0
  20. package/packages/solidjs/dist/index.js.map +1 -0
  21. package/packages/solidjs-css/{src/styles.css → dist/index.css} +107 -253
  22. package/packages/solidjs-css/dist/index.css.map +1 -0
  23. package/packages/solidjs-css/dist/index.d.ts +471 -0
  24. package/packages/solidjs-css/dist/index.js +13774 -0
  25. package/packages/solidjs-css/dist/index.js.map +1 -0
  26. package/.changeset/config.json +0 -11
  27. package/.github/CODEOWNERS +0 -1
  28. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
  29. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
  30. package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
  31. package/.github/dependabot.yml +0 -11
  32. package/.github/workflows/ci.yml +0 -23
  33. package/.github/workflows/release.yml +0 -29
  34. package/.nvmrc +0 -1
  35. package/.project/ACCOUNT.yaml +0 -4
  36. package/.project/IDEAS.yaml +0 -7
  37. package/.project/PROJECT.yaml +0 -11
  38. package/.project/ROADMAP.yaml +0 -15
  39. package/CODE_OF_CONDUCT.md +0 -16
  40. package/CONTRIBUTING.md +0 -26
  41. package/SECURITY.md +0 -15
  42. package/SUPPORT.md +0 -8
  43. package/packages/convex/README.md +0 -1
  44. package/packages/convex/package.json +0 -12
  45. package/packages/convex/src/convex.config.ts +0 -3
  46. package/packages/convex/src/index.ts +0 -3
  47. package/packages/convex/src/mutations.ts +0 -36
  48. package/packages/convex/src/queries.ts +0 -19
  49. package/packages/convex/src/schema.ts +0 -24
  50. package/packages/convex/tsconfig.json +0 -25
  51. package/packages/react/README.md +0 -1
  52. package/packages/react/package.json +0 -46
  53. package/packages/react/src/components/ApprovalModal.tsx +0 -47
  54. package/packages/react/src/components/StepConfigPanel.tsx +0 -67
  55. package/packages/react/src/components/StepConnector.tsx +0 -47
  56. package/packages/react/src/components/StepNode.tsx +0 -38
  57. package/packages/react/src/components/StepPalette.tsx +0 -48
  58. package/packages/react/src/components/WorkflowCanvas.tsx +0 -42
  59. package/packages/react/src/components/WorkflowRunPanel.tsx +0 -64
  60. package/packages/react/src/components/WorkflowToolbar.tsx +0 -43
  61. package/packages/react/src/components/index.ts +0 -9
  62. package/packages/react/src/hooks/index.ts +0 -10
  63. package/packages/react/src/hooks/useApprovalGate.ts +0 -59
  64. package/packages/react/src/hooks/useWorkflow.ts +0 -39
  65. package/packages/react/src/hooks/useWorkflowBuilder.ts +0 -121
  66. package/packages/react/src/hooks/useWorkflowRun.ts +0 -75
  67. package/packages/react/src/hooks/useWorkflowStep.ts +0 -52
  68. package/packages/react/src/hooks/useWorkflowTemplates.ts +0 -54
  69. package/packages/react/src/index.ts +0 -16
  70. package/packages/react/src/pages/WorkflowBuilderPage.tsx +0 -81
  71. package/packages/react/src/pages/WorkflowRunsPage.tsx +0 -59
  72. package/packages/react/src/pages/index.ts +0 -3
  73. package/packages/react/tsconfig.json +0 -1
  74. package/packages/react/tsup.config.ts +0 -7
  75. package/packages/react-css/README.md +0 -1
  76. package/packages/react-css/package.json +0 -44
  77. package/packages/react-css/src/components/ApprovalModal.tsx +0 -6
  78. package/packages/react-css/src/components/StepConfigPanel.tsx +0 -7
  79. package/packages/react-css/src/components/StepConnector.tsx +0 -6
  80. package/packages/react-css/src/components/StepNode.tsx +0 -7
  81. package/packages/react-css/src/components/StepPalette.tsx +0 -6
  82. package/packages/react-css/src/components/WorkflowCanvas.tsx +0 -6
  83. package/packages/react-css/src/components/WorkflowRunPanel.tsx +0 -9
  84. package/packages/react-css/src/components/WorkflowToolbar.tsx +0 -4
  85. package/packages/react-css/src/components/index.ts +0 -9
  86. package/packages/react-css/src/hooks/index.ts +0 -3
  87. package/packages/react-css/src/hooks/useWorkflow.ts +0 -39
  88. package/packages/react-css/src/hooks/useWorkflowBuilder.ts +0 -121
  89. package/packages/react-css/src/index.ts +0 -7
  90. package/packages/react-css/src/pages/WorkflowBuilderPage.tsx +0 -16
  91. package/packages/react-css/src/pages/WorkflowRunsPage.tsx +0 -6
  92. package/packages/react-css/src/pages/index.ts +0 -3
  93. package/packages/react-css/tsconfig.json +0 -26
  94. package/packages/react-css/tsup.config.ts +0 -2
  95. package/packages/shared/README.md +0 -1
  96. package/packages/shared/package.json +0 -56
  97. package/packages/shared/src/__tests__/ai-workflow.test.ts +0 -217
  98. package/packages/shared/src/config.ts +0 -49
  99. package/packages/shared/src/convex/index.ts +0 -2
  100. package/packages/shared/src/convex/schemas.ts +0 -42
  101. package/packages/shared/src/engine.test.ts +0 -1
  102. package/packages/shared/src/engine.ts +0 -295
  103. package/packages/shared/src/index.ts +0 -43
  104. package/packages/shared/src/steps.ts +0 -68
  105. package/packages/shared/src/templates.ts +0 -172
  106. package/packages/shared/src/types.ts +0 -237
  107. package/packages/shared/src/utils/cost.ts +0 -79
  108. package/packages/shared/src/utils/dag.ts +0 -133
  109. package/packages/shared/src/utils/index.ts +0 -5
  110. package/packages/shared/src/utils/interpolation.ts +0 -53
  111. package/packages/shared/src/validators.ts +0 -215
  112. package/packages/shared/tsconfig.json +0 -1
  113. package/packages/shared/tsup.config.ts +0 -5
  114. package/packages/shared/vitest.config.ts +0 -4
  115. package/packages/solidjs/README.md +0 -1
  116. package/packages/solidjs/package.json +0 -45
  117. package/packages/solidjs/src/components/ApprovalModal.tsx +0 -18
  118. package/packages/solidjs/src/components/StepConfigPanel.tsx +0 -14
  119. package/packages/solidjs/src/components/StepConnector.tsx +0 -11
  120. package/packages/solidjs/src/components/StepNode.tsx +0 -12
  121. package/packages/solidjs/src/components/StepPalette.tsx +0 -22
  122. package/packages/solidjs/src/components/WorkflowCanvas.tsx +0 -23
  123. package/packages/solidjs/src/components/WorkflowRunPanel.tsx +0 -18
  124. package/packages/solidjs/src/components/WorkflowToolbar.tsx +0 -13
  125. package/packages/solidjs/src/components/index.ts +0 -9
  126. package/packages/solidjs/src/index.ts +0 -7
  127. package/packages/solidjs/src/pages/WorkflowBuilderPage.tsx +0 -37
  128. package/packages/solidjs/src/pages/WorkflowRunsPage.tsx +0 -20
  129. package/packages/solidjs/src/pages/index.ts +0 -3
  130. package/packages/solidjs/src/primitives/createApprovalGate.ts +0 -29
  131. package/packages/solidjs/src/primitives/createWorkflow.ts +0 -28
  132. package/packages/solidjs/src/primitives/createWorkflowBuilder.ts +0 -56
  133. package/packages/solidjs/src/primitives/createWorkflowRun.ts +0 -32
  134. package/packages/solidjs/src/primitives/createWorkflowStep.ts +0 -23
  135. package/packages/solidjs/src/primitives/createWorkflowTemplates.ts +0 -28
  136. package/packages/solidjs/src/primitives/index.ts +0 -8
  137. package/packages/solidjs/tsconfig.json +0 -1
  138. package/packages/solidjs/tsup.config.ts +0 -7
  139. package/packages/solidjs-css/README.md +0 -1
  140. package/packages/solidjs-css/package.json +0 -43
  141. package/packages/solidjs-css/src/components/ApprovalModal.tsx +0 -6
  142. package/packages/solidjs-css/src/components/StepConfigPanel.tsx +0 -7
  143. package/packages/solidjs-css/src/components/StepConnector.tsx +0 -6
  144. package/packages/solidjs-css/src/components/StepNode.tsx +0 -7
  145. package/packages/solidjs-css/src/components/StepPalette.tsx +0 -7
  146. package/packages/solidjs-css/src/components/WorkflowCanvas.tsx +0 -7
  147. package/packages/solidjs-css/src/components/WorkflowRunPanel.tsx +0 -8
  148. package/packages/solidjs-css/src/components/WorkflowToolbar.tsx +0 -5
  149. package/packages/solidjs-css/src/components/index.ts +0 -9
  150. package/packages/solidjs-css/src/index.ts +0 -7
  151. package/packages/solidjs-css/src/pages/WorkflowBuilderPage.tsx +0 -2
  152. package/packages/solidjs-css/src/pages/WorkflowRunsPage.tsx +0 -7
  153. package/packages/solidjs-css/src/pages/index.ts +0 -3
  154. package/packages/solidjs-css/src/primitives/createWorkflow.ts +0 -28
  155. package/packages/solidjs-css/src/primitives/createWorkflowBuilder.ts +0 -56
  156. package/packages/solidjs-css/src/primitives/index.ts +0 -1
  157. package/packages/solidjs-css/tsconfig.json +0 -27
  158. package/packages/solidjs-css/tsup.config.ts +0 -2
  159. package/pnpm-workspace.yaml +0 -2
@@ -1,48 +0,0 @@
1
- // @geenius-ai-workflow/react — components/StepPalette.tsx
2
- import type { StepType } from '@geenius-ai-workflow/shared'
3
-
4
- export interface StepPaletteItem {
5
- type: StepType
6
- label: string
7
- icon: string
8
- description: string
9
- }
10
-
11
- const PALETTE_ITEMS: StepPaletteItem[] = [
12
- { type: 'llm-call', label: 'LLM Call', icon: '🤖', description: 'Call an AI model' },
13
- { type: 'transform', label: 'Transform', icon: '⚙️', description: 'Transform data' },
14
- { type: 'condition', label: 'Condition', icon: '🔀', description: 'If/else branching' },
15
- { type: 'human-approval', label: 'Approval', icon: '👤', description: 'Human approval gate' },
16
- { type: 'webhook', label: 'Webhook', icon: '🌐', description: 'HTTP request' },
17
- { type: 'delay', label: 'Delay', icon: '⏱️', description: 'Wait for duration' },
18
- { type: 'parallel', label: 'Parallel', icon: '⚡', description: 'Run steps in parallel' },
19
- { type: 'loop', label: 'Loop', icon: '🔄', description: 'Iterate over items' },
20
- { type: 'sub-workflow', label: 'Sub-workflow', icon: '📋', description: 'Run another workflow' },
21
- { type: 'custom', label: 'Custom', icon: '🔧', description: 'Custom handler' },
22
- ]
23
-
24
- export interface StepPaletteProps {
25
- onAddStep: (type: StepType) => void
26
- }
27
-
28
- export function StepPalette({ onAddStep }: StepPaletteProps) {
29
- return (
30
- <div data-workflow="step-palette" role="list" aria-label="Available step types">
31
- <h3 data-workflow="palette-title">Steps</h3>
32
- {PALETTE_ITEMS.map(item => (
33
- <button
34
- key={item.type}
35
- data-workflow="palette-item"
36
- role="listitem"
37
- onClick={() => onAddStep(item.type)}
38
- >
39
- <span data-workflow="palette-icon">{item.icon}</span>
40
- <div data-workflow="palette-info">
41
- <span data-workflow="palette-label">{item.label}</span>
42
- <span data-workflow="palette-desc">{item.description}</span>
43
- </div>
44
- </button>
45
- ))}
46
- </div>
47
- )
48
- }
@@ -1,42 +0,0 @@
1
- // @geenius-ai-workflow/react — components/WorkflowCanvas.tsx
2
- import type { WorkflowDefinition, WorkflowStepDef } from '@geenius-ai-workflow/shared'
3
- import { StepNode } from './StepNode'
4
- import { StepConnector } from './StepConnector'
5
-
6
- export interface WorkflowCanvasProps {
7
- definition: WorkflowDefinition
8
- selectedStepId: string | null
9
- onSelectStep: (id: string | null) => void
10
- onMoveStep?: (stepId: string, pos: { x: number; y: number }) => void
11
- }
12
-
13
- export function WorkflowCanvas({ definition, selectedStepId, onSelectStep, onMoveStep }: WorkflowCanvasProps) {
14
- return (
15
- <div data-workflow="canvas" role="application" aria-label="Workflow canvas">
16
- <svg data-workflow="connections-layer" style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
17
- {definition.connections.map((conn, i) => {
18
- const from = definition.steps.find(s => s.id === conn.fromStepId)
19
- const to = definition.steps.find(s => s.id === conn.toStepId)
20
- if (!from?.position || !to?.position) return null
21
- return <StepConnector key={i} from={from.position} to={to.position} label={conn.label} />
22
- })}
23
- </svg>
24
- <div data-workflow="nodes-layer">
25
- {definition.steps.map(step => (
26
- <StepNode
27
- key={step.id}
28
- step={step}
29
- isSelected={selectedStepId === step.id}
30
- onClick={() => onSelectStep(step.id === selectedStepId ? null : step.id)}
31
- />
32
- ))}
33
- </div>
34
- {definition.steps.length === 0 && (
35
- <div data-workflow="canvas-empty">
36
- <p data-workflow="empty-title">No steps yet</p>
37
- <p data-workflow="empty-hint">Drag steps from the palette or use a template</p>
38
- </div>
39
- )}
40
- </div>
41
- )
42
- }
@@ -1,64 +0,0 @@
1
- // @geenius-ai-workflow/react — components/WorkflowRunPanel.tsx
2
- import type { WorkflowRun, StepResult } from '@geenius-ai-workflow/shared'
3
- import { formatCost } from '@geenius-ai-workflow/shared'
4
-
5
- export interface WorkflowRunPanelProps {
6
- run: WorkflowRun | null
7
- isRunning: boolean
8
- onCancel?: () => void
9
- }
10
-
11
- const STATUS_ICONS: Record<string, string> = {
12
- pending: '⏳', running: '🔄', completed: '✅', failed: '❌', skipped: '⏭️', 'waiting-approval': '👤',
13
- }
14
-
15
- export function WorkflowRunPanel({ run, isRunning, onCancel }: WorkflowRunPanelProps) {
16
- if (!run) {
17
- return (
18
- <div data-workflow="run-panel">
19
- <div data-workflow="run-empty"><p>No active run. Click "Run" to execute the workflow.</p></div>
20
- </div>
21
- )
22
- }
23
-
24
- const completedCount = run.stepResults.filter(s => s.status === 'completed').length
25
- const totalCount = run.stepResults.length
26
- const progress = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0
27
- const totalCost = run.stepResults.reduce((sum, s) => sum + (s.costUsd ?? 0), 0)
28
- const totalTokens = run.stepResults.reduce((sum, s) => sum + (s.tokens ?? 0), 0)
29
- const duration = (run.completedAt ?? Date.now()) - run.startedAt
30
-
31
- return (
32
- <div data-workflow="run-panel" data-status={run.status}>
33
- <div data-workflow="run-header">
34
- <h3 data-workflow="run-title">
35
- {STATUS_ICONS[run.status]} Run {run.status}
36
- </h3>
37
- {isRunning && onCancel && (
38
- <button data-workflow="run-cancel" onClick={onCancel}>⏹ Cancel</button>
39
- )}
40
- </div>
41
- <div data-workflow="run-progress">
42
- <div data-workflow="run-progress-bar">
43
- <div data-workflow="run-progress-fill" style={{ width: `${progress}%` }} />
44
- </div>
45
- <span data-workflow="run-progress-text">{completedCount}/{totalCount} steps ({progress}%)</span>
46
- </div>
47
- <div data-workflow="run-stats">
48
- <span data-workflow="run-stat">⏱ {(duration / 1000).toFixed(1)}s</span>
49
- {totalTokens > 0 && <span data-workflow="run-stat">🪙 {totalTokens.toLocaleString()} tokens</span>}
50
- {totalCost > 0 && <span data-workflow="run-stat">💰 {formatCost(totalCost)}</span>}
51
- </div>
52
- {run.error && <div data-workflow="run-error" role="alert">{run.error}</div>}
53
- <ul data-workflow="run-steps">
54
- {run.stepResults.map(r => (
55
- <li key={r.stepId} data-workflow="run-step-item" data-status={r.status}>
56
- <span data-workflow="run-step-icon">{STATUS_ICONS[r.status]}</span>
57
- <span data-workflow="run-step-name">{r.stepName}</span>
58
- <span data-workflow="run-step-duration">{r.durationMs}ms</span>
59
- </li>
60
- ))}
61
- </ul>
62
- </div>
63
- )
64
- }
@@ -1,43 +0,0 @@
1
- // @geenius-ai-workflow/react — components/WorkflowToolbar.tsx
2
-
3
- export interface WorkflowToolbarProps {
4
- workflowName: string
5
- isDirty: boolean
6
- isRunning: boolean
7
- canUndo: boolean
8
- canRedo: boolean
9
- onSave: () => void
10
- onRun: () => void
11
- onCancel?: () => void
12
- onUndo: () => void
13
- onRedo: () => void
14
- onExport?: () => void
15
- }
16
-
17
- export function WorkflowToolbar(props: WorkflowToolbarProps) {
18
- return (
19
- <div data-workflow="toolbar" role="toolbar" aria-label="Workflow actions">
20
- <div data-workflow="toolbar-left">
21
- <h2 data-workflow="toolbar-title">{props.workflowName}</h2>
22
- {props.isDirty && <span data-workflow="toolbar-dirty">●</span>}
23
- </div>
24
- <div data-workflow="toolbar-center">
25
- <button data-workflow="toolbar-btn" onClick={props.onUndo} disabled={!props.canUndo} title="Undo">↶</button>
26
- <button data-workflow="toolbar-btn" onClick={props.onRedo} disabled={!props.canRedo} title="Redo">↷</button>
27
- </div>
28
- <div data-workflow="toolbar-right">
29
- {props.onExport && (
30
- <button data-workflow="toolbar-btn-secondary" onClick={props.onExport}>📤 Export</button>
31
- )}
32
- <button data-workflow="toolbar-btn-secondary" onClick={props.onSave} disabled={!props.isDirty}>
33
- 💾 Save
34
- </button>
35
- {props.isRunning ? (
36
- <button data-workflow="toolbar-btn-danger" onClick={props.onCancel}>⏹ Stop</button>
37
- ) : (
38
- <button data-workflow="toolbar-btn-primary" onClick={props.onRun}>▶ Run</button>
39
- )}
40
- </div>
41
- </div>
42
- )
43
- }
@@ -1,9 +0,0 @@
1
- // @geenius-ai-workflow/react — components/index.ts
2
- export { WorkflowCanvas, type WorkflowCanvasProps } from './WorkflowCanvas'
3
- export { StepNode, type StepNodeProps } from './StepNode'
4
- export { StepConnector, type StepConnectorProps } from './StepConnector'
5
- export { StepConfigPanel, type StepConfigPanelProps } from './StepConfigPanel'
6
- export { WorkflowRunPanel, type WorkflowRunPanelProps } from './WorkflowRunPanel'
7
- export { ApprovalModal, type ApprovalModalProps } from './ApprovalModal'
8
- export { WorkflowToolbar, type WorkflowToolbarProps } from './WorkflowToolbar'
9
- export { StepPalette, type StepPaletteProps } from './StepPalette'
@@ -1,10 +0,0 @@
1
- // @geenius-ai-workflow/react — src/hooks/index.ts
2
- export { useWorkflow } from './useWorkflow'
3
- export type { UseWorkflowOptions } from './useWorkflow'
4
- export { useWorkflowBuilder } from './useWorkflowBuilder'
5
- export { useWorkflowRun } from './useWorkflowRun'
6
- export type { UseWorkflowRunOptions } from './useWorkflowRun'
7
- export { useWorkflowStep } from './useWorkflowStep'
8
- export { useApprovalGate } from './useApprovalGate'
9
- export type { ApprovalRequest } from './useApprovalGate'
10
- export { useWorkflowTemplates } from './useWorkflowTemplates'
@@ -1,59 +0,0 @@
1
- // @geenius-ai-workflow/react — src/hooks/useApprovalGate.ts
2
- import { useState, useCallback } from 'react'
3
-
4
- export interface ApprovalRequest {
5
- id: string
6
- stepId: string
7
- message: string
8
- requestedAt: number
9
- approvers?: string[]
10
- }
11
-
12
- export function useApprovalGate() {
13
- const [pendingApprovals, setPendingApprovals] = useState<ApprovalRequest[]>([])
14
- const [history, setHistory] = useState<Array<ApprovalRequest & { decision: 'approved' | 'rejected'; decidedAt: number }>>([])
15
-
16
- const requestApproval = useCallback((stepId: string, message: string, approvers?: string[]) => {
17
- const request: ApprovalRequest = {
18
- id: `approval_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,
19
- stepId,
20
- message,
21
- requestedAt: Date.now(),
22
- approvers,
23
- }
24
- setPendingApprovals(prev => [...prev, request])
25
- return request.id
26
- }, [])
27
-
28
- const approve = useCallback((approvalId: string) => {
29
- setPendingApprovals(prev => {
30
- const request = prev.find(a => a.id === approvalId)
31
- if (request) {
32
- setHistory(h => [...h, { ...request, decision: 'approved', decidedAt: Date.now() }])
33
- }
34
- return prev.filter(a => a.id !== approvalId)
35
- })
36
- }, [])
37
-
38
- const reject = useCallback((approvalId: string) => {
39
- setPendingApprovals(prev => {
40
- const request = prev.find(a => a.id === approvalId)
41
- if (request) {
42
- setHistory(h => [...h, { ...request, decision: 'rejected', decidedAt: Date.now() }])
43
- }
44
- return prev.filter(a => a.id !== approvalId)
45
- })
46
- }, [])
47
-
48
- const clearHistory = useCallback(() => setHistory([]), [])
49
-
50
- return {
51
- pendingApprovals,
52
- history,
53
- hasPending: pendingApprovals.length > 0,
54
- requestApproval,
55
- approve,
56
- reject,
57
- clearHistory,
58
- }
59
- }
@@ -1,39 +0,0 @@
1
- // @geenius-ai-workflow/react — src/hooks/useWorkflow.ts
2
- import { useState, useCallback } from 'react'
3
- import type { WorkflowDefinition, WorkflowRun, StepResult } from '@geenius-ai-workflow/shared'
4
- import { WorkflowEngine } from '@geenius-ai-workflow/shared'
5
- import type { WorkflowEngineOptions } from '@geenius-ai-workflow/shared'
6
-
7
- export interface UseWorkflowOptions extends WorkflowEngineOptions { }
8
-
9
- export function useWorkflow(options: UseWorkflowOptions) {
10
- const [run, setRun] = useState<WorkflowRun | null>(null)
11
- const [isRunning, setIsRunning] = useState(false)
12
- const [error, setError] = useState<Error | null>(null)
13
- const [stepResults, setStepResults] = useState<StepResult[]>([])
14
-
15
- const engine = new WorkflowEngine({
16
- ...options,
17
- onStepComplete: (result) => {
18
- setStepResults(prev => [...prev, result])
19
- options.onStepComplete?.(result)
20
- },
21
- })
22
-
23
- const execute = useCallback(async (definition: WorkflowDefinition, input?: Record<string, unknown>) => {
24
- setIsRunning(true); setError(null); setStepResults([])
25
- try {
26
- const result = await engine.execute(definition, input)
27
- setRun(result)
28
- return result
29
- } catch (err) {
30
- const e = err instanceof Error ? err : new Error(String(err))
31
- setError(e); throw e
32
- } finally { setIsRunning(false) }
33
- }, [])
34
-
35
- const cancel = useCallback(() => engine.cancel(), [])
36
- const reset = useCallback(() => { setRun(null); setError(null); setStepResults([]) }, [])
37
-
38
- return { execute, cancel, run, isRunning, error, stepResults, reset }
39
- }
@@ -1,121 +0,0 @@
1
- // @geenius-ai-workflow/react — src/hooks/useWorkflowBuilder.ts
2
- import { useState, useCallback } from 'react'
3
- import type { WorkflowDefinition, WorkflowStepDef, StepConnection, WorkflowBuilderState } from '@geenius-ai-workflow/shared'
4
-
5
- const emptyDef = (): WorkflowDefinition => ({
6
- id: crypto.randomUUID?.() ?? String(Date.now()),
7
- name: 'New Workflow',
8
- version: 1,
9
- status: 'draft',
10
- steps: [],
11
- connections: [],
12
- createdBy: '',
13
- createdAt: Date.now(),
14
- updatedAt: Date.now(),
15
- })
16
-
17
- export function useWorkflowBuilder(initial?: Partial<WorkflowDefinition>) {
18
- const [state, setState] = useState<WorkflowBuilderState>({
19
- definition: { ...emptyDef(), ...initial },
20
- selectedStepId: null,
21
- isDirty: false,
22
- undoStack: [],
23
- redoStack: [],
24
- })
25
-
26
- const pushUndo = useCallback(() => {
27
- setState(prev => ({ ...prev, undoStack: [...prev.undoStack.slice(-20), prev.definition], redoStack: [] }))
28
- }, [])
29
-
30
- const addStep = useCallback((step: WorkflowStepDef) => {
31
- pushUndo()
32
- setState(prev => ({
33
- ...prev,
34
- isDirty: true,
35
- definition: { ...prev.definition, steps: [...prev.definition.steps, step], updatedAt: Date.now() },
36
- }))
37
- }, [pushUndo])
38
-
39
- const removeStep = useCallback((stepId: string) => {
40
- pushUndo()
41
- setState(prev => ({
42
- ...prev,
43
- isDirty: true,
44
- definition: {
45
- ...prev.definition,
46
- steps: prev.definition.steps.filter(s => s.id !== stepId),
47
- connections: prev.definition.connections.filter(c => c.fromStepId !== stepId && c.toStepId !== stepId),
48
- updatedAt: Date.now(),
49
- },
50
- selectedStepId: prev.selectedStepId === stepId ? null : prev.selectedStepId,
51
- }))
52
- }, [pushUndo])
53
-
54
- const updateStep = useCallback((stepId: string, updates: Partial<WorkflowStepDef>) => {
55
- pushUndo()
56
- setState(prev => ({
57
- ...prev,
58
- isDirty: true,
59
- definition: {
60
- ...prev.definition,
61
- steps: prev.definition.steps.map(s => s.id === stepId ? { ...s, ...updates } : s),
62
- updatedAt: Date.now(),
63
- },
64
- }))
65
- }, [pushUndo])
66
-
67
- const addConnection = useCallback((conn: StepConnection) => {
68
- pushUndo()
69
- setState(prev => ({
70
- ...prev,
71
- isDirty: true,
72
- definition: { ...prev.definition, connections: [...prev.definition.connections, conn], updatedAt: Date.now() },
73
- }))
74
- }, [pushUndo])
75
-
76
- const removeConnection = useCallback((fromStepId: string, toStepId: string) => {
77
- pushUndo()
78
- setState(prev => ({
79
- ...prev,
80
- isDirty: true,
81
- definition: {
82
- ...prev.definition,
83
- connections: prev.definition.connections.filter(c => !(c.fromStepId === fromStepId && c.toStepId === toStepId)),
84
- updatedAt: Date.now(),
85
- },
86
- }))
87
- }, [pushUndo])
88
-
89
- const selectStep = useCallback((stepId: string | null) => setState(prev => ({ ...prev, selectedStepId: stepId })), [])
90
-
91
- const undo = useCallback(() => {
92
- setState(prev => {
93
- if (prev.undoStack.length === 0) return prev
94
- const previous = prev.undoStack[prev.undoStack.length - 1]
95
- return { ...prev, definition: previous, undoStack: prev.undoStack.slice(0, -1), redoStack: [prev.definition, ...prev.redoStack] }
96
- })
97
- }, [])
98
-
99
- const redo = useCallback(() => {
100
- setState(prev => {
101
- if (prev.redoStack.length === 0) return prev
102
- const next = prev.redoStack[0]
103
- return { ...prev, definition: next, undoStack: [...prev.undoStack, prev.definition], redoStack: prev.redoStack.slice(1) }
104
- })
105
- }, [])
106
-
107
- const setDefinition = useCallback((def: WorkflowDefinition) => {
108
- setState(prev => ({ ...prev, definition: def, isDirty: false, undoStack: [], redoStack: [] }))
109
- }, [])
110
-
111
- return {
112
- definition: state.definition,
113
- selectedStepId: state.selectedStepId,
114
- isDirty: state.isDirty,
115
- canUndo: state.undoStack.length > 0,
116
- canRedo: state.redoStack.length > 0,
117
- addStep, removeStep, updateStep,
118
- addConnection, removeConnection,
119
- selectStep, undo, redo, setDefinition,
120
- }
121
- }
@@ -1,75 +0,0 @@
1
- // @geenius-ai-workflow/react — src/hooks/useWorkflowRun.ts
2
- import { useState, useCallback, useRef, useEffect } from 'react'
3
- import type { WorkflowRun, StepResult, RunStatus } from '@geenius-ai-workflow/shared'
4
-
5
- export interface UseWorkflowRunOptions {
6
- /** Poll interval for checking run status (ms) */
7
- pollIntervalMs?: number
8
- /** Callback when a step completes */
9
- onStepComplete?: (result: StepResult) => void
10
- /** Callback when the run finishes */
11
- onRunComplete?: (run: WorkflowRun) => void
12
- }
13
-
14
- export function useWorkflowRun(options: UseWorkflowRunOptions = {}) {
15
- const [run, setRun] = useState<WorkflowRun | null>(null)
16
- const [currentStepIndex, setCurrentStepIndex] = useState(0)
17
- const [completedSteps, setCompletedSteps] = useState<StepResult[]>([])
18
- const [status, setStatus] = useState<RunStatus>('pending')
19
- const [progress, setProgress] = useState(0)
20
- const [error, setError] = useState<string | null>(null)
21
- const timerRef = useRef<ReturnType<typeof setInterval> | null>(null)
22
-
23
- const trackRun = useCallback((workflowRun: WorkflowRun) => {
24
- setRun(workflowRun)
25
- setStatus(workflowRun.status)
26
- setCurrentStepIndex(workflowRun.currentStepIndex)
27
- setCompletedSteps(workflowRun.stepResults)
28
- setError(workflowRun.error ?? null)
29
-
30
- const total = workflowRun.stepResults.length
31
- const done = workflowRun.stepResults.filter(s => s.status === 'completed' || s.status === 'skipped').length
32
- setProgress(total > 0 ? Math.round((done / total) * 100) : 0)
33
-
34
- if (workflowRun.status === 'completed' || workflowRun.status === 'failed') {
35
- options.onRunComplete?.(workflowRun)
36
- }
37
- }, [options.onRunComplete])
38
-
39
- const updateStep = useCallback((result: StepResult) => {
40
- setCompletedSteps(prev => {
41
- const existing = prev.findIndex(s => s.stepId === result.stepId)
42
- if (existing >= 0) {
43
- const updated = [...prev]
44
- updated[existing] = result
45
- return updated
46
- }
47
- return [...prev, result]
48
- })
49
- setCurrentStepIndex(prev => prev + 1)
50
- options.onStepComplete?.(result)
51
- }, [options.onStepComplete])
52
-
53
- const reset = useCallback(() => {
54
- setRun(null)
55
- setCurrentStepIndex(0)
56
- setCompletedSteps([])
57
- setStatus('pending')
58
- setProgress(0)
59
- setError(null)
60
- if (timerRef.current) clearInterval(timerRef.current)
61
- }, [])
62
-
63
- useEffect(() => {
64
- return () => { if (timerRef.current) clearInterval(timerRef.current) }
65
- }, [])
66
-
67
- return {
68
- run, status, currentStepIndex, completedSteps,
69
- progress, error,
70
- trackRun, updateStep, reset,
71
- isRunning: status === 'running',
72
- isComplete: status === 'completed',
73
- isFailed: status === 'failed',
74
- }
75
- }
@@ -1,52 +0,0 @@
1
- // @geenius-ai-workflow/react — src/hooks/useWorkflowStep.ts
2
- import { useState, useCallback, useMemo } from 'react'
3
- import type { WorkflowStepDef, StepResult, StepStatus, StepConfig } from '@geenius-ai-workflow/shared'
4
-
5
- export function useWorkflowStep(stepDef: WorkflowStepDef) {
6
- const [status, setStatus] = useState<StepStatus>('pending')
7
- const [output, setOutput] = useState<unknown>(null)
8
- const [error, setError] = useState<string | null>(null)
9
- const [durationMs, setDurationMs] = useState(0)
10
-
11
- const updateFromResult = useCallback((result: StepResult) => {
12
- setStatus(result.status)
13
- setOutput(result.output ?? null)
14
- setError(result.error ?? null)
15
- setDurationMs(result.durationMs)
16
- }, [])
17
-
18
- const reset = useCallback(() => {
19
- setStatus('pending')
20
- setOutput(null)
21
- setError(null)
22
- setDurationMs(0)
23
- }, [])
24
-
25
- const icon = useMemo(() => {
26
- const map: Record<string, string> = {
27
- 'llm-call': '🤖', 'transform': '⚙️', 'condition': '🔀',
28
- 'human-approval': '👤', 'webhook': '🌐', 'delay': '⏱️',
29
- 'parallel': '⚡', 'loop': '🔄', 'sub-workflow': '📋', 'custom': '🔧',
30
- }
31
- return map[stepDef.type] ?? '📦'
32
- }, [stepDef.type])
33
-
34
- const statusColor = useMemo(() => {
35
- const map: Record<StepStatus, string> = {
36
- pending: 'gray', running: 'blue', completed: 'green',
37
- failed: 'red', skipped: 'orange', 'waiting-approval': 'purple',
38
- }
39
- return map[status]
40
- }, [status])
41
-
42
- return {
43
- stepDef, status, output, error, durationMs,
44
- icon, statusColor,
45
- updateFromResult, reset,
46
- isComplete: status === 'completed',
47
- isRunning: status === 'running',
48
- isFailed: status === 'failed',
49
- isWaiting: status === 'waiting-approval',
50
- config: stepDef.config as StepConfig,
51
- }
52
- }
@@ -1,54 +0,0 @@
1
- // @geenius-ai-workflow/react — src/hooks/useWorkflowTemplates.ts
2
- import { useState, useCallback, useMemo } from 'react'
3
- import type { WorkflowDefinition } from '@geenius-ai-workflow/shared'
4
- import { WORKFLOW_TEMPLATES, getTemplate, getTemplatesByCategory } from '@geenius-ai-workflow/shared'
5
- import type { WorkflowTemplate } from '@geenius-ai-workflow/shared'
6
-
7
- export function useWorkflowTemplates(userId: string) {
8
- const [selectedTemplateId, setSelectedTemplateId] = useState<string | null>(null)
9
- const [filterCategory, setFilterCategory] = useState<WorkflowTemplate['category'] | 'all'>('all')
10
- const [searchQuery, setSearchQuery] = useState('')
11
-
12
- const filteredTemplates = useMemo(() => {
13
- let templates = filterCategory === 'all' ? WORKFLOW_TEMPLATES : getTemplatesByCategory(filterCategory)
14
- if (searchQuery.trim()) {
15
- const q = searchQuery.toLowerCase()
16
- templates = templates.filter(t =>
17
- t.name.toLowerCase().includes(q) ||
18
- t.description.toLowerCase().includes(q) ||
19
- t.tags.some(tag => tag.includes(q))
20
- )
21
- }
22
- return templates
23
- }, [filterCategory, searchQuery])
24
-
25
- const selectedTemplate = useMemo(
26
- () => selectedTemplateId ? getTemplate(selectedTemplateId) ?? null : null,
27
- [selectedTemplateId],
28
- )
29
-
30
- const createFromTemplate = useCallback((templateId: string): WorkflowDefinition | null => {
31
- const template = getTemplate(templateId)
32
- if (!template) return null
33
- return template.create(userId)
34
- }, [userId])
35
-
36
- const categories = useMemo(
37
- () => [...new Set(WORKFLOW_TEMPLATES.map(t => t.category))],
38
- [],
39
- )
40
-
41
- return {
42
- templates: filteredTemplates,
43
- allTemplates: WORKFLOW_TEMPLATES,
44
- selectedTemplate,
45
- selectedTemplateId,
46
- categories,
47
- filterCategory,
48
- searchQuery,
49
- setSelectedTemplateId,
50
- setFilterCategory,
51
- setSearchQuery,
52
- createFromTemplate,
53
- }
54
- }
@@ -1,16 +0,0 @@
1
- // @geenius-ai-workflow/react — src/index.ts
2
- export type {
3
- WorkflowStatus, RunStatus, StepStatus, StepType,
4
- WorkflowDefinition, WorkflowStepDef, StepConfig,
5
- WorkflowRun, StepResult, WorkflowBuilderState,
6
- } from '@geenius-ai-workflow/shared'
7
- export { WorkflowEngine, WORKFLOW_TEMPLATES, validateWorkflow } from '@geenius-ai-workflow/shared'
8
-
9
- // Hooks
10
- export * from './hooks'
11
-
12
- // Components
13
- export * from './components'
14
-
15
- // Pages
16
- export * from './pages'