@marktoflow/gui 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/.turbo/turbo-build.log +26 -0
  2. package/.turbo/turbo-test.log +22 -0
  3. package/README.md +179 -0
  4. package/dist/client/assets/index-DwTI8opO.js +608 -0
  5. package/dist/client/assets/index-DwTI8opO.js.map +1 -0
  6. package/dist/client/assets/index-RoEdL6gO.css +1 -0
  7. package/dist/client/index.html +20 -0
  8. package/dist/client/vite.svg +9 -0
  9. package/dist/server/index.d.ts +3 -0
  10. package/dist/server/index.d.ts.map +1 -0
  11. package/dist/server/index.js +56 -0
  12. package/dist/server/index.js.map +1 -0
  13. package/dist/server/routes/ai.js +50 -0
  14. package/dist/server/routes/ai.js.map +1 -0
  15. package/dist/server/routes/execute.js +62 -0
  16. package/dist/server/routes/execute.js.map +1 -0
  17. package/dist/server/routes/workflows.js +99 -0
  18. package/dist/server/routes/workflows.js.map +1 -0
  19. package/dist/server/server/index.js +95 -0
  20. package/dist/server/server/index.js.map +1 -0
  21. package/dist/server/server/routes/ai.js +87 -0
  22. package/dist/server/server/routes/ai.js.map +1 -0
  23. package/dist/server/server/routes/execute.js +63 -0
  24. package/dist/server/server/routes/execute.js.map +1 -0
  25. package/dist/server/server/routes/tools.js +518 -0
  26. package/dist/server/server/routes/tools.js.map +1 -0
  27. package/dist/server/server/routes/workflows.js +99 -0
  28. package/dist/server/server/routes/workflows.js.map +1 -0
  29. package/dist/server/server/services/AIService.js +69 -0
  30. package/dist/server/server/services/AIService.js.map +1 -0
  31. package/dist/server/server/services/FileWatcher.js +60 -0
  32. package/dist/server/server/services/FileWatcher.js.map +1 -0
  33. package/dist/server/server/services/WorkflowService.js +363 -0
  34. package/dist/server/server/services/WorkflowService.js.map +1 -0
  35. package/dist/server/server/services/agents/claude-code-provider.js +250 -0
  36. package/dist/server/server/services/agents/claude-code-provider.js.map +1 -0
  37. package/dist/server/server/services/agents/claude-provider.js +204 -0
  38. package/dist/server/server/services/agents/claude-provider.js.map +1 -0
  39. package/dist/server/server/services/agents/copilot-provider.js +227 -0
  40. package/dist/server/server/services/agents/copilot-provider.js.map +1 -0
  41. package/dist/server/server/services/agents/demo-provider.js +167 -0
  42. package/dist/server/server/services/agents/demo-provider.js.map +1 -0
  43. package/dist/server/server/services/agents/index.js +31 -0
  44. package/dist/server/server/services/agents/index.js.map +1 -0
  45. package/dist/server/server/services/agents/ollama-provider.js +220 -0
  46. package/dist/server/server/services/agents/ollama-provider.js.map +1 -0
  47. package/dist/server/server/services/agents/prompts.js +436 -0
  48. package/dist/server/server/services/agents/prompts.js.map +1 -0
  49. package/dist/server/server/services/agents/registry.js +242 -0
  50. package/dist/server/server/services/agents/registry.js.map +1 -0
  51. package/dist/server/server/services/agents/types.js +6 -0
  52. package/dist/server/server/services/agents/types.js.map +1 -0
  53. package/dist/server/server/websocket/index.js +85 -0
  54. package/dist/server/server/websocket/index.js.map +1 -0
  55. package/dist/server/services/AIService.d.ts +30 -0
  56. package/dist/server/services/AIService.d.ts.map +1 -0
  57. package/dist/server/services/AIService.js +216 -0
  58. package/dist/server/services/AIService.js.map +1 -0
  59. package/dist/server/services/FileWatcher.d.ts +10 -0
  60. package/dist/server/services/FileWatcher.d.ts.map +1 -0
  61. package/dist/server/services/FileWatcher.js +62 -0
  62. package/dist/server/services/FileWatcher.js.map +1 -0
  63. package/dist/server/services/WorkflowService.d.ts +54 -0
  64. package/dist/server/services/WorkflowService.d.ts.map +1 -0
  65. package/dist/server/services/WorkflowService.js +323 -0
  66. package/dist/server/services/WorkflowService.js.map +1 -0
  67. package/dist/server/shared/constants.js +175 -0
  68. package/dist/server/shared/constants.js.map +1 -0
  69. package/dist/server/shared/types.js +3 -0
  70. package/dist/server/shared/types.js.map +1 -0
  71. package/dist/server/websocket/index.d.ts +10 -0
  72. package/dist/server/websocket/index.d.ts.map +1 -0
  73. package/dist/server/websocket/index.js +85 -0
  74. package/dist/server/websocket/index.js.map +1 -0
  75. package/index.html +19 -0
  76. package/package.json +96 -0
  77. package/playwright.config.ts +27 -0
  78. package/postcss.config.js +6 -0
  79. package/public/vite.svg +9 -0
  80. package/src/client/App.tsx +520 -0
  81. package/src/client/components/Canvas/Canvas.tsx +405 -0
  82. package/src/client/components/Canvas/ExecutionOverlay.tsx +847 -0
  83. package/src/client/components/Canvas/NodeContextMenu.tsx +188 -0
  84. package/src/client/components/Canvas/OutputNode.tsx +111 -0
  85. package/src/client/components/Canvas/StepNode.tsx +106 -0
  86. package/src/client/components/Canvas/SubWorkflowNode.tsx +141 -0
  87. package/src/client/components/Canvas/Toolbar.tsx +189 -0
  88. package/src/client/components/Canvas/TriggerNode.tsx +128 -0
  89. package/src/client/components/Editor/InputsEditor.tsx +458 -0
  90. package/src/client/components/Editor/NewStepWizard.tsx +344 -0
  91. package/src/client/components/Editor/StepEditor.tsx +532 -0
  92. package/src/client/components/Editor/YamlEditor.tsx +160 -0
  93. package/src/client/components/Panels/PropertiesPanel.tsx +589 -0
  94. package/src/client/components/Prompt/ChangePreview.tsx +281 -0
  95. package/src/client/components/Prompt/PromptHistoryPanel.tsx +209 -0
  96. package/src/client/components/Prompt/PromptInput.tsx +108 -0
  97. package/src/client/components/Sidebar/Sidebar.tsx +343 -0
  98. package/src/client/components/common/Breadcrumb.tsx +40 -0
  99. package/src/client/components/common/Button.tsx +68 -0
  100. package/src/client/components/common/ContextMenu.tsx +202 -0
  101. package/src/client/components/common/KeyboardShortcuts.tsx +143 -0
  102. package/src/client/components/common/Modal.tsx +93 -0
  103. package/src/client/components/common/Tabs.tsx +57 -0
  104. package/src/client/components/common/ThemeToggle.tsx +63 -0
  105. package/src/client/components/index.ts +32 -0
  106. package/src/client/hooks/index.ts +4 -0
  107. package/src/client/hooks/useAIPrompt.ts +108 -0
  108. package/src/client/hooks/useCanvas.ts +247 -0
  109. package/src/client/hooks/useWebSocket.ts +164 -0
  110. package/src/client/hooks/useWorkflow.ts +138 -0
  111. package/src/client/main.tsx +10 -0
  112. package/src/client/stores/canvasStore.ts +348 -0
  113. package/src/client/stores/editorStore.ts +133 -0
  114. package/src/client/stores/executionStore.ts +440 -0
  115. package/src/client/stores/index.ts +4 -0
  116. package/src/client/stores/layoutStore.ts +103 -0
  117. package/src/client/stores/navigationStore.ts +49 -0
  118. package/src/client/stores/promptStore.ts +113 -0
  119. package/src/client/stores/themeStore.ts +75 -0
  120. package/src/client/stores/workflowStore.ts +177 -0
  121. package/src/client/styles/globals.css +346 -0
  122. package/src/client/utils/cn.ts +9 -0
  123. package/src/client/utils/index.ts +4 -0
  124. package/src/client/utils/serviceIcons.tsx +64 -0
  125. package/src/client/utils/stepValidation.ts +155 -0
  126. package/src/client/utils/workflowToGraph.ts +299 -0
  127. package/src/server/index.ts +114 -0
  128. package/src/server/routes/ai.ts +91 -0
  129. package/src/server/routes/execute.ts +71 -0
  130. package/src/server/routes/tools.ts +564 -0
  131. package/src/server/routes/workflows.ts +106 -0
  132. package/src/server/services/AIService.ts +105 -0
  133. package/src/server/services/FileWatcher.ts +69 -0
  134. package/src/server/services/WorkflowService.ts +441 -0
  135. package/src/server/services/agents/claude-code-provider.ts +320 -0
  136. package/src/server/services/agents/claude-provider.ts +248 -0
  137. package/src/server/services/agents/copilot-provider.ts +311 -0
  138. package/src/server/services/agents/demo-provider.ts +184 -0
  139. package/src/server/services/agents/index.ts +31 -0
  140. package/src/server/services/agents/ollama-provider.ts +267 -0
  141. package/src/server/services/agents/prompts.ts +482 -0
  142. package/src/server/services/agents/registry.ts +289 -0
  143. package/src/server/services/agents/types.ts +146 -0
  144. package/src/server/websocket/index.ts +104 -0
  145. package/src/shared/constants.ts +180 -0
  146. package/src/shared/types.ts +179 -0
  147. package/tailwind.config.ts +73 -0
  148. package/tests/e2e/app.spec.ts +90 -0
  149. package/tests/e2e/canvas.spec.ts +128 -0
  150. package/tests/e2e/workflow.spec.ts +185 -0
  151. package/tests/integration/api.test.ts +250 -0
  152. package/tests/integration/testApp.ts +31 -0
  153. package/tests/setup.ts +37 -0
  154. package/tests/unit/canvasStore.test.ts +502 -0
  155. package/tests/unit/components.test.tsx +151 -0
  156. package/tests/unit/executionStore.test.ts +527 -0
  157. package/tests/unit/layoutStore.test.ts +194 -0
  158. package/tests/unit/navigationStore.test.ts +152 -0
  159. package/tests/unit/stepValidation.test.ts +226 -0
  160. package/tests/unit/themeStore.test.ts +141 -0
  161. package/tests/unit/workflowToGraph.test.ts +289 -0
  162. package/tsconfig.json +29 -0
  163. package/tsconfig.server.json +28 -0
  164. package/vite.config.ts +31 -0
  165. package/vitest.config.ts +26 -0
