@marktoflow/gui 2.0.0-alpha.5 → 2.0.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 (164) hide show
  1. package/README.md +48 -180
  2. package/client.log +0 -0
  3. package/dist/client/assets/index-DQeR1ew6.css +1 -0
  4. package/dist/client/assets/index-LbIVPHbD.js +833 -0
  5. package/dist/client/assets/index-LbIVPHbD.js.map +1 -0
  6. package/dist/client/index.html +2 -2
  7. package/dist/client/marktoflow-logo.png +0 -0
  8. package/dist/server/index.js +31 -5
  9. package/dist/server/index.js.map +1 -1
  10. package/dist/server/routes/admin.js +95 -0
  11. package/dist/server/routes/admin.js.map +1 -0
  12. package/dist/server/routes/ai.js +2 -2
  13. package/dist/server/routes/ai.js.map +1 -1
  14. package/dist/server/routes/collaboration.js +104 -0
  15. package/dist/server/routes/collaboration.js.map +1 -0
  16. package/dist/server/routes/execute.js +181 -14
  17. package/dist/server/routes/execute.js.map +1 -1
  18. package/dist/server/routes/form.js +160 -0
  19. package/dist/server/routes/form.js.map +1 -0
  20. package/dist/server/routes/settings.js +90 -0
  21. package/dist/server/routes/settings.js.map +1 -0
  22. package/dist/server/routes/templates.js +106 -0
  23. package/dist/server/routes/templates.js.map +1 -0
  24. package/dist/server/routes/versions.js +101 -0
  25. package/dist/server/routes/versions.js.map +1 -0
  26. package/dist/server/services/AIService.js +85 -2
  27. package/dist/server/services/AIService.js.map +1 -1
  28. package/dist/server/services/ExecutionManager.js +571 -0
  29. package/dist/server/services/ExecutionManager.js.map +1 -0
  30. package/dist/server/services/VersionService.js +65 -0
  31. package/dist/server/services/VersionService.js.map +1 -0
  32. package/dist/server/services/WorkflowService.js +8 -2
  33. package/dist/server/services/WorkflowService.js.map +1 -1
  34. package/dist/server/services/agents/copilot-provider.js +32 -0
  35. package/dist/server/services/agents/copilot-provider.js.map +1 -1
  36. package/dist/server/websocket/index.js +42 -0
  37. package/dist/server/websocket/index.js.map +1 -1
  38. package/dist/shared/constants.js +9 -0
  39. package/dist/shared/constants.js.map +1 -1
  40. package/dist/shared/settings.js +51 -0
  41. package/dist/shared/settings.js.map +1 -0
  42. package/package.json +14 -10
  43. package/public/marktoflow-logo.png +0 -0
  44. package/server.log +0 -0
  45. package/tests/integration/fixtures/test-workflow.md +6 -0
  46. package/.turbo/turbo-build.log +0 -42
  47. package/dist/client/assets/index-CM44OayM.js +0 -704
  48. package/dist/client/assets/index-CM44OayM.js.map +0 -1
  49. package/dist/client/assets/index-Dru63gi6.css +0 -1
  50. package/marktoflow-gui-2.0.0-alpha.5.tgz +0 -0
  51. package/playwright.config.ts +0 -27
  52. package/postcss.config.js +0 -6
  53. package/src/client/App.tsx +0 -520
  54. package/src/client/components/Canvas/Canvas.tsx +0 -425
  55. package/src/client/components/Canvas/ExecutionOverlay.tsx +0 -935
  56. package/src/client/components/Canvas/ForEachNode.tsx +0 -152
  57. package/src/client/components/Canvas/IfElseNode.tsx +0 -141
  58. package/src/client/components/Canvas/NodeContextMenu.tsx +0 -192
  59. package/src/client/components/Canvas/OutputNode.tsx +0 -111
  60. package/src/client/components/Canvas/ParallelNode.tsx +0 -157
  61. package/src/client/components/Canvas/StepNode.tsx +0 -106
  62. package/src/client/components/Canvas/SubWorkflowNode.tsx +0 -141
  63. package/src/client/components/Canvas/SwitchNode.tsx +0 -185
  64. package/src/client/components/Canvas/Toolbar.tsx +0 -227
  65. package/src/client/components/Canvas/TransformNode.tsx +0 -194
  66. package/src/client/components/Canvas/TriggerNode.tsx +0 -128
  67. package/src/client/components/Canvas/TryCatchNode.tsx +0 -164
  68. package/src/client/components/Canvas/WhileNode.tsx +0 -161
  69. package/src/client/components/Canvas/index.ts +0 -24
  70. package/src/client/components/Debug/VariableInspector.tsx +0 -148
  71. package/src/client/components/Editor/InputsEditor.tsx +0 -458
  72. package/src/client/components/Editor/NewStepWizard.tsx +0 -344
  73. package/src/client/components/Editor/StepEditor.tsx +0 -532
  74. package/src/client/components/Editor/YamlEditor.tsx +0 -160
  75. package/src/client/components/Panels/PropertiesPanel.tsx +0 -589
  76. package/src/client/components/Prompt/ChangePreview.tsx +0 -281
  77. package/src/client/components/Prompt/PromptHistoryPanel.tsx +0 -209
  78. package/src/client/components/Prompt/PromptInput.tsx +0 -110
  79. package/src/client/components/Settings/ProviderSwitcher.tsx +0 -228
  80. package/src/client/components/Sidebar/ImportDialog.tsx +0 -257
  81. package/src/client/components/Sidebar/Sidebar.tsx +0 -362
  82. package/src/client/components/common/Breadcrumb.tsx +0 -40
  83. package/src/client/components/common/Button.tsx +0 -68
  84. package/src/client/components/common/ContextMenu.tsx +0 -202
  85. package/src/client/components/common/KeyboardShortcuts.tsx +0 -149
  86. package/src/client/components/common/Modal.tsx +0 -93
  87. package/src/client/components/common/Tabs.tsx +0 -57
  88. package/src/client/components/common/ThemeToggle.tsx +0 -63
  89. package/src/client/components/index.ts +0 -32
  90. package/src/client/hooks/index.ts +0 -4
  91. package/src/client/hooks/useAIPrompt.ts +0 -108
  92. package/src/client/hooks/useCanvas.ts +0 -247
  93. package/src/client/hooks/useWebSocket.ts +0 -164
  94. package/src/client/hooks/useWorkflow.ts +0 -138
  95. package/src/client/main.tsx +0 -10
  96. package/src/client/stores/agentStore.ts +0 -109
  97. package/src/client/stores/canvasStore.ts +0 -348
  98. package/src/client/stores/editorStore.ts +0 -133
  99. package/src/client/stores/executionStore.ts +0 -502
  100. package/src/client/stores/index.ts +0 -4
  101. package/src/client/stores/layoutStore.ts +0 -103
  102. package/src/client/stores/navigationStore.ts +0 -49
  103. package/src/client/stores/promptStore.ts +0 -113
  104. package/src/client/stores/themeStore.ts +0 -75
  105. package/src/client/stores/workflowStore.ts +0 -185
  106. package/src/client/styles/globals.css +0 -452
  107. package/src/client/utils/cn.ts +0 -9
  108. package/src/client/utils/index.ts +0 -4
  109. package/src/client/utils/platform.ts +0 -46
  110. package/src/client/utils/serviceIcons.tsx +0 -97
  111. package/src/client/utils/stepValidation.ts +0 -155
  112. package/src/client/utils/workflowToGraph.ts +0 -523
  113. package/src/server/index.ts +0 -137
  114. package/src/server/routes/ai.ts +0 -91
  115. package/src/server/routes/execute.ts +0 -71
  116. package/src/server/routes/executions.ts +0 -136
  117. package/src/server/routes/tools.ts +0 -970
  118. package/src/server/routes/workflows.ts +0 -147
  119. package/src/server/services/AIService.ts +0 -105
  120. package/src/server/services/FileWatcher.ts +0 -69
  121. package/src/server/services/WorkflowService.ts +0 -601
  122. package/src/server/services/agents/claude-code-provider.ts +0 -320
  123. package/src/server/services/agents/claude-provider.ts +0 -248
  124. package/src/server/services/agents/codex-provider.ts +0 -398
  125. package/src/server/services/agents/copilot-provider.ts +0 -311
  126. package/src/server/services/agents/demo-provider.ts +0 -184
  127. package/src/server/services/agents/index.ts +0 -31
  128. package/src/server/services/agents/ollama-provider.ts +0 -267
  129. package/src/server/services/agents/prompts.ts +0 -509
  130. package/src/server/services/agents/registry.ts +0 -310
  131. package/src/server/services/agents/types.ts +0 -146
  132. package/src/server/websocket/index.ts +0 -117
  133. package/src/shared/constants.ts +0 -180
  134. package/src/shared/types.ts +0 -179
  135. package/tailwind.config.ts +0 -73
  136. package/tests/e2e/app.spec.ts +0 -90
  137. package/tests/e2e/canvas.spec.ts +0 -128
  138. package/tests/e2e/workflow.spec.ts +0 -185
  139. package/tests/integration/api.test.ts +0 -452
  140. package/tests/integration/testApp.ts +0 -31
  141. package/tests/setup.ts +0 -72
  142. package/tests/unit/ForEachNode.test.tsx +0 -308
  143. package/tests/unit/IfElseNode.test.tsx +0 -235
  144. package/tests/unit/ParallelNode.test.tsx +0 -344
  145. package/tests/unit/SwitchNode.test.tsx +0 -327
  146. package/tests/unit/TransformNode.test.tsx +0 -386
  147. package/tests/unit/TryCatchNode.test.tsx +0 -243
  148. package/tests/unit/WhileNode.test.tsx +0 -230
  149. package/tests/unit/agentStore.test.ts +0 -218
  150. package/tests/unit/canvasStore.test.ts +0 -502
  151. package/tests/unit/codexProvider.test.ts +0 -399
  152. package/tests/unit/components.test.tsx +0 -151
  153. package/tests/unit/executionStore.test.ts +0 -567
  154. package/tests/unit/layoutStore.test.ts +0 -194
  155. package/tests/unit/navigationStore.test.ts +0 -152
  156. package/tests/unit/platform.test.ts +0 -118
  157. package/tests/unit/serviceIcons.test.ts +0 -197
  158. package/tests/unit/stepValidation.test.ts +0 -226
  159. package/tests/unit/themeStore.test.ts +0 -141
  160. package/tests/unit/workflowToGraph.test.ts +0 -311
  161. package/tsconfig.json +0 -29
  162. package/tsconfig.server.json +0 -28
  163. package/vite.config.ts +0 -31
  164. package/vitest.config.ts +0 -26
