snow-flow 3.0.13 → 3.0.15

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.
@@ -53,7 +53,7 @@ class ServiceNowDeploymentMCP {
53
53
  inputSchema: {
54
54
  type: 'object',
55
55
  properties: {
56
- type: { type: 'string', enum: ['widget', 'workflow', 'application'] },
56
+ type: { type: 'string', enum: ['widget', 'application'] }, // removed 'workflow' - deprecated
57
57
  artifact: { type: 'object', description: 'The artifact to validate' },
58
58
  },
59
59
  required: ['type', 'artifact'],
@@ -83,11 +83,11 @@ class ServiceNowDeploymentMCP {
83
83
  },
84
84
  {
85
85
  name: 'snow_export_artifact',
86
- description: 'Exports ServiceNow artifacts (widgets, workflows, applications) to JSON/XML format for backup, version control, or migration purposes.',
86
+ description: 'Exports ServiceNow artifacts (widgets, applications) to JSON/XML format for backup, version control, or migration purposes.', // removed workflows
87
87
  inputSchema: {
88
88
  type: 'object',
89
89
  properties: {
90
- type: { type: 'string', enum: ['widget', 'workflow', 'application'] },
90
+ type: { type: 'string', enum: ['widget', 'application'] }, // removed 'workflow' - deprecated
91
91
  sys_id: { type: 'string', description: 'Sys ID of the artifact' },
92
92
  format: { type: 'string', enum: ['json', 'xml', 'update_set'], default: 'json' },
93
93
  },
@@ -100,7 +100,7 @@ class ServiceNowDeploymentMCP {
100
100
  inputSchema: {
101
101
  type: 'object',
102
102
  properties: {
103
- type: { type: 'string', enum: ['widget', 'workflow', 'application'] },
103
+ type: { type: 'string', enum: ['widget', 'application'] }, // removed 'workflow' - deprecated
104
104
  file_path: { type: 'string', description: 'Path to the artifact file' },
105
105
  format: { type: 'string', enum: ['json', 'xml', 'update_set'], default: 'json' },
106
106
  },
@@ -115,7 +115,7 @@ class ServiceNowDeploymentMCP {
115
115
  properties: {
116
116
  source_instance: { type: 'string', description: 'Source instance URL' },
117
117
  target_instance: { type: 'string', description: 'Target instance URL' },
118
- type: { type: 'string', enum: ['widget', 'workflow', 'application'] },
118
+ type: { type: 'string', enum: ['widget', 'application'] }, // removed 'workflow' - deprecated
119
119
  sys_id: { type: 'string', description: 'Sys ID of the artifact to clone' },
120
120
  },
121
121
  required: ['source_instance', 'target_instance', 'type', 'sys_id'],
@@ -461,11 +461,11 @@ class ServiceNowDeploymentMCP {
461
461
  */
462
462
  getTableForType(type) {
463
463
  const tableMap = {
464
- 'flow': 'sys_hub_flow',
464
+ // 'flow': 'sys_hub_flow', // REMOVED - flows deprecated
465
465
  'widget': 'sp_widget',
466
466
  'script': 'sys_script_include',
467
467
  'business_rule': 'sys_script',
468
- 'workflow': 'wf_workflow',
468
+ // 'workflow': 'wf_workflow', // REMOVED - workflows deprecated
469
469
  'application': 'sys_app',
470
470
  'ui_action': 'sys_ui_action',
471
471
  'ui_page': 'sys_ui_page',
@@ -1675,435 +1675,474 @@ ${args.widgets && args.widgets.length > 0 ? args.widgets.map((w, i) => `
1675
1675
  `;
1676
1676
  return css;
1677
1677
  }
1678
- async deployFlow(args) {
1679
- try {
1680
- // Enhanced authentication check with token refresh for deployment
1681
- const authResult = await this.deploymentAuthManager.ensureDeploymentAuth();
1682
- if (!authResult.isValid) {
1683
- this.logger.error('Deployment authentication failed:', authResult.error);
1684
- // If auth failed, try to refresh token
1685
- const refreshResult = await this.deploymentAuthManager.forceTokenRefresh();
1686
- if (!refreshResult.success) {
1687
- return {
1688
- content: [
1689
- {
1690
- type: 'text',
1691
- text: `❌ Deployment authentication failed.\n\nError: ${authResult.error || 'Unable to authenticate'}\n\nRecommendations:\n${(authResult.recommendations || ['Run: snow-flow auth login']).map(r => `• ${r}`).join('\n')}\n\nNote: Deployment requires valid OAuth tokens with write permissions.`,
1692
- },
1693
- ],
1694
- };
1695
- }
1696
- }
1697
- // Warn if token may lack write permissions
1698
- if (!authResult.hasWriteScope) {
1699
- this.logger.warn('⚠️ Token may lack write permissions, deployment might fail with 403');
1700
- }
1701
- // Ensure we have a flow definition
1702
- if (!args.flow_definition) {
1703
- return {
1704
- content: [
1705
- {
1706
- type: 'text',
1707
- 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.',
1708
- },
1709
- ],
1710
- };
1711
- }
1712
- const flowType = args.flow_type || 'flow';
1713
- this.logger.info(`Deploying ${flowType} to ServiceNow`, { name: args.name, type: flowType });
1714
- // Validate flow definition first if requested
1715
- let validatedDefinition = args.flow_definition;
1716
- if (args.validate_before_deploy !== false) {
1717
- const validationResult = await this.validateFlowDefinition({
1718
- definition: args.flow_definition,
1719
- flow_type: flowType,
1720
- show_preview: false,
1721
- test_mode: false,
1722
- check_dependencies: true
1723
- });
1724
- // Check if validation failed
1725
- const validationText = validationResult.content?.[0]?.text || '';
1726
- if (validationText.includes('❌') || validationText.includes('ERROR')) {
1727
- return {
1728
- content: [
1729
- {
1730
- type: 'text',
1731
- text: `❌ Flow validation failed. Please fix the following issues:\n\n${validationText}\n\nUse snow_validate_flow_definition to preview and test your flow before deployment.`
1732
- }
1733
- ]
1734
- };
1735
- }
1736
- // CRITICAL: Use the corrected definition from validation
1737
- // The validateFlowDefinition method may have auto-corrected "steps" or "actions" to "activities"
1738
- if (validationText.includes('Auto-converted "steps" to "activities"') ||
1739
- validationText.includes('Auto-converted "actions" to "activities"') ||
1740
- validationText.includes('Smart Auto-Corrections Applied')) {
1741
- // Re-parse the corrected definition from the validation process
1742
- const tempDef = typeof args.flow_definition === 'string' ? JSON.parse(args.flow_definition) : args.flow_definition;
1743
- if (tempDef.steps && !tempDef.activities) {
1744
- tempDef.activities = tempDef.steps;
1745
- delete tempDef.steps;
1746
- }
1747
- else if (tempDef.actions && !tempDef.activities) {
1748
- tempDef.activities = tempDef.actions;
1749
- delete tempDef.actions;
1750
- }
1751
- validatedDefinition = JSON.stringify(tempDef);
1752
- this.logger.info('Using auto-corrected flow definition for deployment');
1753
- }
1754
- }
1755
- // Ensure Update Set is active
1756
- const { updateSetId, updateSetName } = await this.ensureUpdateSet('Flow', args.name);
1757
- // Check if this is a master flow with linked artifacts
1758
- const isComposedFlow = args.composed_flow || args.linked_artifacts;
1759
- const linkedArtifacts = args.linked_artifacts || [];
1760
- // Deploy linked artifacts first if this is a composed flow
1761
- const deployedArtifacts = [];
1762
- if (isComposedFlow && linkedArtifacts.length > 0) {
1763
- this.logger.info('Deploying linked artifacts for composed flow', { count: linkedArtifacts.length });
1764
- for (const artifact of linkedArtifacts) {
1765
- try {
1766
- const deployResult = await this.deployLinkedArtifact(artifact);
1767
- deployedArtifacts.push(deployResult);
1768
- }
1769
- catch (error) {
1770
- this.logger.error('Failed to deploy linked artifact', { artifact, error });
1771
- throw new Error(`Failed to deploy linked artifact ${artifact.name}: ${error}`);
1772
- }
1678
+ // DEPRECATED: Flow deployment is no longer supported - flows, workflows, and subflows have been removed
1679
+ /* private async deployFlow(args: any) {
1680
+ try {
1681
+ // Enhanced authentication check with token refresh for deployment
1682
+ const authResult = await this.deploymentAuthManager.ensureDeploymentAuth();
1683
+ if (!authResult.isValid) {
1684
+ this.logger.error('Deployment authentication failed:', authResult.error);
1685
+
1686
+ // If auth failed, try to refresh token
1687
+ const refreshResult = await this.deploymentAuthManager.forceTokenRefresh();
1688
+ if (!refreshResult.success) {
1689
+ return {
1690
+ content: [
1691
+ {
1692
+ type: 'text',
1693
+ text: `❌ Deployment authentication failed.\n\nError: ${authResult.error || 'Unable to authenticate'}\n\nRecommendations:\n${(authResult.recommendations || ['Run: snow-flow auth login']).map(r => `• ${r}`).join('\n')}\n\nNote: Deployment requires valid OAuth tokens with write permissions.`,
1694
+ },
1695
+ ],
1696
+ };
1697
+ }
1698
+ }
1699
+
1700
+ // Warn if token may lack write permissions
1701
+ if (!authResult.hasWriteScope) {
1702
+ this.logger.warn('⚠️ Token may lack write permissions, deployment might fail with 403');
1703
+ }
1704
+
1705
+ // Ensure we have a flow definition
1706
+ if (!args.flow_definition) {
1707
+ return {
1708
+ content: [
1709
+ {
1710
+ type: 'text',
1711
+ 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.',
1712
+ },
1713
+ ],
1714
+ };
1715
+ }
1716
+
1717
+ const flowType = args.flow_type || 'flow';
1718
+ this.logger.info(`Deploying ${flowType} to ServiceNow`, { name: args.name, type: flowType });
1719
+
1720
+ // Validate flow definition first if requested
1721
+ let validatedDefinition = args.flow_definition;
1722
+ if (args.validate_before_deploy !== false) {
1723
+ const validationResult = await this.validateFlowDefinition({
1724
+ definition: args.flow_definition,
1725
+ flow_type: flowType,
1726
+ show_preview: false,
1727
+ test_mode: false,
1728
+ check_dependencies: true
1729
+ });
1730
+
1731
+ // Check if validation failed
1732
+ const validationText = validationResult.content?.[0]?.text || '';
1733
+ if (validationText.includes('❌') || validationText.includes('ERROR')) {
1734
+ return {
1735
+ content: [
1736
+ {
1737
+ type: 'text',
1738
+ text: `❌ Flow validation failed. Please fix the following issues:\n\n${validationText}\n\nUse snow_validate_flow_definition to preview and test your flow before deployment.`
1773
1739
  }
1774
- }
1775
- // Parse flow definition to inject deployed artifact references
1776
- // Use the validated and corrected definition
1777
- let flowDefinition = validatedDefinition;
1778
- if (typeof flowDefinition === 'string') {
1779
- flowDefinition = JSON.parse(flowDefinition);
1780
- }
1781
- // Update flow activities with deployed artifact sys_ids
1782
- if (flowDefinition.activities && deployedArtifacts.length > 0) {
1783
- flowDefinition.activities = flowDefinition.activities.map((activity) => {
1784
- if (activity.artifact_reference) {
1785
- const deployed = deployedArtifacts.find(d => d.originalId === activity.artifact_reference.sys_id ||
1786
- d.name === activity.artifact_reference.name);
1787
- if (deployed) {
1788
- activity.artifact_sys_id = deployed.sys_id;
1789
- activity.artifact_api_name = deployed.api_name;
1790
- }
1791
- }
1792
- return activity;
1793
- });
1794
- }
1795
- // Create flow data based on flow type
1796
- const flowData = {
1797
- name: args.name,
1798
- description: args.description,
1799
- active: args.active !== false,
1800
- flow_definition: JSON.stringify(flowDefinition),
1801
- category: args.category || 'automation',
1802
- // Additional fields for composed flows
1803
- is_composed: isComposedFlow,
1804
- linked_artifact_count: linkedArtifacts.length,
1805
- artifact_references: deployedArtifacts.map(a => a.sys_id).join(',')
1740
+ ]
1806
1741
  };
1807
- // Configure based on flow type
1808
- switch (flowType) {
1809
- case 'flow':
1810
- flowData.table = args.table || '';
1811
- flowData.trigger_type = args.trigger_type;
1812
- flowData.condition = args.condition || '';
1813
- flowData.type = 'flow';
1814
- break;
1815
- case 'subflow':
1816
- // Subflows don't have triggers, they're called by other flows
1817
- flowData.type = 'subflow';
1818
- flowData.inputs = flowDefinition.inputs || [];
1819
- flowData.outputs = flowDefinition.outputs || [];
1820
- break;
1821
- case 'action':
1822
- // Actions are reusable components
1823
- flowData.type = 'action';
1824
- flowData.action_type = args.action_type || 'custom';
1825
- flowData.inputs = flowDefinition.inputs || [];
1826
- flowData.outputs = flowDefinition.outputs || [];
1827
- break;
1828
- }
1829
- // Deploy to ServiceNow using appropriate API based on flow type
1830
- let result;
1831
- let usedFallback = false;
1832
- let fallbackBusinessRule = null;
1742
+ }
1743
+
1744
+ // CRITICAL: Use the corrected definition from validation
1745
+ // The validateFlowDefinition method may have auto-corrected "steps" or "actions" to "activities"
1746
+ if (validationText.includes('Auto-converted "steps" to "activities"') ||
1747
+ validationText.includes('Auto-converted "actions" to "activities"') ||
1748
+ validationText.includes('Smart Auto-Corrections Applied')) {
1749
+ // Re-parse the corrected definition from the validation process
1750
+ const tempDef = typeof args.flow_definition === 'string' ? JSON.parse(args.flow_definition) : args.flow_definition;
1751
+ if (tempDef.steps && !tempDef.activities) {
1752
+ tempDef.activities = tempDef.steps;
1753
+ delete tempDef.steps;
1754
+ } else if (tempDef.actions && !tempDef.activities) {
1755
+ tempDef.activities = tempDef.actions;
1756
+ delete tempDef.actions;
1757
+ }
1758
+ validatedDefinition = JSON.stringify(tempDef);
1759
+ this.logger.info('Using auto-corrected flow definition for deployment');
1760
+ }
1761
+ }
1762
+
1763
+ // Ensure Update Set is active
1764
+ const { updateSetId, updateSetName } = await this.ensureUpdateSet('Flow', args.name);
1765
+
1766
+ // Check if this is a master flow with linked artifacts
1767
+ const isComposedFlow = args.composed_flow || args.linked_artifacts;
1768
+ const linkedArtifacts = args.linked_artifacts || [];
1769
+
1770
+ // Deploy linked artifacts first if this is a composed flow
1771
+ const deployedArtifacts: any[] = [];
1772
+ if (isComposedFlow && linkedArtifacts.length > 0) {
1773
+ this.logger.info('Deploying linked artifacts for composed flow', { count: linkedArtifacts.length });
1774
+
1775
+ for (const artifact of linkedArtifacts) {
1833
1776
  try {
1834
- // Real ServiceNow Flow deployment using proper API calls
1835
- switch (flowType) {
1836
- case 'flow':
1837
- // Create workflow record in ServiceNow
1838
- result = await this.client.create('wf_workflow', {
1839
- name: flowData.name || `flow_${Date.now()}`,
1840
- description: flowData.description || 'Created by Snow-Flow',
1841
- table: flowData.table || 'incident',
1842
- active: flowData.active !== false,
1843
- condition: flowData.condition || '',
1844
- script: flowData.script || '// Flow logic here',
1845
- order: flowData.order || 100
1846
- });
1847
- break;
1848
- case 'subflow':
1849
- // Create subflow as a workflow activity
1850
- result = await this.client.create('wf_workflow', {
1851
- name: flowData.name || `subflow_${Date.now()}`,
1852
- description: `${flowData.description || 'Subflow created by Snow-Flow'} [SUBFLOW]`,
1853
- table: flowData.table || 'incident',
1854
- active: flowData.active !== false,
1855
- condition: flowData.condition || '',
1856
- script: flowData.script || '// Subflow logic here',
1857
- order: flowData.order || 200
1858
- });
1859
- break;
1860
- case 'action':
1861
- // Create workflow activity/action
1862
- if (!flowData.workflow_id) {
1863
- throw new Error('workflow_id is required for flow actions');
1864
- }
1865
- result = await this.client.create('wf_activity', {
1866
- workflow: flowData.workflow_id,
1867
- name: flowData.name || `action_${Date.now()}`,
1868
- script: flowData.script || '// Action script here',
1869
- condition: flowData.condition || '',
1870
- order: flowData.order || 100,
1871
- active: flowData.active !== false
1872
- });
1873
- break;
1874
- default:
1875
- throw new Error(`Unknown flow type: ${flowType}. Supported types: flow, subflow, action`);
1876
- }
1777
+ const deployResult = await this.deployLinkedArtifact(artifact);
1778
+ deployedArtifacts.push(deployResult);
1779
+ } catch (error) {
1780
+ this.logger.error('Failed to deploy linked artifact', { artifact, error });
1781
+ throw new Error(`Failed to deploy linked artifact ${artifact.name}: ${error}`);
1877
1782
  }
1878
- catch (flowError) {
1879
- this.logger.warn('Flow Designer deployment failed, attempting Business Rule fallback', {
1880
- error: flowError,
1881
- flowName: args.name
1882
- });
1883
- // Try to create equivalent Business Rule instead
1884
- try {
1885
- fallbackBusinessRule = await this.createBusinessRuleFallback(args, flowDefinition);
1886
- result = {
1887
- success: true,
1888
- data: fallbackBusinessRule,
1889
- fallback_used: true,
1890
- original_error: flowError instanceof Error ? flowError.message : String(flowError)
1891
- };
1892
- usedFallback = true;
1893
- this.logger.info('Successfully created Business Rule fallback', {
1894
- businessRuleId: fallbackBusinessRule.sys_id,
1895
- originalFlowName: args.name
1896
- });
1897
- }
1898
- catch (fallbackError) {
1899
- this.logger.error('Both Flow Designer and Business Rule fallback failed', {
1900
- flowError,
1901
- fallbackError
1902
- });
1903
- throw new Error(`🚨 Flow deployment failed and fallback unsuccessful:
1904
-
1905
- 📍 **Errors:**
1906
- - Flow Designer Error: ${flowError instanceof Error ? flowError.message : String(flowError)}
1907
- - Business Rule Fallback Error: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}
1908
-
1909
- 🔧 **Update Set Troubleshooting:**
1910
- 1. Check current Update Set: snow_smart_update_set with action="track"
1911
- 2. Verify Update Set is active for tracking
1912
- 3. Use mock testing: snow_test_flow_with_mock instead
1913
- 4. Check flow exists: snow_get_by_sysid
1914
-
1915
- 💡 **Alternative Solutions:**
1916
- - Use snow_test_flow_with_mock for safe testing
1917
- - Verify flow creation with snow_get_by_sysid
1918
- - Check Update Set contains the flow artifact
1919
- - Create Business Rule manually if needed
1920
-
1921
- 📚 Please check your flow definition JSON format or use manual deployment.`);
1922
- }
1923
- }
1924
- const credentials = await this.oauth.loadCredentials();
1925
- const flowUrl = result.success && result.data
1926
- ? (usedFallback
1927
- ? `https://${credentials?.instance}/sys_script.do?sys_id=${result.data.sys_id}`
1928
- : `https://${credentials?.instance}/nav_to.do?uri=sys_hub_flow.do?sys_id=${result.data.sys_id}`)
1929
- : `https://${credentials?.instance}/flow-designer.do`;
1930
- const artifactSummary = deployedArtifacts.length > 0
1931
- ? `\n🔗 **Linked Artifacts Deployed:**\n${deployedArtifacts.map((a, i) => `${i + 1}. ${a.type}: ${a.name} (${a.sys_id})`).join('\n')}\n`
1932
- : '';
1933
- const activitySummary = flowDefinition.activities
1934
- ? `\n📊 **Flow Activities:**\n${flowDefinition.activities.map((a, i) => `${i + 1}. ${a.name} (${a.type})${a.artifact_reference ? ` - Uses: ${a.artifact_reference.name}` : ''}`).join('\n')}\n`
1935
- : '';
1936
- const successMessage = usedFallback
1937
- ? `🔄 **INTELLIGENT FALLBACK SUCCESSFUL!**
1938
-
1939
- ⚠️ Flow Designer deployment failed, but Snow-Flow automatically created a Business Rule that achieves the same result!
1940
-
1941
- 🛠️ **Business Rule Details:**
1942
- - Name: ${args.name}
1943
- - Type: 🔧 Business Rule (Fallback from Flow Designer)
1944
- - Table: ${args.table || 'sys_user'}
1945
- - When: ${this.getTriggerWhen(args.trigger_type)}
1946
- - Active: ${args.active !== false ? 'Yes' : 'No'}
1947
- - Original Error: ${result.original_error}
1948
-
1949
- ✨ **Why This Works Better:**
1950
- - ✅ More reliable than Flow Designer for simple automations
1951
- - ✅ Faster execution (server-side JavaScript)
1952
- - ✅ Better error handling and debugging
1953
- - ✅ Direct database access capabilities`
1954
- : `✅ Flow Designer flow deployed successfully!
1955
-
1956
- 🔄 **${flowType.charAt(0).toUpperCase() + flowType.slice(1)} Details:**
1957
- - Name: ${args.name}
1958
- - Flow Type: ${flowType === 'flow' ? '📋 Flow' : flowType === 'subflow' ? '🔄 Subflow' : '⚡ Action'}
1959
- - Composed: ${isComposedFlow ? '🧠 Yes - Intelligent Composed Flow' : '❌ No - Standard'}
1960
- ${flowType === 'flow' ? `- Trigger Type: ${args.trigger_type}
1961
- - Table: ${args.table || 'N/A'}` : ''}
1962
- ${flowType !== 'flow' ? `- Inputs: ${flowDefinition.inputs?.length || 0}
1963
- - Outputs: ${flowDefinition.outputs?.length || 0}` : ''}
1964
- - Category: ${args.category || 'automation'}
1965
- - Active: ${args.active !== false ? 'Yes' : 'No'}`;
1966
- const continuationMessage = usedFallback
1967
- ? `
1968
- 📦 **Update Set:**
1969
- - Name: ${updateSetName}
1970
- - ID: ${updateSetId}
1971
-
1972
- 🔗 **Direct Links:**
1973
- - Business Rule: ${flowUrl}
1974
- - Business Rules List: https://${credentials?.instance}/sys_script_list.do
1975
-
1976
- 📝 **Business Rule Components Created:**
1977
- 1. ✅ Trigger configured (${this.getTriggerWhen(args.trigger_type)})
1978
- 2. ✅ Condition logic applied
1979
- 3. ✅ Server-side script generated
1980
- 4. ✅ Error handling implemented
1981
- 5. ✅ Activation settings configured
1982
-
1983
- 📋 **Next Steps:**
1984
- 1. Test business rule execution by triggering the event
1985
- 2. Check logs in System Logs > Script Log Statements
1986
- 3. Modify the script if additional logic is needed
1987
- 4. Monitor performance and error handling
1988
-
1989
- 🔄 **Snow-Flow Intelligent Fallback:**
1990
- Snow-Flow automatically detected Flow Designer issues and created a functionally equivalent Business Rule. This is often more reliable and performant for simple automation tasks.`
1991
- : `
1992
- 📦 **Update Set:**
1993
- - Name: ${updateSetName}
1994
- - ID: ${updateSetId}
1995
- ${artifactSummary}${activitySummary}
1996
- 🔗 **Direct Links:**
1997
- - Flow Designer: ${flowUrl}
1998
- - Flow Designer Home: https://${credentials?.instance}/flow-designer.do?sysparm_nostack=true
1999
-
2000
- 📝 **Flow Components Created:**
2001
- 1. ✅ Trigger configured (${args.trigger_type})
2002
- 2. ✅ Condition logic applied
2003
- 3. ✅ Flow definition structured with ${flowDefinition.activities?.length || 0} activities
2004
- 4. ✅ ${linkedArtifacts.length} artifacts linked and deployed
2005
- 5. ✅ Activation settings configured
2006
-
2007
- ${isComposedFlow ? `
2008
- 🧠 **Intelligent Flow Features:**
2009
- - ✅ Natural language instruction processed
2010
- - ✅ Artifacts automatically discovered and linked
2011
- - ✅ Dependencies resolved and deployed
2012
- - ✅ Error handling configured
2013
- - ✅ Variables and connections mapped
2014
- ` : ''}
2015
-
2016
- 📋 **Next Steps:**
2017
- 1. Test flow execution with sample data
2018
- 2. Monitor flow performance and logs
2019
- 3. Review artifact connections
2020
- 4. Customize error handling if needed
2021
-
2022
- 💡 **Composed Flow Capabilities:**
2023
- - Automatic artifact orchestration
2024
- - Intelligent output-to-input mapping
2025
- - Multi-artifact dependency resolution
2026
- - Natural language configuration`;
2027
- // ENHANCED: Ensure artifact is tracked in Update Set
2028
- if (result.success && result.data) {
2029
- await this.ensureUpdateSetTracking({
2030
- sys_id: result.data.sys_id,
2031
- type: usedFallback ? 'Business Rule' : 'Flow',
2032
- name: args.name,
2033
- table: usedFallback ? 'sys_script' : 'sys_hub_flow'
2034
- });
2035
- }
2036
- return {
2037
- content: [
2038
- {
2039
- type: 'text',
2040
- text: successMessage + continuationMessage,
2041
- },
2042
- ],
2043
- };
1783
+ }
2044
1784
  }
2045
- catch (error) {
2046
- const enhancedError = `🚨 Flow Deployment Failed
2047
-
2048
- 📍 Error: ${error instanceof Error ? error.message : String(error)}
2049
-
2050
- 🔧 Troubleshooting Steps:
2051
- 1. Check authentication: snow_auth_diagnostics()
2052
- 2. Validate flow definition: snow_validate_flow_definition()
2053
- 3. Check Update Set: snow_update_set_current()
2054
- 4. Verify flow_designer role permissions
2055
-
2056
- 💡 Alternative Approaches:
2057
- • Use snow_create_flow with natural language (recommended)
2058
- • Test with snow_test_flow_with_mock() first
2059
- • Use snow_flow_wizard for step-by-step creation
2060
- • Try Business Rule fallback if flow creation fails
2061
-
2062
- 📚 Documentation: See CLAUDE.md for Flow Development Guidelines`;
2063
- throw new Error(enhancedError);
1785
+
1786
+ // Parse flow definition to inject deployed artifact references
1787
+ // Use the validated and corrected definition
1788
+ let flowDefinition = validatedDefinition;
1789
+ if (typeof flowDefinition === 'string') {
1790
+ flowDefinition = JSON.parse(flowDefinition);
2064
1791
  }
2065
- }
2066
- /**
2067
- * Deploy a linked artifact (script include, business rule, etc.)
2068
- */
2069
- async deployLinkedArtifact(artifact) {
2070
- this.logger.info('Deploying linked artifact', { type: artifact.type, name: artifact.name });
2071
- switch (artifact.type) {
2072
- case 'script_include':
2073
- return await this.deployScriptInclude(artifact);
2074
- case 'business_rule':
2075
- return await this.deployBusinessRule(artifact);
2076
- case 'table':
2077
- return await this.deployTable(artifact);
2078
- default:
2079
- throw new Error(`Unknown artifact type: ${artifact.type}`);
1792
+
1793
+ // Update flow activities with deployed artifact sys_ids
1794
+ if (flowDefinition.activities && deployedArtifacts.length > 0) {
1795
+ flowDefinition.activities = flowDefinition.activities.map((activity: any) => {
1796
+ if (activity.artifact_reference) {
1797
+ const deployed = deployedArtifacts.find(d =>
1798
+ d.originalId === activity.artifact_reference.sys_id ||
1799
+ d.name === activity.artifact_reference.name
1800
+ );
1801
+ if (deployed) {
1802
+ activity.artifact_sys_id = deployed.sys_id;
1803
+ activity.artifact_api_name = deployed.api_name;
1804
+ }
1805
+ }
1806
+ return activity;
1807
+ });
2080
1808
  }
2081
- }
2082
- /**
2083
- * Deploy a script include artifact
2084
- */
2085
- async deployScriptInclude(artifact) {
2086
- const scriptIncludeData = {
2087
- name: artifact.name,
2088
- api_name: artifact.api_name || artifact.name,
2089
- description: artifact.description || `Script include for ${artifact.purpose}`,
2090
- script: artifact.script || artifact.fallback_script,
2091
- active: true,
2092
- access: 'public'
1809
+
1810
+ // Create flow data based on flow type
1811
+ const flowData: any = {
1812
+ name: args.name,
1813
+ description: args.description,
1814
+ active: args.active !== false,
1815
+ flow_definition: JSON.stringify(flowDefinition),
1816
+ category: args.category || 'automation',
1817
+ // Additional fields for composed flows
1818
+ is_composed: isComposedFlow,
1819
+ linked_artifact_count: linkedArtifacts.length,
1820
+ artifact_references: deployedArtifacts.map(a => a.sys_id).join(',')
2093
1821
  };
2094
- const result = await this.client.createScriptInclude(scriptIncludeData);
2095
- if (!result.data?.sys_id) {
2096
- throw new Error(`Script Include deployment failed: No sys_id returned from ServiceNow. Result: ${JSON.stringify(result)}`);
1822
+
1823
+ // Configure based on flow type
1824
+ switch (flowType) {
1825
+ case 'flow':
1826
+ flowData.table = args.table || '';
1827
+ flowData.trigger_type = args.trigger_type;
1828
+ flowData.condition = args.condition || '';
1829
+ flowData.type = 'flow';
1830
+ break;
1831
+ case 'subflow':
1832
+ // Subflows don't have triggers, they're called by other flows
1833
+ flowData.type = 'subflow';
1834
+ flowData.inputs = flowDefinition.inputs || [];
1835
+ flowData.outputs = flowDefinition.outputs || [];
1836
+ break;
1837
+ case 'action':
1838
+ // Actions are reusable components
1839
+ flowData.type = 'action';
1840
+ flowData.action_type = args.action_type || 'custom';
1841
+ flowData.inputs = flowDefinition.inputs || [];
1842
+ flowData.outputs = flowDefinition.outputs || [];
1843
+ break;
2097
1844
  }
2098
- return {
2099
- originalId: artifact.sys_id,
1845
+
1846
+ // Deploy to ServiceNow using appropriate API based on flow type
1847
+ let result;
1848
+ let usedFallback = false;
1849
+ let fallbackBusinessRule = null;
1850
+
1851
+ try {
1852
+ // Real ServiceNow Flow deployment using proper API calls
1853
+ switch (flowType) {
1854
+ case 'flow':
1855
+ // Create workflow record in ServiceNow
1856
+ result = await (this.client as any).createRecord('wf_workflow', {
1857
+ name: flowData.name || `flow_${Date.now()}`,
1858
+ description: flowData.description || 'Created by Snow-Flow',
1859
+ table: flowData.table || 'incident',
1860
+ active: flowData.active !== false,
1861
+ condition: flowData.condition || '',
1862
+ script: flowData.script || '// Flow logic here',
1863
+ order: flowData.order || 100
1864
+ });
1865
+ break;
1866
+ case 'subflow':
1867
+ // Create subflow as a workflow activity
1868
+ result = await (this.client as any).createRecord('wf_workflow', {
1869
+ name: flowData.name || `subflow_${Date.now()}`,
1870
+ description: `${flowData.description || 'Subflow created by Snow-Flow'} [SUBFLOW]`,
1871
+ table: flowData.table || 'incident',
1872
+ active: flowData.active !== false,
1873
+ condition: flowData.condition || '',
1874
+ script: flowData.script || '// Subflow logic here',
1875
+ order: flowData.order || 200
1876
+ });
1877
+ break;
1878
+ case 'action':
1879
+ // Create workflow activity/action
1880
+ if (!flowData.workflow_id) {
1881
+ throw new Error('workflow_id is required for flow actions');
1882
+ }
1883
+ result = await (this.client as any).createRecord('wf_activity', {
1884
+ workflow: flowData.workflow_id,
1885
+ name: flowData.name || `action_${Date.now()}`,
1886
+ script: flowData.script || '// Action script here',
1887
+ condition: flowData.condition || '',
1888
+ order: flowData.order || 100,
1889
+ active: flowData.active !== false
1890
+ });
1891
+ break;
1892
+ default:
1893
+ throw new Error(`Unknown flow type: ${flowType}. Supported types: flow, subflow, action`);
1894
+ }
1895
+ } catch (flowError) {
1896
+ this.logger.warn('Flow Designer deployment failed, attempting Business Rule fallback', {
1897
+ error: flowError,
1898
+ flowName: args.name
1899
+ });
1900
+
1901
+ // Try to create equivalent Business Rule instead
1902
+ try {
1903
+ fallbackBusinessRule = await this.createBusinessRuleFallback(args, flowDefinition);
1904
+ result = {
1905
+ success: true,
1906
+ data: fallbackBusinessRule,
1907
+ fallback_used: true,
1908
+ original_error: flowError instanceof Error ? flowError.message : String(flowError)
1909
+ };
1910
+ usedFallback = true;
1911
+
1912
+ this.logger.info('Successfully created Business Rule fallback', {
1913
+ businessRuleId: fallbackBusinessRule.sys_id,
1914
+ originalFlowName: args.name
1915
+ });
1916
+
1917
+ } catch (fallbackError) {
1918
+ this.logger.error('Both Flow Designer and Business Rule fallback failed', {
1919
+ flowError,
1920
+ fallbackError
1921
+ });
1922
+ throw new Error(
1923
+ `🚨 Flow deployment failed and fallback unsuccessful:
1924
+
1925
+ 📍 **Errors:**
1926
+ - Flow Designer Error: ${flowError instanceof Error ? flowError.message : String(flowError)}
1927
+ - Business Rule Fallback Error: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}
1928
+
1929
+ 🔧 **Update Set Troubleshooting:**
1930
+ 1. Check current Update Set: snow_smart_update_set with action="track"
1931
+ 2. Verify Update Set is active for tracking
1932
+ 3. Use mock testing: snow_test_flow_with_mock instead
1933
+ 4. Check flow exists: snow_get_by_sysid
1934
+
1935
+ 💡 **Alternative Solutions:**
1936
+ - Use snow_test_flow_with_mock for safe testing
1937
+ - Verify flow creation with snow_get_by_sysid
1938
+ - Check Update Set contains the flow artifact
1939
+ - Create Business Rule manually if needed
1940
+
1941
+ 📚 Please check your flow definition JSON format or use manual deployment.`
1942
+ );
1943
+ }
1944
+ }
1945
+
1946
+ const credentials = await this.oauth.loadCredentials();
1947
+ const flowUrl = result.success && result.data
1948
+ ? (usedFallback
1949
+ ? `https://${credentials?.instance}/sys_script.do?sys_id=${result.data.sys_id}`
1950
+ : `https://${credentials?.instance}/nav_to.do?uri=sys_hub_flow.do?sys_id=${result.data.sys_id}`)
1951
+ : `https://${credentials?.instance}/flow-designer.do`;
1952
+
1953
+ const artifactSummary = deployedArtifacts.length > 0
1954
+ ? `\n🔗 **Linked Artifacts Deployed:**\n${deployedArtifacts.map((a, i) =>
1955
+ `${i + 1}. ${a.type}: ${a.name} (${a.sys_id})`
1956
+ ).join('\n')}\n`
1957
+ : '';
1958
+
1959
+ const activitySummary = flowDefinition.activities
1960
+ ? `\n📊 **Flow Activities:**\n${flowDefinition.activities.map((a: any, i: number) =>
1961
+ `${i + 1}. ${a.name} (${a.type})${a.artifact_reference ? ` - Uses: ${a.artifact_reference.name}` : ''}`
1962
+ ).join('\n')}\n`
1963
+ : '';
1964
+
1965
+ const successMessage = usedFallback
1966
+ ? `🔄 **INTELLIGENT FALLBACK SUCCESSFUL!**
1967
+
1968
+ ⚠️ Flow Designer deployment failed, but Snow-Flow automatically created a Business Rule that achieves the same result!
1969
+
1970
+ 🛠️ **Business Rule Details:**
1971
+ - Name: ${args.name}
1972
+ - Type: 🔧 Business Rule (Fallback from Flow Designer)
1973
+ - Table: ${args.table || 'sys_user'}
1974
+ - When: ${this.getTriggerWhen(args.trigger_type)}
1975
+ - Active: ${args.active !== false ? 'Yes' : 'No'}
1976
+ - Original Error: ${result.original_error}
1977
+
1978
+ ✨ **Why This Works Better:**
1979
+ - ✅ More reliable than Flow Designer for simple automations
1980
+ - ✅ Faster execution (server-side JavaScript)
1981
+ - ✅ Better error handling and debugging
1982
+ - ✅ Direct database access capabilities`
1983
+ : `✅ Flow Designer flow deployed successfully!
1984
+
1985
+ 🔄 **${flowType.charAt(0).toUpperCase() + flowType.slice(1)} Details:**
1986
+ - Name: ${args.name}
1987
+ - Flow Type: ${flowType === 'flow' ? '📋 Flow' : flowType === 'subflow' ? '🔄 Subflow' : '⚡ Action'}
1988
+ - Composed: ${isComposedFlow ? '🧠 Yes - Intelligent Composed Flow' : '❌ No - Standard'}
1989
+ ${flowType === 'flow' ? `- Trigger Type: ${args.trigger_type}
1990
+ - Table: ${args.table || 'N/A'}` : ''}
1991
+ ${flowType !== 'flow' ? `- Inputs: ${flowDefinition.inputs?.length || 0}
1992
+ - Outputs: ${flowDefinition.outputs?.length || 0}` : ''}
1993
+ - Category: ${args.category || 'automation'}
1994
+ - Active: ${args.active !== false ? 'Yes' : 'No'}`;
1995
+
1996
+ const continuationMessage = usedFallback
1997
+ ? `
1998
+ 📦 **Update Set:**
1999
+ - Name: ${updateSetName}
2000
+ - ID: ${updateSetId}
2001
+
2002
+ 🔗 **Direct Links:**
2003
+ - Business Rule: ${flowUrl}
2004
+ - Business Rules List: https://${credentials?.instance}/sys_script_list.do
2005
+
2006
+ 📝 **Business Rule Components Created:**
2007
+ 1. ✅ Trigger configured (${this.getTriggerWhen(args.trigger_type)})
2008
+ 2. ✅ Condition logic applied
2009
+ 3. ✅ Server-side script generated
2010
+ 4. ✅ Error handling implemented
2011
+ 5. ✅ Activation settings configured
2012
+
2013
+ 📋 **Next Steps:**
2014
+ 1. Test business rule execution by triggering the event
2015
+ 2. Check logs in System Logs > Script Log Statements
2016
+ 3. Modify the script if additional logic is needed
2017
+ 4. Monitor performance and error handling
2018
+
2019
+ 🔄 **Snow-Flow Intelligent Fallback:**
2020
+ Snow-Flow automatically detected Flow Designer issues and created a functionally equivalent Business Rule. This is often more reliable and performant for simple automation tasks.`
2021
+ : `
2022
+ 📦 **Update Set:**
2023
+ - Name: ${updateSetName}
2024
+ - ID: ${updateSetId}
2025
+ ${artifactSummary}${activitySummary}
2026
+ 🔗 **Direct Links:**
2027
+ - Flow Designer: ${flowUrl}
2028
+ - Flow Designer Home: https://${credentials?.instance}/flow-designer.do?sysparm_nostack=true
2029
+
2030
+ 📝 **Flow Components Created:**
2031
+ 1. ✅ Trigger configured (${args.trigger_type})
2032
+ 2. ✅ Condition logic applied
2033
+ 3. ✅ Flow definition structured with ${flowDefinition.activities?.length || 0} activities
2034
+ 4. ✅ ${linkedArtifacts.length} artifacts linked and deployed
2035
+ 5. ✅ Activation settings configured
2036
+
2037
+ ${isComposedFlow ? `
2038
+ 🧠 **Intelligent Flow Features:**
2039
+ - ✅ Natural language instruction processed
2040
+ - ✅ Artifacts automatically discovered and linked
2041
+ - ✅ Dependencies resolved and deployed
2042
+ - ✅ Error handling configured
2043
+ - ✅ Variables and connections mapped
2044
+ ` : ''}
2045
+
2046
+ 📋 **Next Steps:**
2047
+ 1. Test flow execution with sample data
2048
+ 2. Monitor flow performance and logs
2049
+ 3. Review artifact connections
2050
+ 4. Customize error handling if needed
2051
+
2052
+ 💡 **Composed Flow Capabilities:**
2053
+ - Automatic artifact orchestration
2054
+ - Intelligent output-to-input mapping
2055
+ - Multi-artifact dependency resolution
2056
+ - Natural language configuration`;
2057
+
2058
+ // ENHANCED: Ensure artifact is tracked in Update Set
2059
+ if (result.success && result.data) {
2060
+ await this.ensureUpdateSetTracking({
2100
2061
  sys_id: result.data.sys_id,
2101
- name: artifact.name,
2102
- api_name: scriptIncludeData.api_name,
2103
- type: 'script_include',
2104
- success: result.success
2062
+ type: usedFallback ? 'Business Rule' : 'Flow',
2063
+ name: args.name,
2064
+ table: usedFallback ? 'sys_script' : 'sys_hub_flow'
2065
+ });
2066
+ }
2067
+
2068
+ return {
2069
+ content: [
2070
+ {
2071
+ type: 'text',
2072
+ text: successMessage + continuationMessage,
2073
+ },
2074
+ ],
2105
2075
  };
2076
+ } catch (error) {
2077
+ const enhancedError = `🚨 Flow Deployment Failed
2078
+
2079
+ 📍 Error: ${error instanceof Error ? error.message : String(error)}
2080
+
2081
+ 🔧 Troubleshooting Steps:
2082
+ 1. Check authentication: snow_auth_diagnostics()
2083
+ 2. Validate flow definition: snow_validate_flow_definition()
2084
+ 3. Check Update Set: snow_update_set_current()
2085
+ 4. Verify flow_designer role permissions
2086
+
2087
+ 💡 Alternative Approaches:
2088
+ • Use snow_create_flow with natural language (recommended)
2089
+ • Test with snow_test_flow_with_mock() first
2090
+ • Use snow_flow_wizard for step-by-step creation
2091
+ • Try Business Rule fallback if flow creation fails
2092
+
2093
+ 📚 Documentation: See CLAUDE.md for Flow Development Guidelines`;
2094
+ throw new Error(enhancedError);
2095
+ }
2096
+ } */
2097
+ /**
2098
+ * Deploy a linked artifact (script include, business rule, etc.) - DEPRECATED
2099
+ */
2100
+ /* private async deployLinkedArtifact(artifact: any): Promise<any> {
2101
+ this.logger.info('Deploying linked artifact', { type: artifact.type, name: artifact.name });
2102
+
2103
+ switch (artifact.type) {
2104
+ case 'script_include':
2105
+ throw new Error('Script includes via flow deployment are deprecated. Use direct artifact creation instead.');
2106
+
2107
+ case 'business_rule':
2108
+ return await this.deployBusinessRule(artifact);
2109
+
2110
+ case 'table':
2111
+ return await this.deployTable(artifact);
2112
+
2113
+ default:
2114
+ throw new Error(`Unknown artifact type: ${artifact.type}`);
2115
+ }
2116
+ } */
2117
+ /**
2118
+ * Deploy a script include artifact - DEPRECATED
2119
+ */
2120
+ /* private async deployScriptInclude(artifact: any): Promise<any> {
2121
+ const scriptIncludeData = {
2122
+ name: artifact.name,
2123
+ api_name: artifact.api_name || artifact.name,
2124
+ description: artifact.description || `Script include for ${artifact.purpose}`,
2125
+ script: artifact.script || artifact.fallback_script,
2126
+ active: true,
2127
+ access: 'public'
2128
+ };
2129
+
2130
+ const result = await this.client.createScriptInclude(scriptIncludeData);
2131
+
2132
+ if (!result.data?.sys_id) {
2133
+ throw new Error(`Script Include deployment failed: No sys_id returned from ServiceNow. Result: ${JSON.stringify(result)}`);
2134
+ }
2135
+
2136
+ return {
2137
+ originalId: artifact.sys_id,
2138
+ sys_id: result.data.sys_id,
2139
+ name: artifact.name,
2140
+ api_name: scriptIncludeData.api_name,
2141
+ type: 'script_include',
2142
+ success: result.success
2143
+ };
2106
2144
  }
2145
+
2107
2146
  /**
2108
2147
  * Deploy a business rule artifact
2109
2148
  */
@@ -2627,7 +2666,7 @@ ${hasErrors ? '❌ Validation failed - fix errors before deployment' : '✅ Vali
2627
2666
  let rollbackResult;
2628
2667
  try {
2629
2668
  // Set update set to ignore state (ServiceNow's way of "rolling back")
2630
- rollbackResult = await this.client.update(`sys_update_set/${update_set_id}`, {
2669
+ rollbackResult = await this.client.updateRecord(`sys_update_set/${update_set_id}`, {
2631
2670
  state: 'ignore',
2632
2671
  description: `${updateSet.description || ''} - ROLLED BACK: ${reason}`
2633
2672
  });
@@ -3067,12 +3106,12 @@ ${deploymentList || 'No recent deployments found in the last 7 days'}
3067
3106
  if (existingArtifact) {
3068
3107
  // Update existing artifact
3069
3108
  const { sys_id, ...updateData } = artifact;
3070
- result = await this.client.update(`${tableName}/${sys_id}`, updateData);
3109
+ result = await this.client.updateRecord(`${tableName}/${sys_id}`, updateData);
3071
3110
  action = 'updated';
3072
3111
  }
3073
3112
  else {
3074
3113
  // Create new artifact
3075
- result = await this.client.create(tableName, artifact);
3114
+ result = await this.client.createRecord(tableName, artifact);
3076
3115
  action = 'created';
3077
3116
  }
3078
3117
  if (!result?.result) {
@@ -3835,25 +3874,39 @@ This will use your .env credentials to start the OAuth flow and generate access
3835
3874
  template: '<div>Test widget - safe to delete</div>',
3836
3875
  description: 'Temporary test widget created by Snow-Flow MCP diagnostics'
3837
3876
  };
3838
- const createResult = await this.client.create('sp_widget', testWidget);
3839
- if (createResult?.result?.sys_id) {
3877
+ const createResult = await this.client.createRecord('sp_widget', testWidget);
3878
+ if (createResult?.success && createResult?.data?.sys_id) {
3840
3879
  // Immediately delete the test widget
3841
3880
  try {
3842
- await this.client.delete(`sp_widget/${createResult.result.sys_id}`);
3881
+ await this.client.deleteRecord('sp_widget', createResult.data.sys_id);
3843
3882
  realApiTests.writePermissions = {
3844
3883
  status: '✅ Full Access',
3845
3884
  description: 'Can create and delete artifacts - full deployment capability',
3846
- details: `Successfully created and cleaned up test widget ${createResult.result.sys_id}`
3885
+ details: `Successfully created and cleaned up test widget ${createResult.data.sys_id}`
3847
3886
  };
3848
3887
  }
3849
3888
  catch (deleteError) {
3850
3889
  realApiTests.writePermissions = {
3851
3890
  status: '⚠️ Partial',
3852
3891
  description: 'Can create but cannot delete - cleanup may be needed',
3853
- details: `Created test widget ${createResult.result.sys_id} but failed to delete: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`
3892
+ details: `Created test widget ${createResult.data.sys_id} but failed to delete: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`
3854
3893
  };
3855
3894
  }
3856
3895
  }
3896
+ else {
3897
+ // Log what we got for debugging
3898
+ this.logger.warn('Create succeeded but unexpected response structure:', {
3899
+ success: createResult?.success,
3900
+ hasData: !!createResult?.data,
3901
+ hasSysId: !!createResult?.data?.sys_id,
3902
+ dataKeys: createResult?.data ? Object.keys(createResult.data) : []
3903
+ });
3904
+ realApiTests.writePermissions = {
3905
+ status: '⚠️ Partial',
3906
+ description: 'Created widget but response structure unexpected',
3907
+ details: `Response structure: ${JSON.stringify(createResult?.data || {})}`
3908
+ };
3909
+ }
3857
3910
  }
3858
3911
  catch (writeError) {
3859
3912
  realApiTests.writePermissions = {
@@ -5525,13 +5578,13 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
5525
5578
  let result;
5526
5579
  switch (artifact.type) {
5527
5580
  case 'flow':
5528
- result = await this.deployFlow(artifact.create);
5581
+ throw new Error('Flow deployment is deprecated. Flows, workflows, and subflows are no longer supported. Use widgets or applications instead.');
5529
5582
  break;
5530
5583
  case 'widget':
5531
5584
  result = await this.deployWidget(artifact.create);
5532
5585
  break;
5533
5586
  case 'script_include':
5534
- result = await this.deployScriptInclude(artifact.create);
5587
+ result = await this.client.createScriptInclude(artifact.create);
5535
5588
  break;
5536
5589
  case 'business_rule':
5537
5590
  result = await this.deployBusinessRule(artifact.create);
@@ -5847,12 +5900,7 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
5847
5900
  };
5848
5901
  }
5849
5902
  case 'flow':
5850
- const flowResult = await this.deployFlow(config);
5851
- return {
5852
- success: flowResult.content[0].text.includes('✅'),
5853
- sys_id: flowResult.content[0].text.match(/sys_id: ([a-f0-9]+)/)?.[1],
5854
- message: 'Flow deployed'
5855
- };
5903
+ throw new Error('Flow deployment is deprecated. Use widgets or applications instead.');
5856
5904
  case 'script':
5857
5905
  case 'script_include':
5858
5906
  const scriptResult = await this.createRecordWithRetry('sys_script_include', config);
@@ -5947,7 +5995,7 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
5947
5995
  async rollbackArtifact(artifact) {
5948
5996
  const tableMap = {
5949
5997
  'widget': 'sp_widget',
5950
- 'flow': 'sys_hub_flow',
5998
+ // 'flow': 'sys_hub_flow', // REMOVED - flows deprecated
5951
5999
  'script': 'sys_script_include',
5952
6000
  'script_include': 'sys_script_include',
5953
6001
  'business_rule': 'sys_script',
@@ -7582,11 +7630,11 @@ Use individual deployment tools like \`snow_deploy_${args.type}\` with manual co
7582
7630
  getTableForArtifactType(artifactType) {
7583
7631
  const ARTIFACT_TABLES = {
7584
7632
  'widget': 'sp_widget',
7585
- 'flow': 'sys_hub_flow',
7633
+ // 'flow': 'sys_hub_flow', // REMOVED - flows deprecated
7586
7634
  'script': 'sys_script_include',
7587
7635
  'script_include': 'sys_script_include',
7588
7636
  'business_rule': 'sys_script',
7589
- 'workflow': 'wf_workflow',
7637
+ // 'workflow': 'wf_workflow', // REMOVED - workflows deprecated
7590
7638
  'application': 'sys_app',
7591
7639
  'ui_action': 'sys_ui_action',
7592
7640
  'ui_page': 'sys_ui_page',