snow-flow 1.1.60 → 1.1.61
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.
- package/dist/mcp/servicenow-deployment-mcp.js +243 -11
- package/dist/mcp/servicenow-deployment-mcp.js.map +1 -1
- package/dist/mcp/servicenow-flow-composer-mcp.js +60 -11
- package/dist/mcp/servicenow-flow-composer-mcp.js.map +1 -1
- package/dist/mcp/servicenow-intelligent-mcp.js +14 -1
- package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -1
- package/dist/mcp/servicenow-operations-mcp.js +19 -1
- package/dist/mcp/servicenow-operations-mcp.js.map +1 -1
- package/dist/utils/servicenow-client.d.ts +15 -0
- package/dist/utils/servicenow-client.d.ts.map +1 -1
- package/dist/utils/servicenow-client.js +182 -15
- package/dist/utils/servicenow-client.js.map +1 -1
- package/dist/version.d.ts +2 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +11 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -472,7 +472,19 @@ class ServiceNowDeploymentMCP {
|
|
|
472
472
|
updateSetName: currentUpdateSet.data.name
|
|
473
473
|
};
|
|
474
474
|
}
|
|
475
|
-
// No current Update Set - create one automatically
|
|
475
|
+
// No current Update Set - show guidance and create one automatically
|
|
476
|
+
console.warn(`
|
|
477
|
+
⚠️ No Active Update Set Detected
|
|
478
|
+
|
|
479
|
+
🔧 Auto-creating Update Set for deployment safety...
|
|
480
|
+
|
|
481
|
+
💡 Best Practice: Always start with:
|
|
482
|
+
1. snow_update_set_create()
|
|
483
|
+
2. snow_update_set_switch()
|
|
484
|
+
3. Deploy your artifacts
|
|
485
|
+
4. snow_update_set_add_artifact() (automatic)
|
|
486
|
+
5. snow_update_set_complete()
|
|
487
|
+
`);
|
|
476
488
|
const updateSetName = `Auto: ${artifactType} - ${artifactName} - ${new Date().toISOString().split('T')[0]}`;
|
|
477
489
|
const createResult = await this.client.createUpdateSet({
|
|
478
490
|
name: updateSetName,
|
|
@@ -493,6 +505,69 @@ class ServiceNowDeploymentMCP {
|
|
|
493
505
|
updateSetName: updateSetName
|
|
494
506
|
};
|
|
495
507
|
}
|
|
508
|
+
/**
|
|
509
|
+
* Ensure artifact is tracked in current Update Set
|
|
510
|
+
*/
|
|
511
|
+
async ensureUpdateSetTracking(artifact) {
|
|
512
|
+
try {
|
|
513
|
+
// Check if we have an active update set
|
|
514
|
+
const currentSet = await this.client.getCurrentUpdateSet();
|
|
515
|
+
if (!currentSet || !currentSet.data || !currentSet.data.sys_id) {
|
|
516
|
+
console.warn('⚠️ No active Update Set - creating one automatically');
|
|
517
|
+
const newSet = await this.client.createUpdateSet({
|
|
518
|
+
name: `AUTO-${new Date().toISOString().split('T')[0]}-${Date.now().toString().slice(-6)}`,
|
|
519
|
+
description: 'Automatically created for artifact deployment',
|
|
520
|
+
state: 'in_progress'
|
|
521
|
+
});
|
|
522
|
+
if (newSet.success && newSet.data) {
|
|
523
|
+
await this.client.setCurrentUpdateSet(newSet.data.sys_id);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
// Track the artifact by creating a sys_update_xml record
|
|
527
|
+
if (artifact.sys_id && artifact.type && artifact.name) {
|
|
528
|
+
const updateXmlData = {
|
|
529
|
+
name: artifact.name,
|
|
530
|
+
type: artifact.type,
|
|
531
|
+
target_name: artifact.name,
|
|
532
|
+
action: 'INSERT_OR_UPDATE',
|
|
533
|
+
table: artifact.table || this.getTableForType(artifact.type),
|
|
534
|
+
target_sys_id: artifact.sys_id,
|
|
535
|
+
category: 'customer',
|
|
536
|
+
update_set: currentSet?.data?.sys_id
|
|
537
|
+
};
|
|
538
|
+
// Create the sys_update_xml record to track the artifact
|
|
539
|
+
const trackingResult = await this.client.createRecord('sys_update_xml', updateXmlData);
|
|
540
|
+
if (trackingResult.success) {
|
|
541
|
+
console.log(`✅ Artifact tracked in Update Set: ${artifact.name} (${artifact.sys_id})`);
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
console.warn(`⚠️ Failed to track artifact in Update Set: ${trackingResult.error}`);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
catch (error) {
|
|
549
|
+
console.error('Failed to track artifact in Update Set:', error);
|
|
550
|
+
// Don't fail the deployment, just warn
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Get ServiceNow table name for artifact type
|
|
555
|
+
*/
|
|
556
|
+
getTableForType(type) {
|
|
557
|
+
const tableMap = {
|
|
558
|
+
'flow': 'sys_hub_flow',
|
|
559
|
+
'widget': 'sp_widget',
|
|
560
|
+
'script': 'sys_script_include',
|
|
561
|
+
'business_rule': 'sys_script',
|
|
562
|
+
'workflow': 'wf_workflow',
|
|
563
|
+
'application': 'sys_app',
|
|
564
|
+
'ui_action': 'sys_ui_action',
|
|
565
|
+
'ui_page': 'sys_ui_page',
|
|
566
|
+
'script_include': 'sys_script_include',
|
|
567
|
+
'processor': 'sys_processor'
|
|
568
|
+
};
|
|
569
|
+
return tableMap[type] || 'sys_metadata';
|
|
570
|
+
}
|
|
496
571
|
async deployWidget(args) {
|
|
497
572
|
try {
|
|
498
573
|
// Check authentication first
|
|
@@ -809,6 +884,13 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
809
884
|
// Track the artifact for consistency validation
|
|
810
885
|
const trackedArtifact = artifact_tracker_js_1.artifactTracker.trackArtifact(result.data.sys_id, 'sp_widget', args.name, 'widget', 'create');
|
|
811
886
|
trackedArtifact.updateSetId = updateSetId;
|
|
887
|
+
// ENHANCED: Ensure artifact is tracked in Update Set
|
|
888
|
+
await this.ensureUpdateSetTracking({
|
|
889
|
+
sys_id: result.data.sys_id,
|
|
890
|
+
type: 'Widget',
|
|
891
|
+
name: args.name,
|
|
892
|
+
table: 'sp_widget'
|
|
893
|
+
});
|
|
812
894
|
// Record successful deployment operation
|
|
813
895
|
artifact_tracker_js_1.artifactTracker.recordOperation(result.data.sys_id, 'create', true, `Widget deployed successfully to table sp_widget`);
|
|
814
896
|
// Validate the artifact was actually created (with retry for indexing delay)
|
|
@@ -884,11 +966,43 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
884
966
|
else {
|
|
885
967
|
// Record failed deployment
|
|
886
968
|
artifact_tracker_js_1.artifactTracker.recordOperation('unknown', 'create', false, `Widget deployment failed: ${result.error}`, result.error);
|
|
887
|
-
|
|
969
|
+
const enhancedError = `🚨 Widget Deployment Failed
|
|
970
|
+
|
|
971
|
+
📍 Error: ${result.error || 'Unknown deployment error'}
|
|
972
|
+
|
|
973
|
+
🔧 Troubleshooting Steps:
|
|
974
|
+
1. Check authentication: snow_auth_diagnostics()
|
|
975
|
+
2. Verify Update Set: snow_update_set_current()
|
|
976
|
+
3. Check permissions: Ensure user has sp_admin role
|
|
977
|
+
4. Try widget preview: snow_preview_widget()
|
|
978
|
+
|
|
979
|
+
💡 Alternative Approaches:
|
|
980
|
+
• Use snow_deploy_widget with smaller components first
|
|
981
|
+
• Test with snow_widget_test() before deployment
|
|
982
|
+
• Check dependencies with check_dependencies: true
|
|
983
|
+
|
|
984
|
+
📚 Documentation: See CLAUDE.md for Widget Deployment Guidelines`;
|
|
985
|
+
throw new Error(enhancedError);
|
|
888
986
|
}
|
|
889
987
|
}
|
|
890
988
|
catch (error) {
|
|
891
|
-
|
|
989
|
+
const enhancedError = `🚨 Widget Deployment System Error
|
|
990
|
+
|
|
991
|
+
📍 Error: ${error instanceof Error ? error.message : String(error)}
|
|
992
|
+
|
|
993
|
+
🔧 Troubleshooting Steps:
|
|
994
|
+
1. Check authentication: snow_auth_diagnostics()
|
|
995
|
+
2. Verify ServiceNow connectivity
|
|
996
|
+
3. Check Update Set status: snow_update_set_current()
|
|
997
|
+
4. Validate widget structure before deployment
|
|
998
|
+
|
|
999
|
+
💡 Alternative Approaches:
|
|
1000
|
+
• Use snow_preview_widget() to test first
|
|
1001
|
+
• Deploy components separately
|
|
1002
|
+
• Use snow_widget_test() for validation
|
|
1003
|
+
|
|
1004
|
+
📚 Documentation: See CLAUDE.md for Widget Deployment Guidelines`;
|
|
1005
|
+
throw new Error(enhancedError);
|
|
892
1006
|
}
|
|
893
1007
|
}
|
|
894
1008
|
async deployFlow(args) {
|
|
@@ -1066,10 +1180,25 @@ Use \`snow_deployment_debug\` for more information about this session.`,
|
|
|
1066
1180
|
flowError,
|
|
1067
1181
|
fallbackError
|
|
1068
1182
|
});
|
|
1069
|
-
throw new Error(
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1183
|
+
throw new Error(`🚨 Flow deployment failed and fallback unsuccessful:
|
|
1184
|
+
|
|
1185
|
+
📍 **Errors:**
|
|
1186
|
+
- Flow Designer Error: ${flowError instanceof Error ? flowError.message : String(flowError)}
|
|
1187
|
+
- Business Rule Fallback Error: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}
|
|
1188
|
+
|
|
1189
|
+
🔧 **Update Set Troubleshooting:**
|
|
1190
|
+
1. Check current Update Set: snow_smart_update_set with action="track"
|
|
1191
|
+
2. Verify Update Set is active for tracking
|
|
1192
|
+
3. Use mock testing: snow_test_flow_with_mock instead
|
|
1193
|
+
4. Check flow exists: snow_get_by_sysid
|
|
1194
|
+
|
|
1195
|
+
💡 **Alternative Solutions:**
|
|
1196
|
+
- Use snow_test_flow_with_mock for safe testing
|
|
1197
|
+
- Verify flow creation with snow_get_by_sysid
|
|
1198
|
+
- Check Update Set contains the flow artifact
|
|
1199
|
+
- Create Business Rule manually if needed
|
|
1200
|
+
|
|
1201
|
+
📚 Please check your flow definition JSON format or use manual deployment.`);
|
|
1073
1202
|
}
|
|
1074
1203
|
}
|
|
1075
1204
|
const credentials = await this.oauth.loadCredentials();
|
|
@@ -1175,6 +1304,15 @@ ${isComposedFlow ? `
|
|
|
1175
1304
|
- Intelligent output-to-input mapping
|
|
1176
1305
|
- Multi-artifact dependency resolution
|
|
1177
1306
|
- Natural language configuration`;
|
|
1307
|
+
// ENHANCED: Ensure artifact is tracked in Update Set
|
|
1308
|
+
if (result.success && result.data) {
|
|
1309
|
+
await this.ensureUpdateSetTracking({
|
|
1310
|
+
sys_id: result.data.sys_id,
|
|
1311
|
+
type: usedFallback ? 'Business Rule' : 'Flow',
|
|
1312
|
+
name: args.name,
|
|
1313
|
+
table: usedFallback ? 'sys_script' : 'sys_hub_flow'
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1178
1316
|
return {
|
|
1179
1317
|
content: [
|
|
1180
1318
|
{
|
|
@@ -1185,7 +1323,24 @@ ${isComposedFlow ? `
|
|
|
1185
1323
|
};
|
|
1186
1324
|
}
|
|
1187
1325
|
catch (error) {
|
|
1188
|
-
|
|
1326
|
+
const enhancedError = `🚨 Flow Deployment Failed
|
|
1327
|
+
|
|
1328
|
+
📍 Error: ${error instanceof Error ? error.message : String(error)}
|
|
1329
|
+
|
|
1330
|
+
🔧 Troubleshooting Steps:
|
|
1331
|
+
1. Check authentication: snow_auth_diagnostics()
|
|
1332
|
+
2. Validate flow definition: snow_validate_flow_definition()
|
|
1333
|
+
3. Check Update Set: snow_update_set_current()
|
|
1334
|
+
4. Verify flow_designer role permissions
|
|
1335
|
+
|
|
1336
|
+
💡 Alternative Approaches:
|
|
1337
|
+
• Use snow_create_flow with natural language (recommended)
|
|
1338
|
+
• Test with snow_test_flow_with_mock() first
|
|
1339
|
+
• Use snow_flow_wizard for step-by-step creation
|
|
1340
|
+
• Try Business Rule fallback if flow creation fails
|
|
1341
|
+
|
|
1342
|
+
📚 Documentation: See CLAUDE.md for Flow Development Guidelines`;
|
|
1343
|
+
throw new Error(enhancedError);
|
|
1189
1344
|
}
|
|
1190
1345
|
}
|
|
1191
1346
|
/**
|
|
@@ -1329,6 +1484,15 @@ ${isComposedFlow ? `
|
|
|
1329
1484
|
if (!deploymentResult.success) {
|
|
1330
1485
|
throw new Error(deploymentResult.message || 'Failed to deploy application');
|
|
1331
1486
|
}
|
|
1487
|
+
// ENHANCED: Ensure artifact is tracked in Update Set
|
|
1488
|
+
if (deploymentResult.artifactId) {
|
|
1489
|
+
await this.ensureUpdateSetTracking({
|
|
1490
|
+
sys_id: deploymentResult.artifactId,
|
|
1491
|
+
type: 'Application',
|
|
1492
|
+
name: args.name,
|
|
1493
|
+
table: 'sys_app'
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1332
1496
|
const credentials = await this.oauth.loadCredentials();
|
|
1333
1497
|
const appUrl = `https://${credentials?.instance}/nav_to.do?uri=sys_app.do?sys_id=${deploymentResult.artifactId}`;
|
|
1334
1498
|
return {
|
|
@@ -2560,11 +2724,79 @@ Use \`snow_preview_widget\` to see a detailed preview of the widget rendering.`,
|
|
|
2560
2724
|
workingDefinition = definition.flow_definition;
|
|
2561
2725
|
corrections.push('✅ Processing nested flow_definition structure');
|
|
2562
2726
|
}
|
|
2563
|
-
//
|
|
2727
|
+
// Check for empty flow definition first
|
|
2564
2728
|
if (!workingDefinition.activities && !workingDefinition.steps && !workingDefinition.actions) {
|
|
2565
|
-
|
|
2729
|
+
return {
|
|
2730
|
+
content: [
|
|
2731
|
+
{
|
|
2732
|
+
type: 'text',
|
|
2733
|
+
text: `🚨 Flow Definition Error: No activities found
|
|
2734
|
+
|
|
2735
|
+
📍 Common Causes:
|
|
2736
|
+
• Used snow_deploy_flow with manual JSON (often fails)
|
|
2737
|
+
• Incorrect flow_definition format
|
|
2738
|
+
• Activities not properly mapped from actions/steps
|
|
2739
|
+
|
|
2740
|
+
🔧 Recommended Solutions:
|
|
2741
|
+
✅ Use snow_create_flow with natural language:
|
|
2742
|
+
snow_create_flow({
|
|
2743
|
+
instruction: "create approval flow for...",
|
|
2744
|
+
deploy_immediately: true
|
|
2745
|
+
})
|
|
2746
|
+
|
|
2747
|
+
✅ Or use snow_flow_wizard for step-by-step creation
|
|
2748
|
+
|
|
2749
|
+
❌ Avoid: Manual JSON flow definitions (unreliable)
|
|
2750
|
+
|
|
2751
|
+
💡 Alternative Approach:
|
|
2752
|
+
1. Use snow_create_flow for natural language creation
|
|
2753
|
+
2. Use snow_test_flow_with_mock for testing
|
|
2754
|
+
3. Use snow_deploy_flow only for pre-validated definitions`
|
|
2755
|
+
}
|
|
2756
|
+
]
|
|
2757
|
+
};
|
|
2566
2758
|
}
|
|
2567
|
-
|
|
2759
|
+
// Check for activities that exist but are empty
|
|
2760
|
+
const activitiesArray = workingDefinition.activities || workingDefinition.steps || workingDefinition.actions;
|
|
2761
|
+
if (activitiesArray && Array.isArray(activitiesArray) && activitiesArray.length === 0) {
|
|
2762
|
+
return {
|
|
2763
|
+
content: [
|
|
2764
|
+
{
|
|
2765
|
+
type: 'text',
|
|
2766
|
+
text: `🚨 Flow Definition Error: Empty activities array
|
|
2767
|
+
|
|
2768
|
+
📍 Problem: Flow has an activities array but no actual activities defined.
|
|
2769
|
+
|
|
2770
|
+
🔧 Recommended Solutions:
|
|
2771
|
+
✅ Use snow_create_flow with natural language:
|
|
2772
|
+
snow_create_flow({
|
|
2773
|
+
instruction: "create flow that sends email when incident priority is high",
|
|
2774
|
+
deploy_immediately: true
|
|
2775
|
+
})
|
|
2776
|
+
|
|
2777
|
+
✅ Or define activities manually:
|
|
2778
|
+
{
|
|
2779
|
+
"activities": [
|
|
2780
|
+
{
|
|
2781
|
+
"name": "Check Priority",
|
|
2782
|
+
"type": "condition",
|
|
2783
|
+
"condition": "current.priority == 1"
|
|
2784
|
+
},
|
|
2785
|
+
{
|
|
2786
|
+
"name": "Send Alert",
|
|
2787
|
+
"type": "notification",
|
|
2788
|
+
"recipients": "incident.assigned_to"
|
|
2789
|
+
}
|
|
2790
|
+
]
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
💡 Best Practice: Use natural language flow creation instead of manual JSON`
|
|
2794
|
+
}
|
|
2795
|
+
]
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
// Now check for activities/steps/actions in the working definition
|
|
2799
|
+
if (workingDefinition.steps && !workingDefinition.activities) {
|
|
2568
2800
|
// AUTO-CORRECT: Convert "steps" to "activities"
|
|
2569
2801
|
workingDefinition.activities = workingDefinition.steps;
|
|
2570
2802
|
delete workingDefinition.steps;
|