@@ -1,509 +0,0 @@
1
- /**
2
- * Prompt Engineering Module for Workflow Modifications
3
- *
4
- * This module provides context-aware prompts for different workflow operations:
5
- * - Adding/removing steps
6
- * - Modifying step inputs
7
- * - Adding error handling
8
- * - Creating sub-workflows
9
- * - Adding conditions
10
- */
11
-
12
- // Available service integrations with their SDK mappings
13
- export const AVAILABLE_SERVICES = {
14
- slack: {
15
- sdk: '@slack/web-api',
16
- description: 'Slack messaging and workspace management',
17
- commonActions: [
18
- 'chat.postMessage',
19
- 'chat.update',
20
- 'chat.delete',
21
- 'conversations.list',
22
- 'conversations.history',
23
- 'users.list',
24
- 'files.upload',
25
- 'reactions.add',
26
- ],
27
- },
28
- github: {
29
- sdk: '@octokit/rest',
30
- description: 'GitHub repository, issues, and PR management',
31
- commonActions: [
32
- 'pulls.get',
33
- 'pulls.create',
34
- 'pulls.list',
35
- 'issues.create',
36
- 'issues.update',
37
- 'issues.list',
38
- 'repos.getContent',
39
- 'repos.createRelease',
40
- ],
41
- },
42
- jira: {
43
- sdk: 'jira.js',
44
- description: 'Jira issue and project tracking',
45
- commonActions: [
46
- 'issues.createIssue',
47
- 'issues.updateIssue',
48
- 'issues.getIssue',
49
- 'issues.searchJql',
50
- 'projects.getProject',
51
- 'transitions.transitionIssue',
52
- ],
53
- },
54
- gmail: {
55
- sdk: 'googleapis',
56
- description: 'Gmail email sending and management',
57
- commonActions: [
58
- 'users.messages.send',
59
- 'users.messages.list',
60
- 'users.messages.get',
61
- 'users.labels.list',
62
- 'users.drafts.create',
63
- ],
64
- },
65
- outlook: {
66
- sdk: '@microsoft/microsoft-graph-client',
67
- description: 'Microsoft Outlook email and calendar',
68
- commonActions: [
69
- 'mail.sendMail',
70
- 'mail.listMessages',
71
- 'calendar.createEvent',
72
- 'calendar.listEvents',
73
- ],
74
- },
75
- linear: {
76
- sdk: '@linear/sdk',
77
- description: 'Linear issue tracking and project management',
78
- commonActions: [
79
- 'issues.create',
80
- 'issues.update',
81
- 'issues.archive',
82
- 'projects.list',
83
- 'cycles.list',
84
- ],
85
- },
86
- notion: {
87
- sdk: '@notionhq/client',
88
- description: 'Notion pages and databases',
89
- commonActions: [
90
- 'pages.create',
91
- 'pages.update',
92
- 'databases.query',
93
- 'blocks.children.append',
94
- ],
95
- },
96
- discord: {
97
- sdk: 'discord.js',
98
- description: 'Discord messaging and server management',
99
- commonActions: [
100
- 'channels.send',
101
- 'channels.createWebhook',
102
- 'guilds.members.fetch',
103
- ],
104
- },
105
- airtable: {
106
- sdk: 'airtable',
107
- description: 'Airtable database and records',
108
- commonActions: [
109
- 'tables.list',
110
- 'records.create',
111
- 'records.update',
112
- 'records.list',
113
- ],
114
- },
115
- confluence: {
116
- sdk: 'confluence.js',
117
- description: 'Atlassian Confluence wiki pages',
118
- commonActions: [
119
- 'content.getContent',
120
- 'content.createContent',
121
- 'content.updateContent',
122
- 'space.getSpaces',
123
- ],
124
- },
125
- http: {
126
- sdk: 'built-in',
127
- description: 'Generic HTTP requests to any API',
128
- commonActions: ['request', 'get', 'post', 'put', 'delete'],
129
- },
130
- claude: {
131
- sdk: '@anthropic-ai/sdk',
132
- description: 'Claude AI for text generation and analysis',
133
- commonActions: ['messages.create', 'completions.create'],
134
- },
135
- opencode: {
136
- sdk: '@anthropic-ai/claude-agent-sdk',
137
- description: 'OpenCode for code generation and analysis',
138
- commonActions: ['generate', 'analyze', 'refactor'],
139
- },
140
- ollama: {
141
- sdk: 'ollama',
142
- description: 'Local Ollama LLM for AI tasks',
143
- commonActions: ['generate', 'chat', 'embeddings'],
144
- },
145
- codex: {
146
- sdk: '@openai/codex-sdk',
147
- description: 'OpenAI Codex for AI-powered coding workflows',
148
- commonActions: [
149
- 'chat',
150
- 'codeModify',
151
- 'codeAnalyze',
152
- 'codeReview',
153
- 'webSearch',
154
- 'execute',
155
- 'structured',
156
- 'resume',
157
- 'withImages',
158
- ],
159
- },
160
- copilot: {
161
- sdk: '@github/copilot-sdk',
162
- description: 'GitHub Copilot for AI code assistance',
163
- commonActions: [
164
- 'chat',
165
- 'codeReview',
166
- 'codeModify',
167
- 'withTools',
168
- 'withAgents',
169
- 'withMcp',
170
- ],
171
- },
172
- } as const;
173
-
174
- // Base system prompt with comprehensive context
175
- export const BASE_SYSTEM_PROMPT = `You are an expert workflow automation assistant for Marktoflow, a markdown-based workflow automation framework.
176
-
177
- ## Your Role
178
- Help users modify their workflows based on natural language requests. You must:
179
- 1. Understand the current workflow structure
180
- 2. Make precise modifications based on user requests
181
- 3. Explain what changes you made and why
182
- 4. Return valid YAML that can be parsed
183
-
184
- ## Workflow Structure
185
-
186
- A workflow consists of:
187
- - **metadata**: name, description, version, author, tags
188
- - **inputs**: declared input variables with types and defaults
189
- - **tools**: service SDK configurations with authentication
190
- - **steps**: array of actions to execute
191
-
192
- ### Step Structure
193
- \`\`\`yaml
194
- - id: unique-step-id # Required: kebab-case identifier
195
- name: "Human Readable Name" # Optional: display name
196
- action: service.method # Required: SDK method to call
197
- inputs: # Required: method parameters
198
- param1: value
199
- param2: "{{ variable }}" # Template variables
200
- output_variable: result_name # Optional: store output
201
- conditions: # Optional: when to run
202
- - "{{ previous_step.success }}"
203
- errorHandling: # Optional: error handling
204
- action: retry # stop | continue | retry
205
- maxRetries: 3
206
- \`\`\`
207
-
208
- ### Template Variables
209
- - Access inputs: \`{{ inputs.variable_name }}\`
210
- - Access step outputs: \`{{ step_id.field }}\` or \`{{ output_variable.field }}\`
211
- - JavaScript expressions: \`{{ inputs.count > 10 ? "many" : "few" }}\`
212
-
213
- ### Available Services
214
- ${Object.entries(AVAILABLE_SERVICES)
215
- .map(([name, info]) => `- **${name}**: ${info.description} (SDK: ${info.sdk})`)
216
- .join('\n')}
217
-
218
- ## Response Format
219
-
220
- Always respond with:
221
- 1. A brief explanation (1-3 sentences) of what you changed
222
- 2. The complete modified workflow in a YAML code block
223
-
224
- \`\`\`yaml
225
- # Your modified workflow here
226
- \`\`\`
227
-
228
- ## Important Guidelines
229
- - Only make the changes requested - don't "improve" other parts
230
- - Preserve existing step IDs unless explicitly asked to rename
231
- - Generate unique IDs for new steps (use kebab-case)
232
- - Ensure all YAML is valid and properly indented
233
- - Keep the same workflow structure (don't remove required sections)
234
- `;
235
-
236
- // Operation-specific prompts for different modification types
237
- export const OPERATION_PROMPTS = {
238
- addStep: `
239
- ## Adding Steps
240
- When adding a new step:
241
- 1. Generate a unique, descriptive kebab-case ID (e.g., "send-slack-notification")
242
- 2. Add a human-readable name
243
- 3. Use the correct action format: service.method
244
- 4. Include all required inputs for the action
245
- 5. Consider adding an output_variable if the result will be used later
246
- 6. Place the step at a logical position in the workflow
247
-
248
- Common step patterns:
249
- - Notifications: slack.chat.postMessage, gmail.users.messages.send
250
- - API calls: http.request, github.pulls.get
251
- - Data processing: Transform data between steps
252
- `,
253
-
254
- removeStep: `
255
- ## Removing Steps
256
- When removing a step:
257
- 1. Remove the entire step block from the steps array
258
- 2. Check if other steps reference this step's output_variable
259
- 3. If references exist, either:
260
- - Update those references to use a different source
261
- - Warn the user about broken references
262
- 4. Preserve the workflow structure and other steps
263
- `,
264
-
265
- modifyInputs: `
266
- ## Modifying Step Inputs
267
- When modifying inputs:
268
- 1. Only change the specified inputs
269
- 2. Preserve other inputs unless asked to remove them
270
- 3. Use template variables for dynamic values: {{ variable }}
271
- 4. Ensure the value type matches what the action expects
272
- 5. Consider adding validation or error handling if needed
273
- `,
274
-
275
- addErrorHandling: `
276
- ## Adding Error Handling
277
- Error handling options:
278
- - **stop**: Halt workflow execution on error (default)
279
- - **continue**: Log error and continue to next step
280
- - **retry**: Retry the step with backoff
281
-
282
- Example:
283
- \`\`\`yaml
284
- errorHandling:
285
- action: retry
286
- maxRetries: 3
287
- retryDelay: 1000 # milliseconds
288
- fallback:
289
- action: slack.chat.postMessage
290
- inputs:
291
- channel: "#alerts"
292
- text: "Step {{ step.name }} failed: {{ error.message }}"
293
- \`\`\`
294
- `,
295
-
296
- addConditions: `
297
- ## Adding Conditions
298
- Conditions control when a step executes. They are JavaScript-like expressions.
299
-
300
- Examples:
301
- \`\`\`yaml
302
- conditions:
303
- - "{{ previous_step.success === true }}"
304
- - "{{ inputs.environment === 'production' }}"
305
- - "{{ pr_details.state === 'open' && pr_details.draft === false }}"
306
- \`\`\`
307
-
308
- Common patterns:
309
- - Check previous step success: \`{{ step_id.success }}\`
310
- - Check variable values: \`{{ output_var.field === 'value' }}\`
311
- - Check input values: \`{{ inputs.flag === true }}\`
312
- - Combine conditions: \`{{ condition1 && condition2 }}\`
313
- `,
314
-
315
- createSubWorkflow: `
316
- ## Creating Sub-Workflows
317
- A sub-workflow is referenced by path instead of an action:
318
-
319
- \`\`\`yaml
320
- - id: run-notification-workflow
321
- name: "Run Notification Workflow"
322
- workflowPath: "./workflows/notify.md"
323
- inputs:
324
- message: "{{ previous_step.summary }}"
325
- channel: "{{ inputs.notification_channel }}"
326
- output_variable: notification_result
327
- \`\`\`
328
-
329
- When creating sub-workflows:
330
- 1. Use workflowPath instead of action
331
- 2. Pass inputs that the sub-workflow expects
332
- 3. The sub-workflow's outputs are available via output_variable
333
- `,
334
-
335
- addTool: `
336
- ## Adding Tool Configurations
337
- Tools are configured with their SDK and authentication:
338
-
339
- \`\`\`yaml
340
- tools:
341
- slack:
342
- sdk: '@slack/web-api'
343
- auth:
344
- token: '\${SLACK_BOT_TOKEN}'
345
- github:
346
- sdk: '@octokit/rest'
347
- auth:
348
- token: '\${GITHUB_TOKEN}'
349
- \`\`\`
350
-
351
- Authentication patterns:
352
- - Environment variables: \${ENV_VAR_NAME}
353
- - OAuth tokens: Stored and retrieved automatically
354
- - API keys: Configured per-tool
355
- `,
356
- };
357
-
358
- /**
359
- * Build a context-aware prompt based on the user's request
360
- */
361
- export function buildPrompt(
362
- userRequest: string,
363
- workflow: { metadata?: Record<string, unknown>; steps: unknown[]; tools?: Record<string, unknown> },
364
- context?: {
365
- selectedStepId?: string;
366
- recentHistory?: string[];
367
- }
368
- ): { systemPrompt: string; userPrompt: string } {
369
- // Detect the type of operation requested
370
- const operations = detectOperations(userRequest);
371
-
372
- // Build system prompt with relevant operation guides
373
- let systemPrompt = BASE_SYSTEM_PROMPT;
374
- for (const op of operations) {
375
- if (OPERATION_PROMPTS[op as keyof typeof OPERATION_PROMPTS]) {
376
- systemPrompt += '\n' + OPERATION_PROMPTS[op as keyof typeof OPERATION_PROMPTS];
377
- }
378
- }
379
-
380
- // Build user prompt with context
381
- let userPrompt = `Current workflow:\n\`\`\`yaml\n${formatWorkflow(workflow)}\n\`\`\`\n\n`;
382
-
383
- if (context?.selectedStepId) {
384
- const selectedStep = workflow.steps?.find(
385
- (s: any) => s.id === context.selectedStepId
386
- );
387
- if (selectedStep) {
388
- userPrompt += `Currently selected step: "${context.selectedStepId}"\n\n`;
389
- }
390
- }
391
-
392
- if (context?.recentHistory && context.recentHistory.length > 0) {
393
- userPrompt += `Recent changes:\n${context.recentHistory.map((h) => `- ${h}`).join('\n')}\n\n`;
394
- }
395
-
396
- userPrompt += `User request: ${userRequest}`;
397
-
398
- return { systemPrompt, userPrompt };
399
- }
400
-
401
- /**
402
- * Detect what type of operations the user is requesting
403
- */
404
- function detectOperations(request: string): string[] {
405
- const lower = request.toLowerCase();
406
- const operations: string[] = [];
407
-
408
- if (lower.includes('add') && (lower.includes('step') || lower.includes('action'))) {
409
- operations.push('addStep');
410
- }
411
- if (lower.includes('remove') || lower.includes('delete')) {
412
- operations.push('removeStep');
413
- }
414
- if (lower.includes('change') || lower.includes('modify') || lower.includes('update')) {
415
- operations.push('modifyInputs');
416
- }
417
- if (lower.includes('error') || lower.includes('retry') || lower.includes('fallback')) {
418
- operations.push('addErrorHandling');
419
- }
420
- if (lower.includes('condition') || lower.includes('if') || lower.includes('when')) {
421
- operations.push('addConditions');
422
- }
423
- if (lower.includes('sub-workflow') || lower.includes('subworkflow') || lower.includes('nested')) {
424
- operations.push('createSubWorkflow');
425
- }
426
- if (lower.includes('tool') || lower.includes('sdk') || lower.includes('connect')) {
427
- operations.push('addTool');
428
- }
429
-
430
- // Default to addStep if no specific operation detected
431
- if (operations.length === 0) {
432
- operations.push('addStep');
433
- }
434
-
435
- return operations;
436
- }
437
-
438
- /**
439
- * Format workflow for prompt (simplified YAML)
440
- */
441
- function formatWorkflow(workflow: {
442
- metadata?: Record<string, unknown>;
443
- steps: unknown[];
444
- tools?: Record<string, unknown>;
445
- }): string {
446
- const { stringify } = require('yaml');
447
- return stringify(workflow, { indent: 2, lineWidth: 0 });
448
- }
449
-
450
- /**
451
- * Generate contextual suggestions based on workflow state
452
- */
453
- export function generateSuggestions(
454
- workflow: { metadata?: Record<string, unknown>; steps: unknown[]; tools?: Record<string, unknown> },
455
- selectedStepId?: string
456
- ): string[] {
457
- const suggestions: string[] = [];
458
- const steps = workflow.steps || [];
459
-
460
- // No steps - suggest getting started
461
- if (steps.length === 0) {
462
- return [
463
- 'Add a step to send a Slack message',
464
- 'Add a step to fetch data from GitHub',
465
- 'Add an HTTP request step',
466
- 'Create a workflow that monitors a webhook',
467
- ];
468
- }
469
-
470
- // Check for missing error handling
471
- const stepsWithoutErrorHandling = steps.filter((s: any) => !s.errorHandling);
472
- if (stepsWithoutErrorHandling.length > 0) {
473
- suggestions.push('Add error handling with retries to all steps');
474
- }
475
-
476
- // Check for missing notifications
477
- const hasNotification = steps.some(
478
- (s: any) =>
479
- s.action?.includes('slack') ||
480
- s.action?.includes('gmail') ||
481
- s.action?.includes('discord')
482
- );
483
- if (!hasNotification) {
484
- suggestions.push('Add a Slack notification at the end');
485
- }
486
-
487
- // Step-specific suggestions
488
- if (selectedStepId) {
489
- const step = steps.find((s: any) => s.id === selectedStepId) as any;
490
- if (step) {
491
- if (!step.errorHandling) {
492
- suggestions.push(`Add retry logic to "${step.name || step.id}"`);
493
- }
494
- if (!step.conditions || step.conditions.length === 0) {
495
- suggestions.push(`Add a condition to "${step.name || step.id}"`);
496
- }
497
- suggestions.push(`Duplicate "${step.name || step.id}" with modifications`);
498
- }
499
- }
500
-
501
- // General suggestions
502
- if (steps.length >= 3) {
503
- suggestions.push('Convert these steps into a reusable sub-workflow');
504
- }
505
- suggestions.push('Add a step to log results to a database');
506
- suggestions.push('Add parallel execution for independent steps');
507
-
508
- return suggestions.slice(0, 5);
509
- }