@marktoflow/gui 2.0.0-alpha.12 → 2.0.0-alpha.13

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 (121) hide show
  1. package/package.json +1 -3
  2. package/.marktoflow/state/workflow-state.db +0 -0
  3. package/.marktoflow/state/workflow-state.db-shm +0 -0
  4. package/.marktoflow/state/workflow-state.db-wal +0 -0
  5. package/.turbo/turbo-build.log +0 -42
  6. package/.turbo/turbo-test.log +0 -38
  7. package/marktoflow-gui-2.0.0-alpha.12.tgz +0 -0
  8. package/playwright.config.ts +0 -27
  9. package/postcss.config.js +0 -6
  10. package/src/client/App.tsx +0 -520
  11. package/src/client/components/Canvas/Canvas.tsx +0 -425
  12. package/src/client/components/Canvas/ExecutionOverlay.tsx +0 -935
  13. package/src/client/components/Canvas/ForEachNode.tsx +0 -152
  14. package/src/client/components/Canvas/IfElseNode.tsx +0 -141
  15. package/src/client/components/Canvas/NodeContextMenu.tsx +0 -192
  16. package/src/client/components/Canvas/OutputNode.tsx +0 -111
  17. package/src/client/components/Canvas/ParallelNode.tsx +0 -157
  18. package/src/client/components/Canvas/StepNode.tsx +0 -106
  19. package/src/client/components/Canvas/SubWorkflowNode.tsx +0 -141
  20. package/src/client/components/Canvas/SwitchNode.tsx +0 -185
  21. package/src/client/components/Canvas/Toolbar.tsx +0 -227
  22. package/src/client/components/Canvas/TransformNode.tsx +0 -194
  23. package/src/client/components/Canvas/TriggerNode.tsx +0 -128
  24. package/src/client/components/Canvas/TryCatchNode.tsx +0 -164
  25. package/src/client/components/Canvas/WhileNode.tsx +0 -161
  26. package/src/client/components/Canvas/index.ts +0 -24
  27. package/src/client/components/Debug/VariableInspector.tsx +0 -148
  28. package/src/client/components/Editor/InputsEditor.tsx +0 -458
  29. package/src/client/components/Editor/NewStepWizard.tsx +0 -344
  30. package/src/client/components/Editor/StepEditor.tsx +0 -532
  31. package/src/client/components/Editor/YamlEditor.tsx +0 -160
  32. package/src/client/components/Panels/PropertiesPanel.tsx +0 -589
  33. package/src/client/components/Prompt/ChangePreview.tsx +0 -281
  34. package/src/client/components/Prompt/PromptHistoryPanel.tsx +0 -209
  35. package/src/client/components/Prompt/PromptInput.tsx +0 -110
  36. package/src/client/components/Settings/ProviderSwitcher.tsx +0 -228
  37. package/src/client/components/Sidebar/ImportDialog.tsx +0 -257
  38. package/src/client/components/Sidebar/Sidebar.tsx +0 -362
  39. package/src/client/components/common/Breadcrumb.tsx +0 -40
  40. package/src/client/components/common/Button.tsx +0 -68
  41. package/src/client/components/common/ContextMenu.tsx +0 -202
  42. package/src/client/components/common/KeyboardShortcuts.tsx +0 -149
  43. package/src/client/components/common/Modal.tsx +0 -93
  44. package/src/client/components/common/Tabs.tsx +0 -57
  45. package/src/client/components/common/ThemeToggle.tsx +0 -63
  46. package/src/client/components/index.ts +0 -32
  47. package/src/client/hooks/index.ts +0 -4
  48. package/src/client/hooks/useAIPrompt.ts +0 -108
  49. package/src/client/hooks/useCanvas.ts +0 -247
  50. package/src/client/hooks/useWebSocket.ts +0 -164
  51. package/src/client/hooks/useWorkflow.ts +0 -138
  52. package/src/client/main.tsx +0 -10
  53. package/src/client/stores/agentStore.ts +0 -109
  54. package/src/client/stores/canvasStore.ts +0 -348
  55. package/src/client/stores/editorStore.ts +0 -133
  56. package/src/client/stores/executionStore.ts +0 -502
  57. package/src/client/stores/index.ts +0 -4
  58. package/src/client/stores/layoutStore.ts +0 -103
  59. package/src/client/stores/navigationStore.ts +0 -49
  60. package/src/client/stores/promptStore.ts +0 -113
  61. package/src/client/stores/themeStore.ts +0 -75
  62. package/src/client/stores/workflowStore.ts +0 -185
  63. package/src/client/styles/globals.css +0 -452
  64. package/src/client/utils/cn.ts +0 -9
  65. package/src/client/utils/index.ts +0 -4
  66. package/src/client/utils/platform.ts +0 -46
  67. package/src/client/utils/serviceIcons.tsx +0 -97
  68. package/src/client/utils/stepValidation.ts +0 -155
  69. package/src/client/utils/workflowToGraph.ts +0 -523
  70. package/src/server/index.ts +0 -137
  71. package/src/server/routes/ai.ts +0 -91
  72. package/src/server/routes/execute.ts +0 -71
  73. package/src/server/routes/executions.ts +0 -136
  74. package/src/server/routes/tools.ts +0 -970
  75. package/src/server/routes/workflows.ts +0 -147
  76. package/src/server/services/AIService.ts +0 -105
  77. package/src/server/services/FileWatcher.ts +0 -69
  78. package/src/server/services/WorkflowService.ts +0 -601
  79. package/src/server/services/agents/claude-code-provider.ts +0 -320
  80. package/src/server/services/agents/claude-provider.ts +0 -248
  81. package/src/server/services/agents/codex-provider.ts +0 -398
  82. package/src/server/services/agents/copilot-provider.ts +0 -311
  83. package/src/server/services/agents/demo-provider.ts +0 -184
  84. package/src/server/services/agents/index.ts +0 -31
  85. package/src/server/services/agents/ollama-provider.ts +0 -267
  86. package/src/server/services/agents/prompts.ts +0 -509
  87. package/src/server/services/agents/registry.ts +0 -310
  88. package/src/server/services/agents/types.ts +0 -146
  89. package/src/server/websocket/index.ts +0 -117
  90. package/src/shared/constants.ts +0 -180
  91. package/src/shared/types.ts +0 -179
  92. package/tailwind.config.ts +0 -73
  93. package/tests/e2e/app.spec.ts +0 -90
  94. package/tests/e2e/canvas.spec.ts +0 -128
  95. package/tests/e2e/workflow.spec.ts +0 -185
  96. package/tests/integration/api.test.ts +0 -452
  97. package/tests/integration/testApp.ts +0 -31
  98. package/tests/setup.ts +0 -72
  99. package/tests/unit/ForEachNode.test.tsx +0 -308
  100. package/tests/unit/IfElseNode.test.tsx +0 -235
  101. package/tests/unit/ParallelNode.test.tsx +0 -344
  102. package/tests/unit/SwitchNode.test.tsx +0 -327
  103. package/tests/unit/TransformNode.test.tsx +0 -386
  104. package/tests/unit/TryCatchNode.test.tsx +0 -243
  105. package/tests/unit/WhileNode.test.tsx +0 -230
  106. package/tests/unit/agentStore.test.ts +0 -218
  107. package/tests/unit/canvasStore.test.ts +0 -502
  108. package/tests/unit/codexProvider.test.ts +0 -399
  109. package/tests/unit/components.test.tsx +0 -151
  110. package/tests/unit/executionStore.test.ts +0 -567
  111. package/tests/unit/layoutStore.test.ts +0 -194
  112. package/tests/unit/navigationStore.test.ts +0 -152
  113. package/tests/unit/platform.test.ts +0 -118
  114. package/tests/unit/serviceIcons.test.ts +0 -197
  115. package/tests/unit/stepValidation.test.ts +0 -226
  116. package/tests/unit/themeStore.test.ts +0 -141
  117. package/tests/unit/workflowToGraph.test.ts +0 -311
  118. package/tsconfig.json +0 -29
  119. package/tsconfig.server.json +0 -28
  120. package/vite.config.ts +0 -31
  121. 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
- }