snow-flow 1.1.74 → 1.1.75

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.
@@ -1073,6 +1073,17 @@ Use \`snow_deployment_debug\` for more information about this session.`,
1073
1073
  ],
1074
1074
  };
1075
1075
  }
1076
+ // Ensure we have a flow definition
1077
+ if (!args.flow_definition) {
1078
+ return {
1079
+ content: [
1080
+ {
1081
+ type: 'text',
1082
+ text: 'āŒ Flow deployment failed: No flow_definition provided.\n\nšŸ’” You need to provide a flow_definition with activities.\n\nExample:\n```json\n{\n "name": "approval_flow",\n "flow_definition": {\n "activities": [\n {\n "id": "activity_1",\n "name": "Check Condition",\n "type": "condition"\n }\n ]\n }\n}\n```\n\nOr use snow_create_flow with natural language for easier flow creation.',
1083
+ },
1084
+ ],
1085
+ };
1086
+ }
1076
1087
  const flowType = args.flow_type || 'flow';
1077
1088
  this.logger.info(`Deploying ${flowType} to ServiceNow`, { name: args.name, type: flowType });
1078
1089
  // Validate flow definition first if requested
@@ -2760,6 +2771,17 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
2760
2771
  ]
2761
2772
  };
2762
2773
  }
2774
+ // Check if definition is null or undefined
2775
+ if (!definition) {
2776
+ return {
2777
+ content: [
2778
+ {
2779
+ type: 'text',
2780
+ text: `āŒ Flow validation failed: No definition provided.\n\nšŸ’” Please provide a flow definition with activities.\n\nExample:\n\`\`\`json\n{\n "activities": [\n {\n "id": "activity_1",\n "name": "Send Notification",\n "type": "notification"\n }\n ]\n}\n\`\`\``
2781
+ }
2782
+ ]
2783
+ };
2784
+ }
2763
2785
  const issues = [];
2764
2786
  const warnings = [];
2765
2787
  const info = [];
@@ -2768,13 +2790,13 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
2768
2790
  // Handle multiple JSON structure variations: top-level, nested in "flow", nested in "flow_definition"
2769
2791
  let workingDefinition = definition;
2770
2792
  // Check if we have a nested structure like { "flow": { "steps": [...] } }
