@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,133 +0,0 @@
1
- // @geenius-ai-workflow/shared — src/utils/dag.ts
2
- /**
3
- * DAG (Directed Acyclic Graph) utilities — topological sort, cycle detection, path finding.
4
- */
5
-
6
- export interface DAGNode { id: string }
7
- export interface DAGEdge { from: string; to: string }
8
-
9
- /**
10
- * Topological sort using Kahn's algorithm.
11
- * Returns sorted node IDs or throws if a cycle is detected.
12
- */
13
- export function topoSort(nodeIds: string[], edges: DAGEdge[]): string[] {
14
- const inDegree = new Map<string, number>()
15
- const adjacency = new Map<string, string[]>()
16
-
17
- for (const id of nodeIds) {
18
- inDegree.set(id, 0)
19
- adjacency.set(id, [])
20
- }
21
-
22
- for (const edge of edges) {
23
- adjacency.get(edge.from)?.push(edge.to)
24
- inDegree.set(edge.to, (inDegree.get(edge.to) ?? 0) + 1)
25
- }
26
-
27
- const queue: string[] = []
28
- for (const [id, deg] of inDegree) {
29
- if (deg === 0) queue.push(id)
30
- }
31
-
32
- const sorted: string[] = []
33
- while (queue.length > 0) {
34
- const id = queue.shift()!
35
- sorted.push(id)
36
- for (const neighbor of adjacency.get(id) ?? []) {
37
- const newDeg = (inDegree.get(neighbor) ?? 1) - 1
38
- inDegree.set(neighbor, newDeg)
39
- if (newDeg === 0) queue.push(neighbor)
40
- }
41
- }
42
-
43
- if (sorted.length !== nodeIds.length) {
44
- throw new Error('Cycle detected in workflow DAG — topological sort is not possible')
45
- }
46
-
47
- return sorted
48
- }
49
-
50
- /**
51
- * Detect cycles using DFS. Returns the cycle path if one exists, or null.
52
- */
53
- export function detectCycle(nodeIds: string[], edges: DAGEdge[]): string[] | null {
54
- const adjacency = new Map<string, string[]>()
55
- for (const id of nodeIds) adjacency.set(id, [])
56
- for (const edge of edges) adjacency.get(edge.from)?.push(edge.to)
57
-
58
- const WHITE = 0, GRAY = 1, BLACK = 2
59
- const color = new Map<string, number>()
60
- const parent = new Map<string, string | null>()
61
- for (const id of nodeIds) { color.set(id, WHITE); parent.set(id, null) }
62
-
63
- for (const startId of nodeIds) {
64
- if (color.get(startId) !== WHITE) continue
65
- const stack = [startId]
66
- while (stack.length > 0) {
67
- const node = stack[stack.length - 1]
68
- if (color.get(node) === WHITE) {
69
- color.set(node, GRAY)
70
- for (const neighbor of adjacency.get(node) ?? []) {
71
- if (color.get(neighbor) === GRAY) {
72
- // Build cycle path
73
- const cycle = [neighbor, node]
74
- let cur = node
75
- while (cur !== neighbor && parent.get(cur)) {
76
- cur = parent.get(cur)!
77
- cycle.push(cur)
78
- }
79
- return cycle.reverse()
80
- }
81
- if (color.get(neighbor) === WHITE) {
82
- parent.set(neighbor, node)
83
- stack.push(neighbor)
84
- }
85
- }
86
- } else {
87
- color.set(node, BLACK)
88
- stack.pop()
89
- }
90
- }
91
- }
92
-
93
- return null
94
- }
95
-
96
- /**
97
- * Find all paths from source to target in the DAG.
98
- */
99
- export function findPaths(nodeIds: string[], edges: DAGEdge[], source: string, target: string): string[][] {
100
- const adjacency = new Map<string, string[]>()
101
- for (const id of nodeIds) adjacency.set(id, [])
102
- for (const edge of edges) adjacency.get(edge.from)?.push(edge.to)
103
-
104
- const paths: string[][] = []
105
- const dfs = (current: string, path: string[]) => {
106
- if (current === target) { paths.push([...path]); return }
107
- for (const neighbor of adjacency.get(current) ?? []) {
108
- if (!path.includes(neighbor)) {
109
- path.push(neighbor)
110
- dfs(neighbor, path)
111
- path.pop()
112
- }
113
- }
114
- }
115
- dfs(source, [source])
116
- return paths
117
- }
118
-
119
- /**
120
- * Find entry nodes (no incoming edges) in the DAG.
121
- */
122
- export function findEntryNodes(nodeIds: string[], edges: DAGEdge[]): string[] {
123
- const hasIncoming = new Set(edges.map(e => e.to))
124
- return nodeIds.filter(id => !hasIncoming.has(id))
125
- }
126
-
127
- /**
128
- * Find exit nodes (no outgoing edges) in the DAG.
129
- */
130
- export function findExitNodes(nodeIds: string[], edges: DAGEdge[]): string[] {
131
- const hasOutgoing = new Set(edges.map(e => e.from))
132
- return nodeIds.filter(id => !hasOutgoing.has(id))
133
- }
@@ -1,5 +0,0 @@
1
- // @geenius-ai-workflow/shared — src/utils/index.ts
2
- export { interpolate, extractVariables, findMissingVariables } from './interpolation'
3
- export { topoSort, detectCycle, findPaths, findEntryNodes, findExitNodes } from './dag'
4
- export type { DAGNode, DAGEdge } from './dag'
5
- export { estimateTokens, estimateStepTokens, estimateStepCost, estimateWorkflowCost, calculateRunCost, formatCost, MODEL_RATES } from './cost'
@@ -1,53 +0,0 @@
1
- // @geenius-ai-workflow/shared — src/utils/interpolation.ts
2
- /**
3
- * Template variable interpolation — {{varName}} syntax with nested access.
4
- */
5
-
6
- /** Resolve a dot-path like "user.name" from a nested object */
7
- function resolvePath(obj: Record<string, unknown>, path: string): unknown {
8
- return path.split('.').reduce<unknown>((acc, key) => {
9
- if (acc !== null && acc !== undefined && typeof acc === 'object') {
10
- return (acc as Record<string, unknown>)[key]
11
- }
12
- return undefined
13
- }, obj)
14
- }
15
-
16
- /**
17
- * Interpolate {{variable}} or {{nested.path}} references in a string.
18
- * Supports optional default values: {{varName|default}}.
19
- */
20
- export function interpolate(template: string, vars: Record<string, unknown>): string {
21
- return template.replace(/\{\{([^}]+)\}\}/g, (match, expr: string) => {
22
- const [path, defaultValue] = expr.trim().split('|').map((s: string) => s.trim())
23
- const val = resolvePath(vars, path)
24
- if (val !== undefined && val !== null) {
25
- return typeof val === 'object' ? JSON.stringify(val) : String(val)
26
- }
27
- return defaultValue ?? match
28
- })
29
- }
30
-
31
- /**
32
- * Extract all variable references from a template string.
33
- * Returns unique variable names (without defaults).
34
- */
35
- export function extractVariables(template: string): string[] {
36
- const vars = new Set<string>()
37
- const re = /\{\{([^}]+)\}\}/g
38
- let m: RegExpExecArray | null
39
- while ((m = re.exec(template)) !== null) {
40
- const path = m[1].trim().split('|')[0].trim()
41
- vars.add(path.split('.')[0]) // add root variable name
42
- }
43
- return [...vars]
44
- }
45
-
46
- /**
47
- * Check if all required variables in a template are present in the vars object.
48
- * Returns missing variable names.
49
- */
50
- export function findMissingVariables(template: string, vars: Record<string, unknown>): string[] {
51
- const required = extractVariables(template)
52
- return required.filter(v => vars[v] === undefined || vars[v] === null)
53
- }
@@ -1,215 +0,0 @@
1
- // @geenius-ai-workflow/shared — src/validators.ts
2
- /**
3
- * Zod schemas for workflow definition and run validation.
4
- */
5
- import { z } from 'zod/v4'
6
-
7
- // ============================================================================
8
- // Step Config Schemas
9
- // ============================================================================
10
-
11
- export const llmCallConfigSchema = z.object({
12
- type: z.literal('llm-call'),
13
- model: z.string().optional(),
14
- systemPrompt: z.string().min(1, 'System prompt is required'),
15
- userPromptTemplate: z.string().min(1, 'User prompt template is required'),
16
- temperature: z.number().min(0).max(2).optional(),
17
- maxTokens: z.number().int().positive().optional(),
18
- parseJson: z.boolean().optional(),
19
- outputVar: z.string().min(1, 'Output variable name is required'),
20
- })
21
-
22
- export const transformConfigSchema = z.object({
23
- type: z.literal('transform'),
24
- expression: z.string().min(1, 'Expression is required'),
25
- inputVars: z.array(z.string()).min(1, 'At least one input variable is required'),
26
- outputVar: z.string().min(1),
27
- })
28
-
29
- export const conditionConfigSchema = z.object({
30
- type: z.literal('condition'),
31
- expression: z.string().min(1),
32
- trueStepId: z.string().min(1),
33
- falseStepId: z.string().min(1),
34
- })
35
-
36
- export const humanApprovalConfigSchema = z.object({
37
- type: z.literal('human-approval'),
38
- message: z.string().min(1, 'Approval message is required'),
39
- approvers: z.array(z.string()).optional(),
40
- autoApproveAfterMs: z.number().positive().optional(),
41
- })
42
-
43
- export const webhookConfigSchema = z.object({
44
- type: z.literal('webhook'),
45
- url: z.string().url('Valid URL required'),
46
- method: z.enum(['GET', 'POST', 'PUT', 'DELETE']),
47
- headers: z.record(z.string()).optional(),
48
- bodyTemplate: z.string().optional(),
49
- outputVar: z.string().min(1),
50
- })
51
-
52
- export const delayConfigSchema = z.object({
53
- type: z.literal('delay'),
54
- durationMs: z.number().int().positive('Duration must be positive'),
55
- })
56
-
57
- export const parallelConfigSchema = z.object({
58
- type: z.literal('parallel'),
59
- stepIds: z.array(z.string()).min(2, 'Parallel needs at least 2 steps'),
60
- failurePolicy: z.enum(['fail-fast', 'continue']),
61
- })
62
-
63
- export const loopConfigSchema = z.object({
64
- type: z.literal('loop'),
65
- stepIds: z.array(z.string()).min(1),
66
- iterateVar: z.string().min(1),
67
- itemVar: z.string().min(1),
68
- maxIterations: z.number().int().positive().optional(),
69
- })
70
-
71
- export const subWorkflowConfigSchema = z.object({
72
- type: z.literal('sub-workflow'),
73
- workflowId: z.string().min(1),
74
- inputMapping: z.record(z.string()),
75
- outputVar: z.string().min(1),
76
- })
77
-
78
- export const customStepConfigSchema = z.object({
79
- type: z.literal('custom'),
80
- handler: z.string().min(1, 'Handler name is required'),
81
- params: z.record(z.unknown()),
82
- outputVar: z.string().optional(),
83
- })
84
-
85
- export const stepConfigSchema = z.discriminatedUnion('type', [
86
- llmCallConfigSchema,
87
- transformConfigSchema,
88
- conditionConfigSchema,
89
- humanApprovalConfigSchema,
90
- webhookConfigSchema,
91
- delayConfigSchema,
92
- parallelConfigSchema,
93
- loopConfigSchema,
94
- subWorkflowConfigSchema,
95
- customStepConfigSchema,
96
- ])
97
-
98
- // ============================================================================
99
- // Step Definition Schema
100
- // ============================================================================
101
-
102
- export const workflowStepDefSchema = z.object({
103
- id: z.string().min(1),
104
- name: z.string().min(1, 'Step name is required'),
105
- type: z.enum(['llm-call', 'transform', 'condition', 'human-approval', 'webhook', 'delay', 'parallel', 'loop', 'sub-workflow', 'custom']),
106
- config: stepConfigSchema,
107
- position: z.object({ x: z.number(), y: z.number() }).optional(),
108
- optional: z.boolean().optional(),
109
- retries: z.object({ maxAttempts: z.number().int().positive(), backoffMs: z.number().positive() }).optional(),
110
- })
111
-
112
- // ============================================================================
113
- // Connection Schema
114
- // ============================================================================
115
-
116
- export const stepConnectionSchema = z.object({
117
- fromStepId: z.string().min(1),
118
- toStepId: z.string().min(1),
119
- label: z.string().optional(),
120
- condition: z.string().optional(),
121
- })
122
-
123
- // ============================================================================
124
- // Variable Schema
125
- // ============================================================================
126
-
127
- export const workflowVariableSchema = z.object({
128
- name: z.string().min(1),
129
- type: z.enum(['string', 'number', 'boolean', 'object', 'array']),
130
- description: z.string().optional(),
131
- required: z.boolean().optional(),
132
- default: z.unknown().optional(),
133
- })
134
-
135
- // ============================================================================
136
- // Workflow Definition Schema
137
- // ============================================================================
138
-
139
- export const workflowDefinitionSchema = z.object({
140
- id: z.string().min(1),
141
- name: z.string().min(1, 'Workflow name is required').max(120, 'Name too long'),
142
- description: z.string().max(2000).optional(),
143
- version: z.number().int().positive(),
144
- status: z.enum(['draft', 'active', 'paused', 'archived']),
145
- steps: z.array(workflowStepDefSchema).min(1, 'At least one step is required'),
146
- connections: z.array(stepConnectionSchema),
147
- inputSchema: z.array(workflowVariableSchema).optional(),
148
- variables: z.record(z.unknown()).optional(),
149
- tags: z.array(z.string()).optional(),
150
- createdBy: z.string(),
151
- createdAt: z.number(),
152
- updatedAt: z.number(),
153
- })
154
-
155
- // ============================================================================
156
- // Run Schema
157
- // ============================================================================
158
-
159
- export const stepResultSchema = z.object({
160
- stepId: z.string(),
161
- stepName: z.string(),
162
- type: z.enum(['llm-call', 'transform', 'condition', 'human-approval', 'webhook', 'delay', 'parallel', 'loop', 'sub-workflow', 'custom']),
163
- status: z.enum(['pending', 'running', 'completed', 'failed', 'skipped', 'waiting-approval']),
164
- input: z.record(z.unknown()).optional(),
165
- output: z.unknown().optional(),
166
- error: z.string().optional(),
167
- durationMs: z.number(),
168
- tokens: z.number().optional(),
169
- costUsd: z.number().optional(),
170
- startedAt: z.number(),
171
- completedAt: z.number().optional(),
172
- })
173
-
174
- export const workflowRunSchema = z.object({
175
- id: z.string(),
176
- workflowId: z.string(),
177
- workflowVersion: z.number(),
178
- status: z.enum(['pending', 'running', 'paused', 'completed', 'failed', 'cancelled']),
179
- input: z.record(z.unknown()),
180
- variables: z.record(z.unknown()),
181
- stepResults: z.array(stepResultSchema),
182
- currentStepIndex: z.number(),
183
- error: z.string().optional(),
184
- triggeredBy: z.string(),
185
- startedAt: z.number(),
186
- completedAt: z.number().optional(),
187
- })
188
-
189
- // ============================================================================
190
- // Validation helpers
191
- // ============================================================================
192
-
193
- /** Validate a WorkflowDefinition, returning { success, data?, error? } */
194
- export function validateWorkflow(data: unknown) {
195
- return workflowDefinitionSchema.safeParse(data)
196
- }
197
-
198
- /** Validate a WorkflowRun, returning { success, data?, error? } */
199
- export function validateRun(data: unknown) {
200
- return workflowRunSchema.safeParse(data)
201
- }
202
-
203
- /** Validate step connections reference valid step IDs */
204
- export function validateConnectionIntegrity(
205
- steps: Array<{ id: string }>,
206
- connections: Array<{ fromStepId: string; toStepId: string }>,
207
- ): string[] {
208
- const stepIds = new Set(steps.map(s => s.id))
209
- const errors: string[] = []
210
- for (const conn of connections) {
211
- if (!stepIds.has(conn.fromStepId)) errors.push(`Connection references unknown source step: ${conn.fromStepId}`)
212
- if (!stepIds.has(conn.toStepId)) errors.push(`Connection references unknown target step: ${conn.toStepId}`)
213
- }
214
- return errors
215
- }
@@ -1 +0,0 @@
1
- {"compilerOptions":{"target":"ES2022","module":"ESNext","moduleResolution":"bundler","declaration":true,"declarationMap":true,"sourceMap":true,"outDir":"./dist","rootDir":"./src","strict":true,"esModuleInterop":true,"skipLibCheck":true,"forceConsistentCasingInFileNames":true,"resolveJsonModule":true,"isolatedModules":true},"include":["src"],"exclude":["node_modules","dist"]}
@@ -1,5 +0,0 @@
1
- import { defineConfig } from 'tsup'
2
- export default defineConfig({
3
- entry: { index: 'src/index.ts', engine: 'src/engine.ts', steps: 'src/steps.ts', 'convex/index': 'src/convex/index.ts' },
4
- format: ['esm'], dts: true, clean: true, sourcemap: true,
5
- })
@@ -1,4 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
- export default defineConfig({
3
- test: { globals: true, environment: 'node' },
4
- })
@@ -1 +0,0 @@
1
- # ✦ @geenius-ai-workflow/solidjs\n\n> Geenius AI Workflow — SolidJS primitives & components\n\n---\n\n## Overview\nBuilt with Steve Jobs-level minimalism and Jony Ive-level craftsmanship, this package is designed to deliver unparalleled developer experience (DX) and rock-solid performance.\n\n## Installation\n\n```bash\npnpm add @geenius-ai-workflow/solidjs\n```\n\n## Usage\n\n```typescript\nimport { init } from '@geenius-ai-workflow/solidjs';\n\n// Initialize the module with absolute precision\ninit({\n mode: 'premium',\n});\n```\n\n## Architecture\n- **Zero-config**: It just works.\n- **Strictly Typed**: Fully written in TypeScript for flawless IntelliSense.\n- **Framework Agnostic**: seamlessly integrates into the Geenius ecosystem.\n\n---\n\n*Designed by Antigravity HQ*\n
@@ -1,45 +0,0 @@
1
- {
2
- "name": "@geenius-ai-workflow/solidjs",
3
- "version": "0.1.0",
4
- "private": false,
5
- "type": "module",
6
- "description": "Geenius AI Workflow \u2014 SolidJS primitives & components",
7
- "main": "./dist/index.js",
8
- "module": "./dist/index.js",
9
- "types": "./dist/index.d.ts",
10
- "exports": {
11
- ".": {
12
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.js"
14
- }
15
- },
16
- "files": [
17
- "dist",
18
- "src"
19
- ],
20
- "scripts": {
21
- "build": "tsup",
22
- "clean": "rm -rf dist",
23
- "type-check": "tsc --noEmit",
24
- "prepublishOnly": "pnpm clean && pnpm build"
25
- },
26
- "dependencies": {
27
- "@geenius-ai-workflow/shared": "workspace:*"
28
- },
29
- "devDependencies": {
30
- "solid-js": "^1.9.0",
31
- "tsup": "^8.5.1",
32
- "typescript": "~5.9.3"
33
- },
34
- "peerDependencies": {
35
- "solid-js": ">=1.8.0"
36
- },
37
- "author": "Antigravity HQ",
38
- "license": "MIT",
39
- "engines": {
40
- "node": ">=20.0.0"
41
- },
42
- "publishConfig": {
43
- "access": "public"
44
- }
45
- }
@@ -1,18 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/ApprovalModal.tsx
2
- import { Show, For } from 'solid-js'
3
- import type { ApprovalRequest } from '../primitives/createApprovalGate'
4
-
5
- export function ApprovalModal(props: { request: ApprovalRequest | null; onApprove: (id: string) => void; onReject: (id: string) => void }) {
6
- return (
7
- <Show when={props.request}>{(req) => (
8
- <div data-workflow="approval-modal" role="dialog" aria-modal="true">
9
- <div data-workflow="approval-overlay" />
10
- <div data-workflow="approval-dialog">
11
- <div data-workflow="approval-header"><span data-workflow="approval-icon">👤</span><h3 data-workflow="approval-title">Approval Required</h3></div>
12
- <div data-workflow="approval-body"><p data-workflow="approval-message">{req().message}</p>
13
- <Show when={req().approvers && req().approvers!.length > 0}><div data-workflow="approval-approvers"><For each={req().approvers!}>{(a) => <span data-workflow="approval-approver-badge">{a}</span>}</For></div></Show></div>
14
- <div data-workflow="approval-actions"><button data-workflow="approval-reject" onClick={() => props.onReject(req().id)}>✕ Reject</button><button data-workflow="approval-approve" onClick={() => props.onApprove(req().id)}>✓ Approve</button></div>
15
- </div>
16
- </div>)}</Show>
17
- )
18
- }
@@ -1,14 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/StepConfigPanel.tsx
2
- import { createSignal, Show } from 'solid-js'
3
- import type { WorkflowStepDef } from '@geenius-ai-workflow/shared'
4
-
5
- export function StepConfigPanel(props: { step: WorkflowStepDef; onUpdate: (id: string, u: Partial<WorkflowStepDef>) => void; onDelete: (id: string) => void; onClose: () => void }) {
6
- const [name, setName] = createSignal(props.step.name)
7
- return (
8
- <div data-workflow="config-panel" role="complementary"><div data-workflow="config-header"><h3 data-workflow="config-title">Configure Step</h3><button data-workflow="config-close" onClick={props.onClose}>✕</button></div>
9
- <div data-workflow="config-body"><label data-workflow="config-label">Step Name<input data-workflow="config-input" value={name()} onInput={(e) => setName(e.currentTarget.value)} onBlur={() => { if (name().trim() && name() !== props.step.name) props.onUpdate(props.step.id, { name: name().trim() }) }} /></label>
10
- <div data-workflow="config-field"><span data-workflow="config-field-label">Type</span><span data-workflow="config-field-value">{props.step.type}</span></div>
11
- <pre data-workflow="config-json-view">{JSON.stringify(props.step.config, null, 2)}</pre></div>
12
- <div data-workflow="config-footer"><button data-workflow="config-delete" onClick={() => { props.onDelete(props.step.id); props.onClose() }}>🗑 Delete</button></div></div>
13
- )
14
- }
@@ -1,11 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/StepConnector.tsx
2
- const W = 200, H = 80
3
- export function StepConnector(props: { from: { x: number; y: number }; to: { x: number; y: number }; label?: string; isActive?: boolean }) {
4
- const x1 = () => props.from.x + W, y1 = () => props.from.y + H / 2, x2 = () => props.to.x, y2 = () => props.to.y + H / 2, mx = () => (x1() + x2()) / 2
5
- return (
6
- <g data-workflow="connector" data-active={props.isActive || undefined}>
7
- <path d={`M ${x1()} ${y1()} C ${mx()} ${y1()}, ${mx()} ${y2()}, ${x2()} ${y2()}`} fill="none" stroke={props.isActive ? 'oklch(0.7 0.2 145)' : 'oklch(0.5 0.02 260)'} stroke-width={props.isActive ? 3 : 2} />
8
- {props.label && <text x={mx()} y={(y1() + y2()) / 2 - 8} text-anchor="middle" fill="oklch(0.7 0.02 260)" font-size="12">{props.label}</text>}
9
- </g>
10
- )
11
- }
@@ -1,12 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/StepNode.tsx
2
- import type { WorkflowStepDef, StepType } from '@geenius-ai-workflow/shared'
3
- const ICONS: Record<StepType, string> = { 'llm-call': '🤖', transform: '⚙️', condition: '🔀', 'human-approval': '👤', webhook: '🌐', delay: '⏱️', parallel: '⚡', loop: '🔄', 'sub-workflow': '📋', custom: '🔧' }
4
-
5
- export function StepNode(props: { step: WorkflowStepDef; isSelected?: boolean; status?: string; onClick?: () => void }) {
6
- return (
7
- <div data-workflow="step-node" data-step-type={props.step.type} data-selected={props.isSelected || undefined} data-status={props.status} role="button" tabIndex={0} onClick={props.onClick} style={props.step.position ? { position: 'absolute', left: `${props.step.position.x}px`, top: `${props.step.position.y}px` } : undefined}>
8
- <div data-workflow="step-header"><span data-workflow="step-icon">{ICONS[props.step.type]}</span><span data-workflow="step-name">{props.step.name}</span></div>
9
- <div data-workflow="step-type-badge">{props.step.type}</div>
10
- </div>
11
- )
12
- }
@@ -1,22 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/StepPalette.tsx
2
- import { For } from 'solid-js'
3
- import type { StepType } from '@geenius-ai-workflow/shared'
4
- const ITEMS: Array<{ type: StepType; label: string; icon: string; desc: string }> = [
5
- { type: 'llm-call', label: 'LLM Call', icon: '🤖', desc: 'Call an AI model' },
6
- { type: 'transform', label: 'Transform', icon: '⚙️', desc: 'Transform data' },
7
- { type: 'condition', label: 'Condition', icon: '🔀', desc: 'If/else branching' },
8
- { type: 'human-approval', label: 'Approval', icon: '👤', desc: 'Human approval gate' },
9
- { type: 'webhook', label: 'Webhook', icon: '🌐', desc: 'HTTP request' },
10
- { type: 'delay', label: 'Delay', icon: '⏱️', desc: 'Wait for duration' },
11
- { type: 'parallel', label: 'Parallel', icon: '⚡', desc: 'Run in parallel' },
12
- { type: 'loop', label: 'Loop', icon: '🔄', desc: 'Iterate items' },
13
- { type: 'sub-workflow', label: 'Sub-workflow', icon: '📋', desc: 'Run another workflow' },
14
- { type: 'custom', label: 'Custom', icon: '🔧', desc: 'Custom handler' },
15
- ]
16
- export function StepPalette(props: { onAddStep: (t: StepType) => void }) {
17
- return (
18
- <div data-workflow="step-palette" role="list"><h3 data-workflow="palette-title">Steps</h3>
19
- <For each={ITEMS}>{(item) => <button data-workflow="palette-item" onClick={() => props.onAddStep(item.type)}><span data-workflow="palette-icon">{item.icon}</span><div data-workflow="palette-info"><span data-workflow="palette-label">{item.label}</span><span data-workflow="palette-desc">{item.desc}</span></div></button>}</For>
20
- </div>
21
- )
22
- }
@@ -1,23 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/WorkflowCanvas.tsx
2
- import { For, Show } from 'solid-js'
3
- import type { WorkflowDefinition } from '@geenius-ai-workflow/shared'
4
- import { StepNode } from './StepNode'
5
- import { StepConnector } from './StepConnector'
6
-
7
- export function WorkflowCanvas(props: { definition: WorkflowDefinition; selectedStepId: string | null; onSelectStep: (id: string | null) => void }) {
8
- return (
9
- <div data-workflow="canvas" role="application" aria-label="Workflow canvas">
10
- <svg data-workflow="connections-layer" style={{ position: 'absolute', inset: '0', 'pointer-events': 'none' }}>
11
- <For each={props.definition.connections}>{(conn) => {
12
- const from = () => props.definition.steps.find(s => s.id === conn.fromStepId)
13
- const to = () => props.definition.steps.find(s => s.id === conn.toStepId)
14
- return <Show when={from()?.position && to()?.position}><StepConnector from={from()!.position!} to={to()!.position!} label={conn.label} /></Show>
15
- }}</For>
16
- </svg>
17
- <div data-workflow="nodes-layer">
18
- <For each={props.definition.steps}>{(step) => <StepNode step={step} isSelected={props.selectedStepId === step.id} onClick={() => props.onSelectStep(step.id === props.selectedStepId ? null : step.id)} />}</For>
19
- </div>
20
- <Show when={props.definition.steps.length === 0}><div data-workflow="canvas-empty"><p data-workflow="empty-title">No steps yet</p></div></Show>
21
- </div>
22
- )
23
- }
@@ -1,18 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/WorkflowRunPanel.tsx
2
- import { Show, For } from 'solid-js'
3
- import type { WorkflowRun } from '@geenius-ai-workflow/shared'
4
- import { formatCost } from '@geenius-ai-workflow/shared'
5
- const SI: Record<string, string> = { pending: '⏳', running: '🔄', completed: '✅', failed: '❌', skipped: '⏭️', 'waiting-approval': '👤' }
6
-
7
- export function WorkflowRunPanel(props: { run: WorkflowRun | null; isRunning: boolean; onCancel?: () => void }) {
8
- return (
9
- <div data-workflow="run-panel" data-status={props.run?.status}><Show when={!props.run}><div data-workflow="run-empty"><p>No active run.</p></div></Show>
10
- <Show when={props.run}>{(r) => { const done = () => r().stepResults.filter(s => s.status === 'completed').length; const total = () => r().stepResults.length; const pct = () => total() > 0 ? Math.round((done() / total()) * 100) : 0; const cost = () => r().stepResults.reduce((s, x) => s + (x.costUsd ?? 0), 0)
11
- return (<><div data-workflow="run-header"><h3 data-workflow="run-title">{SI[r().status]} Run {r().status}</h3><Show when={props.isRunning && props.onCancel}><button data-workflow="run-cancel" onClick={props.onCancel}>⏹ Cancel</button></Show></div>
12
- <div data-workflow="run-progress"><div data-workflow="run-progress-bar"><div data-workflow="run-progress-fill" style={{ width: `${pct()}%` }} /></div><span data-workflow="run-progress-text">{done()}/{total()} ({pct()}%)</span></div>
13
- <Show when={cost() > 0}><span data-workflow="run-stat">💰 {formatCost(cost())}</span></Show>
14
- <Show when={r().error}><div data-workflow="run-error">{r().error}</div></Show>
15
- <ul data-workflow="run-steps"><For each={r().stepResults}>{(sr) => <li data-workflow="run-step-item" data-status={sr.status}><span>{SI[sr.status]}</span><span>{sr.stepName}</span><span>{sr.durationMs}ms</span></li>}</For></ul></>)
16
- }}</Show></div>
17
- )
18
- }
@@ -1,13 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/WorkflowToolbar.tsx
2
- import { Show } from 'solid-js'
3
-
4
- export function WorkflowToolbar(props: { workflowName: string; isDirty: boolean; isRunning: boolean; canUndo: boolean; canRedo: boolean; onSave: () => void; onRun: () => void; onCancel?: () => void; onUndo: () => void; onRedo: () => void; onExport?: () => void }) {
5
- return (
6
- <div data-workflow="toolbar" role="toolbar">
7
- <div data-workflow="toolbar-left"><h2 data-workflow="toolbar-title">{props.workflowName}</h2><Show when={props.isDirty}><span data-workflow="toolbar-dirty">●</span></Show></div>
8
- <div data-workflow="toolbar-center"><button data-workflow="toolbar-btn" onClick={props.onUndo} disabled={!props.canUndo}>↶</button><button data-workflow="toolbar-btn" onClick={props.onRedo} disabled={!props.canRedo}>↷</button></div>
9
- <div data-workflow="toolbar-right"><Show when={props.onExport}><button data-workflow="toolbar-btn-secondary" onClick={props.onExport}>📤 Export</button></Show><button data-workflow="toolbar-btn-secondary" onClick={props.onSave} disabled={!props.isDirty}>💾 Save</button>
10
- <Show when={props.isRunning} fallback={<button data-workflow="toolbar-btn-primary" onClick={props.onRun}>▶ Run</button>}><button data-workflow="toolbar-btn-danger" onClick={props.onCancel}>⏹ Stop</button></Show></div>
11
- </div>
12
- )
13
- }
@@ -1,9 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — components/index.ts
2
- export { WorkflowCanvas } from './WorkflowCanvas'
3
- export { StepNode } from './StepNode'
4
- export { StepConnector } from './StepConnector'
5
- export { StepConfigPanel } from './StepConfigPanel'
6
- export { WorkflowRunPanel } from './WorkflowRunPanel'
7
- export { ApprovalModal } from './ApprovalModal'
8
- export { WorkflowToolbar } from './WorkflowToolbar'
9
- export { StepPalette } from './StepPalette'
@@ -1,7 +0,0 @@
1
- // @geenius-ai-workflow/solidjs — src/index.ts
2
- export type { WorkflowDefinition, WorkflowStepDef, WorkflowRun, StepResult, WorkflowBuilderState } from '@geenius-ai-workflow/shared'
3
- export { WorkflowEngine, WORKFLOW_TEMPLATES } from '@geenius-ai-workflow/shared'
4
-
5
- export * from './primitives'
6
- export * from './components'
7
- export * from './pages'