@@ -0,0 +1,106 @@
1
+ import { Router, type Router as RouterType } from 'express';
2
+ import { WorkflowService } from '../services/WorkflowService.js';
3
+
4
+ const router: RouterType = Router();
5
+ const workflowService = new WorkflowService();
6
+
7
+ // List all workflows
8
+ router.get('/', async (_req, res) => {
9
+ try {
10
+ const workflows = await workflowService.listWorkflows();
11
+ res.json({ workflows });
12
+ } catch (error) {
13
+ res.status(500).json({
14
+ error: 'Failed to list workflows',
15
+ message: error instanceof Error ? error.message : 'Unknown error',
16
+ });
17
+ }
18
+ });
19
+
20
+ // Get a specific workflow
21
+ router.get('/:path(*)', async (req, res) => {
22
+ try {
23
+ const workflowPath = decodeURIComponent((req.params as Record<string, string>)['path(*)']);
24
+ const workflow = await workflowService.getWorkflow(workflowPath);
25
+
26
+ if (!workflow) {
27
+ return res.status(404).json({ error: 'Workflow not found' });
28
+ }
29
+
30
+ res.json({ workflow });
31
+ } catch (error) {
32
+ res.status(500).json({
33
+ error: 'Failed to get workflow',
34
+ message: error instanceof Error ? error.message : 'Unknown error',
35
+ });
36
+ }
37
+ });
38
+
39
+ // Create a new workflow
40
+ router.post('/', async (req, res) => {
41
+ try {
42
+ const { name, template } = req.body;
43
+
44
+ if (!name) {
45
+ return res.status(400).json({ error: 'Name is required' });
46
+ }
47
+
48
+ const workflow = await workflowService.createWorkflow(name, template);
49
+ res.status(201).json({ workflow });
50
+ } catch (error) {
51
+ res.status(500).json({
52
+ error: 'Failed to create workflow',
53
+ message: error instanceof Error ? error.message : 'Unknown error',
54
+ });
55
+ }
56
+ });
57
+
58
+ // Update a workflow
59
+ router.put('/:path(*)', async (req, res) => {
60
+ try {
61
+ const workflowPath = decodeURIComponent((req.params as Record<string, string>)['path(*)']);
62
+ const { workflow } = req.body;
63
+
64
+ if (!workflow) {
65
+ return res.status(400).json({ error: 'Workflow data is required' });
66
+ }
67
+
68
+ const updated = await workflowService.updateWorkflow(workflowPath, workflow);
69
+ res.json({ workflow: updated });
70
+ } catch (error) {
71
+ res.status(500).json({
72
+ error: 'Failed to update workflow',
73
+ message: error instanceof Error ? error.message : 'Unknown error',
74
+ });
75
+ }
76
+ });
77
+
78
+ // Delete a workflow
79
+ router.delete('/:path(*)', async (req, res) => {
80
+ try {
81
+ const workflowPath = decodeURIComponent((req.params as Record<string, string>)['path(*)']);
82
+ await workflowService.deleteWorkflow(workflowPath);
83
+ res.json({ success: true });
84
+ } catch (error) {
85
+ res.status(500).json({
86
+ error: 'Failed to delete workflow',
87
+ message: error instanceof Error ? error.message : 'Unknown error',
88
+ });
89
+ }
90
+ });
91
+
92
+ // Get workflow execution history
93
+ router.get('/:path(*)/runs', async (req, res) => {
94
+ try {
95
+ const workflowPath = decodeURIComponent((req.params as Record<string, string>)['path(*)']);
96
+ const runs = await workflowService.getExecutionHistory(workflowPath);
97
+ res.json({ runs });
98
+ } catch (error) {
99
+ res.status(500).json({
100
+ error: 'Failed to get execution history',
101
+ message: error instanceof Error ? error.message : 'Unknown error',
102
+ });
103
+ }
104
+ });
105
+
106
+ export { router as workflowRoutes };
@@ -0,0 +1,105 @@
1
+ /**
2
+ * AI Service - Backwards-compatible wrapper around the Agent Registry
3
+ *
4
+ * This service provides the same interface as before but now supports
5
+ * multiple AI backends through the agent provider system.
6
+ */
7
+
8
+ import { getAgentRegistry, type AgentRegistry, type PromptHistoryItem } from './agents/index.js';
9
+
10
+ interface Workflow {
11
+ metadata: any;
12
+ steps: any[];
13
+ tools?: Record<string, any>;
14
+ inputs?: Record<string, any>;
15
+ }
16
+
17
+ interface PromptResult {
18
+ explanation: string;
19
+ workflow?: Workflow;
20
+ diff?: string;
21
+ }
22
+
23
+ export class AIService {
24
+ private registry: AgentRegistry;
25
+ private initialized: boolean = false;
26
+
27
+ constructor() {
28
+ this.registry = getAgentRegistry();
29
+ }
30
+
31
+ /**
32
+ * Initialize the service with auto-detection of available providers
33
+ */
34
+ async initialize(): Promise<void> {
35
+ if (!this.initialized) {
36
+ await this.registry.autoDetectProvider();
37
+ this.initialized = true;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Process a prompt to modify a workflow
43
+ */
44
+ async processPrompt(prompt: string, workflow: Workflow): Promise<PromptResult> {
45
+ await this.initialize();
46
+ return this.registry.processPrompt(prompt, workflow);
47
+ }
48
+
49
+ /**
50
+ * Stream a prompt response (if supported by the active provider)
51
+ */
52
+ async streamPrompt(
53
+ prompt: string,
54
+ workflow: Workflow,
55
+ onChunk: (chunk: string) => void
56
+ ): Promise<PromptResult> {
57
+ await this.initialize();
58
+ return this.registry.streamPrompt(prompt, workflow, onChunk);
59
+ }
60
+
61
+ /**
62
+ * Get prompt history
63
+ */
64
+ async getHistory(): Promise<PromptHistoryItem[]> {
65
+ return this.registry.getHistory(20);
66
+ }
67
+
68
+ /**
69
+ * Get suggestions for the current workflow
70
+ */
71
+ async getSuggestions(
72
+ workflow: Workflow,
73
+ selectedStepId?: string
74
+ ): Promise<string[]> {
75
+ await this.initialize();
76
+ return this.registry.getSuggestions(workflow, selectedStepId);
77
+ }
78
+
79
+ /**
80
+ * Get the current provider status
81
+ */
82
+ getStatus(): {
83
+ activeProvider: string;
84
+ providers: Array<{ id: string; name: string; ready: boolean; model?: string; error?: string }>;
85
+ } {
86
+ return this.registry.getStatus();
87
+ }
88
+
89
+ /**
90
+ * Switch to a different provider
91
+ */
92
+ async setProvider(
93
+ providerId: string,
94
+ config?: { apiKey?: string; baseUrl?: string; model?: string }
95
+ ): Promise<boolean> {
96
+ return this.registry.setActiveProvider(providerId, config);
97
+ }
98
+
99
+ /**
100
+ * Get the registry for direct access to providers
101
+ */
102
+ getRegistry(): AgentRegistry {
103
+ return this.registry;
104
+ }
105
+ }
@@ -0,0 +1,69 @@
1
+ import { watch, type FSWatcher } from 'chokidar';
2
+ import type { Server as SocketIOServer } from 'socket.io';
3
+
4
+ export class FileWatcher {
5
+ private watcher: FSWatcher;
6
+ private io: SocketIOServer;
7
+
8
+ constructor(baseDir: string, io: SocketIOServer) {
9
+ this.io = io;
10
+
11
+ // Watch for workflow files
12
+ this.watcher = watch(['**/*.md', '**/*.yaml', '**/*.yml'], {
13
+ cwd: baseDir,
14
+ ignored: [
15
+ '**/node_modules/**',
16
+ '**/dist/**',
17
+ '**/.git/**',
18
+ '**/.*',
19
+ ],
20
+ persistent: true,
21
+ ignoreInitial: true,
22
+ awaitWriteFinish: {
23
+ stabilityThreshold: 300,
24
+ pollInterval: 100,
25
+ },
26
+ });
27
+
28
+ this.setupListeners();
29
+ console.log(`File watcher started for: ${baseDir}`);
30
+ }
31
+
32
+ private setupListeners() {
33
+ this.watcher.on('change', (path) => {
34
+ console.log(`File changed: ${path}`);
35
+ this.io.emit('workflow:updated', {
36
+ path,
37
+ event: 'change',
38
+ timestamp: new Date().toISOString(),
39
+ });
40
+ });
41
+
42
+ this.watcher.on('add', (path) => {
43
+ console.log(`File added: ${path}`);
44
+ this.io.emit('workflow:updated', {
45
+ path,
46
+ event: 'add',
47
+ timestamp: new Date().toISOString(),
48
+ });
49
+ });
50
+
51
+ this.watcher.on('unlink', (path) => {
52
+ console.log(`File removed: ${path}`);
53
+ this.io.emit('workflow:updated', {
54
+ path,
55
+ event: 'remove',
56
+ timestamp: new Date().toISOString(),
57
+ });
58
+ });
59
+
60
+ this.watcher.on('error', (error) => {
61
+ console.error('File watcher error:', error);
62
+ });
63
+ }
64
+
65
+ stop() {
66
+ this.watcher.close();
67
+ console.log('File watcher stopped');
68
+ }
69
+ }