2771
- if (definition.flow && typeof definition.flow === 'object') {
2793
+ if (definition && definition.flow && typeof definition.flow === 'object') {
2772
2794
  workingDefinition = definition.flow;
2773
2795
  corrections.push('āœ… Processing nested flow structure (definition.flow)');
2774
2796
  info.push('šŸ’” Detected nested flow definition format - extracting flow content');
2775
2797
  }
2776
2798
  // Check if we have nested flow_definition
2777
- if (definition.flow_definition && typeof definition.flow_definition === 'object') {
2799
+ if (definition && definition.flow_definition && typeof definition.flow_definition === 'object') {
2778
2800
  workingDefinition = definition.flow_definition;
2779
2801
  corrections.push('āœ… Processing nested flow_definition structure');
2780
2802
  }
@@ -3784,13 +3806,127 @@ Use individual deployment tools like \`snow_deploy_${args.type}\` with manual co
3784
3806
  * Process natural language instruction into deployment configuration
3785
3807
  */
3786
3808
  async processNaturalLanguageInstruction(type, instruction) {
3787
- // For flows, delegate to flow composer
3809
+ // For flows, create a proper flow structure
3788
3810
  if (type === 'flow') {
3789
- // This would call the flow composer MCP, but for now return a basic structure
3811
+ // Extract flow name from instruction
3812
+ const flowName = this.extractNameFromInstruction(instruction);
3813
+ // Create a basic flow definition based on the instruction
3814
+ // This is a simplified version - in production, this would call the flow composer
3815
+ const lowerInstruction = instruction.toLowerCase();
3816
+ // Determine trigger type
3817
+ let triggerType = 'manual';
3818
+ let triggerTable = '';
3819
+ if (lowerInstruction.includes('new service catalog request') ||
3820
+ lowerInstruction.includes('new catalog request')) {
3821
+ triggerType = 'record_created';
3822
+ triggerTable = 'sc_request';
3823
+ }
3824
+ else if (lowerInstruction.includes('new incident')) {
3825
+ triggerType = 'record_created';
3826
+ triggerTable = 'incident';
3827
+ }
3828
+ else if (lowerInstruction.includes('updated') || lowerInstruction.includes('changes')) {
3829
+ triggerType = 'record_updated';
3830
+ }
3831
+ // Create activities based on instruction
3832
+ const activities = [];
3833
+ let activityId = 1;
3834
+ // Check for approval requirement
3835
+ if (lowerInstruction.includes('approval') || lowerInstruction.includes('approve')) {
3836
+ // Check for condition
3837
+ if (lowerInstruction.includes('if') &&
3838
+ (lowerInstruction.includes('monitor') || lowerInstruction.includes('display') ||
3839
+ lowerInstruction.includes('screen') || lowerInstruction.includes('lcd'))) {
3840
+ // Add condition activity
3841
+ activities.push({
3842
+ id: `activity_${activityId++}`,
3843
+ name: 'Check Item Type',
3844
+ type: 'condition',
3845
+ condition: 'current.cat_item.name.toLowerCase().includes("monitor") || current.cat_item.name.toLowerCase().includes("display") || current.cat_item.name.toLowerCase().includes("screen") || current.cat_item.name.toLowerCase().includes("lcd")',
3846
+ outputs: {
3847
+ condition_met: true
3848
+ }
3849
+ });
3850
+ }
3851
+ // Add approval activity
3852
+ activities.push({
3853
+ id: `activity_${activityId++}`,
3854
+ name: 'Request Approval',
3855
+ type: 'approval',
3856
+ approval_type: 'user',
3857
+ approvers: lowerInstruction.includes('admin') ? 'admin' : 'assignment_group.manager',
3858
+ inputs: {
3859
+ record: '${trigger.current}',
3860
+ approvers: lowerInstruction.includes('admin') ? 'admin' : 'assignment_group.manager'
3861
+ },
3862
+ outputs: {
3863
+ approval_state: '${approval.state}',
3864
+ approval_comments: '${approval.comments}'
3865
+ }
3866
+ });
3867
+ // Add wait for approval if mentioned
3868
+ if (lowerInstruction.includes('wait for approval')) {
3869
+ activities.push({
3870
+ id: `activity_${activityId++}`,
3871
+ name: 'Wait for Approval',
3872
+ type: 'wait',
3873
+ wait_type: 'approval',
3874
+ inputs: {
3875
+ approval_record: '${activity_' + (activityId - 2) + '.approval_id}'
3876
+ }
3877
+ });
3878
+ }
3879
+ }
3880
+ // Add update status if mentioned
3881
+ if (lowerInstruction.includes('update') && lowerInstruction.includes('status')) {
3882
+ activities.push({
3883
+ id: `activity_${activityId++}`,
3884
+ name: 'Update Request Status',
3885
+ type: 'update_record',
3886
+ table: triggerTable || 'sc_request',
3887
+ inputs: {
3888
+ record: '${trigger.current}',
3889
+ fields: {
3890
+ state: '${activity_' + (activityId - 2) + '.approval_state === "approved" ? "approved" : "rejected"}'
3891
+ }
3892
+ }
3893
+ });
3894
+ }
3895
+ // Create flow definition
3896
+ const flowDefinition = {
3897
+ name: flowName,
3898
+ description: instruction,
3899
+ table: triggerTable,
3900
+ trigger: {
3901
+ type: triggerType,
3902
+ table: triggerTable,
3903
+ condition: ''
3904
+ },
3905
+ activities: activities.length > 0 ? activities : [{
3906
+ id: 'activity_1',
3907
+ name: 'Log Action',
3908
+ type: 'log',
3909
+ message: 'Flow executed for: ' + instruction,
3910
+ level: 'info'
3911
+ }],
3912
+ connections: []
3913
+ };
3914
+ // Generate connections between activities
3915
+ for (let i = 0; i < activities.length - 1; i++) {
3916
+ flowDefinition.connections.push({
3917
+ from: activities[i].id,
3918
+ to: activities[i + 1].id,
3919
+ type: 'always'
3920
+ });
3921
+ }
3790
3922
  return {
3791
- name: this.extractNameFromInstruction(instruction),
3923
+ name: flowName,
3792
3924
  description: instruction,
3793
- instruction: instruction
3925
+ flow_definition: flowDefinition,
3926
+ table: triggerTable,
3927
+ trigger_type: triggerType,
3928
+ condition: '',
3929
+ active: true
3794
3930
  };
3795
3931
  }
3796
3932
  // For widgets, delegate to widget composer
@@ -3799,6 +3935,10 @@ Use individual deployment tools like \`snow_deploy_${args.type}\` with manual co
3799
3935
  name: this.extractNameFromInstruction(instruction),
3800
3936
  title: this.extractNameFromInstruction(instruction),
3801
3937
  description: instruction,
3938
+ template: '<div>Widget placeholder - implement with proper template</div>',
3939
+ css: '',
3940
+ server_script: '',
3941
+ client_script: '',
3802
3942
  instruction: instruction
3803
3943
  };
3804
3944
  }