snow-flow 4.5.48 → 4.5.49

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.
@@ -263,6 +263,35 @@ class ServiceNowFlowWorkspaceMobileMCP {
263
263
  required: ['workspace_sys_id', 'workspace_type']
264
264
  }
265
265
  },
266
+ // COMPREHENSIVE TOOL HEALTH CHECKING
267
+ {
268
+ name: 'snow_test_all_workspace_tools',
269
+ description: 'Test all workspace and UI Builder tools to check availability, permissions, and functionality. Provides comprehensive status report with detailed feedback.',
270
+ inputSchema: {
271
+ type: 'object',
272
+ properties: {
273
+ include_ui_builder: { type: 'boolean', default: true, description: 'Test UI Builder tools' },
274
+ include_workspace: { type: 'boolean', default: true, description: 'Test workspace creation tools' },
275
+ include_mobile: { type: 'boolean', default: true, description: 'Test mobile tools' },
276
+ include_flow: { type: 'boolean', default: true, description: 'Test flow tools' },
277
+ detailed_errors: { type: 'boolean', default: true, description: 'Include detailed error information' }
278
+ }
279
+ }
280
+ },
281
+ {
282
+ name: 'snow_check_plugin_availability',
283
+ description: 'Check availability and licensing status of all ServiceNow plugins required for workspace and UI Builder functionality.',
284
+ inputSchema: {
285
+ type: 'object',
286
+ properties: {
287
+ check_ui_builder: { type: 'boolean', default: true, description: 'Check UI Builder plugin' },
288
+ check_uxf: { type: 'boolean', default: true, description: 'Check Now Experience Framework' },
289
+ check_agent_workspace: { type: 'boolean', default: true, description: 'Check Agent Workspace plugin' },
290
+ check_mobile: { type: 'boolean', default: true, description: 'Check Mobile Publishing' },
291
+ include_recommendations: { type: 'boolean', default: true, description: 'Include setup recommendations' }
292
+ }
293
+ }
294
+ },
266
295
  // Mobile Tools
267
296
  {
268
297
  name: 'snow_configure_mobile_app',
@@ -822,6 +851,12 @@ class ServiceNowFlowWorkspaceMobileMCP {
822
851
  case 'snow_validate_workspace_configuration':
823
852
  result = await this.validateWorkspaceConfiguration(args);
824
853
  break;
854
+ case 'snow_test_all_workspace_tools':
855
+ result = await this.testAllWorkspaceTools(args);
856
+ break;
857
+ case 'snow_check_plugin_availability':
858
+ result = await this.checkPluginAvailability(args);
859
+ break;
825
860
  // Mobile
826
861
  case 'snow_configure_mobile_app':
827
862
  result = await this.configureMobileApp(args);
@@ -1870,12 +1905,34 @@ ${configList}${layoutsText}${offlineText}
1870
1905
  await this.client.deleteRecord('sys_ux_lib_source_script', sourceResponse.data.sys_id);
1871
1906
  throw new Error(`Failed to create component: ${componentResponse.error}`);
1872
1907
  }
1873
- this.logger.info('✅ UI Builder component created successfully');
1908
+ // VERIFICATION: Confirm both records were created
1909
+ const componentVerification = await this.client.getRecord('sys_ux_lib_component', componentResponse.data.result.sys_id);
1910
+ const sourceVerification = await this.client.getRecord('sys_ux_lib_source_script', sourceResponse.data.result.sys_id);
1911
+ if (!componentVerification.success || !sourceVerification.success) {
1912
+ return {
1913
+ success: false,
1914
+ error: 'Component creation reported success but records not found in tables',
1915
+ suggestion: 'Component creation may have been rolled back due to validation errors',
1916
+ verification_failed: true
1917
+ };
1918
+ }
1919
+ this.logger.info(`✅ UI Builder component created and verified: ${componentResponse.data.result.sys_id}`);
1874
1920
  return {
1875
1921
  success: true,
1876
- component: componentResponse.data,
1877
- source_script: sourceResponse.data,
1878
- message: `Custom UI Builder component '${args.name}' created successfully`
1922
+ verified: true,
1923
+ component_sys_id: componentResponse.data.result.sys_id,
1924
+ source_script_sys_id: sourceResponse.data.result.sys_id,
1925
+ component_name: args.name,
1926
+ category: args.category || 'custom',
1927
+ created_at: new Date().toISOString(),
1928
+ message: `✅ Custom UI Builder component '${args.name}' created and verified successfully`,
1929
+ detailed_confirmation: {
1930
+ operation: 'CREATE UI Builder Component',
1931
+ component_sys_id: componentResponse.data.result.sys_id,
1932
+ source_script_sys_id: sourceResponse.data.result.sys_id,
1933
+ verified_in_tables: ['sys_ux_lib_component', 'sys_ux_lib_source_script'],
1934
+ verification_timestamp: new Date().toISOString()
1935
+ }
1879
1936
  };
1880
1937
  }
1881
1938
  catch (error) {
@@ -2673,18 +2730,55 @@ ${configList}${layoutsText}${offlineText}
2673
2730
  };
2674
2731
  }
2675
2732
  const result = await this.client.createRecord('sys_ux_experience', experienceData);
2733
+ // ENHANCED FEEDBACK SYSTEM
2676
2734
  if (result.success && result.data && result.data.result && result.data.result.sys_id) {
2677
- this.logger.info(`✅ UX Experience created with sys_id: ${result.data.result.sys_id}`);
2735
+ const sys_id = result.data.result.sys_id;
2736
+ // VERIFICATION: Confirm record actually exists
2737
+ const verification = await this.client.getRecord('sys_ux_experience', sys_id);
2738
+ if (!verification.success) {
2739
+ return {
2740
+ success: false,
2741
+ error: `UX Experience creation reported success but record not found in sys_ux_experience table`,
2742
+ suggestion: 'Record creation may have failed silently or been rolled back due to permissions',
2743
+ reported_sys_id: sys_id,
2744
+ verification_failed: true
2745
+ };
2746
+ }
2747
+ this.logger.info(`✅ UX Experience created and verified with sys_id: ${sys_id}`);
2678
2748
  return {
2679
2749
  success: true,
2680
- experience_sys_id: result.data.result.sys_id,
2681
- message: `Experience '${args.name}' created successfully`,
2682
- next_step: "Create App Configuration using this experience_sys_id"
2750
+ verified: true,
2751
+ experience_sys_id: sys_id,
2752
+ experience_name: args.name,
2753
+ shell_macroponent: shellSysId ? 'Linked to app shell' : 'No shell linked',
2754
+ created_at: new Date().toISOString(),
2755
+ table: 'sys_ux_experience',
2756
+ message: `✅ UX Experience '${args.name}' created and verified successfully`,
2757
+ detailed_confirmation: {
2758
+ operation: 'CREATE UX Experience',
2759
+ sys_id: sys_id,
2760
+ name: args.name,
2761
+ active: true,
2762
+ verified_in_table: 'sys_ux_experience',
2763
+ verification_timestamp: new Date().toISOString()
2764
+ },
2765
+ next_step: `Create App Configuration using experience_sys_id: ${sys_id}`
2683
2766
  };
2684
2767
  }
2685
2768
  else {
2686
2769
  const error = (result.data && result.data.error) || (result.error) || 'Unknown error creating experience';
2687
- throw new Error(`Failed to create experience: ${error}`);
2770
+ return {
2771
+ success: false,
2772
+ error: `Failed to create UX Experience: ${error}`,
2773
+ suggestion: this.getErrorSuggestion(error),
2774
+ operation_attempted: 'CREATE sys_ux_experience',
2775
+ debug_info: {
2776
+ result_success: result.success,
2777
+ has_data: !!(result.data),
2778
+ has_result: !!(result.data && result.data.result),
2779
+ has_sys_id: !!(result.data && result.data.result && result.data.result.sys_id)
2780
+ }
2781
+ };
2688
2782
  }
2689
2783
  }
2690
2784
  catch (error) {
@@ -3292,6 +3386,216 @@ ${configList}${layoutsText}${offlineText}
3292
3386
  throw error;
3293
3387
  }
3294
3388
  }
3389
+ /**
3390
+ * COMPREHENSIVE TOOL HEALTH TESTING
3391
+ * Tests all workspace tools and provides detailed status report
3392
+ */
3393
+ async testAllWorkspaceTools(args) {
3394
+ try {
3395
+ this.logger.info('🛠️ Starting comprehensive tool health test...');
3396
+ const testResults = {
3397
+ test_timestamp: new Date().toISOString(),
3398
+ tools_tested: 0,
3399
+ tools_working: 0,
3400
+ tools_failing: 0,
3401
+ tools_unclear: 0,
3402
+ detailed_results: [],
3403
+ plugin_status: {},
3404
+ recommendations: []
3405
+ };
3406
+ // Test critical plugins first
3407
+ const pluginTests = [
3408
+ { name: 'UI Builder', table: 'sys_ux_page', description: 'UI Builder functionality' },
3409
+ { name: 'Now Experience Framework', table: 'sys_ux_experience', description: 'UX Workspace creation' },
3410
+ { name: 'Agent Workspace', table: 'sys_ux_app_route', description: 'Configurable Agent Workspaces' },
3411
+ { name: 'Mobile Publishing', table: 'sys_push_notif_msg', description: 'Mobile app management' },
3412
+ { name: 'Flow Designer', table: 'sys_hub_flow', description: 'Flow automation' }
3413
+ ];
3414
+ for (const plugin of pluginTests) {
3415
+ const pluginTest = await this.client.searchRecords(plugin.table, '', 1);
3416
+ testResults.plugin_status[plugin.name] = {
3417
+ available: pluginTest.success,
3418
+ table: plugin.table,
3419
+ description: plugin.description,
3420
+ status: pluginTest.success ? '✅ Available' : '❌ Not Available'
3421
+ };
3422
+ }
3423
+ // Test individual tools
3424
+ const toolTests = [
3425
+ // UX Experience tools
3426
+ {
3427
+ name: 'snow_create_ux_experience',
3428
+ test: () => this.snow_create_ux_experience({ name: 'Health Test Experience' }),
3429
+ category: 'UX Experience',
3430
+ expects_sys_id: true
3431
+ },
3432
+ // UI Builder tools
3433
+ {
3434
+ name: 'snow_discover_uib_pages',
3435
+ test: () => this.discoverUIBuilderPages({}),
3436
+ category: 'UI Builder',
3437
+ expects_sys_id: false
3438
+ },
3439
+ // Mobile tools
3440
+ {
3441
+ name: 'snow_configure_mobile_app',
3442
+ test: () => this.configureMobileApp({ app_name: 'Health Test App' }),
3443
+ category: 'Mobile',
3444
+ expects_sys_id: true
3445
+ }
3446
+ ];
3447
+ for (const toolTest of toolTests) {
3448
+ try {
3449
+ testResults.tools_tested++;
3450
+ const testStart = Date.now();
3451
+ const result = await toolTest.test();
3452
+ const testDuration = Date.now() - testStart;
3453
+ let status = '❌ FAILED';
3454
+ let feedback = 'No response';
3455
+ if (result && result.success === true) {
3456
+ if (toolTest.expects_sys_id && result.sys_id) {
3457
+ status = '✅ WORKING';
3458
+ feedback = `Created record with sys_id: ${result.sys_id}`;
3459
+ testResults.tools_working++;
3460
+ }
3461
+ else if (!toolTest.expects_sys_id) {
3462
+ status = '✅ WORKING';
3463
+ feedback = 'Operation completed successfully';
3464
+ testResults.tools_working++;
3465
+ }
3466
+ else {
3467
+ status = '⚠️ UNCLEAR';
3468
+ feedback = 'Success reported but no sys_id returned';
3469
+ testResults.tools_unclear++;
3470
+ }
3471
+ }
3472
+ else if (result && result.success === false) {
3473
+ status = '❌ FAILED';
3474
+ feedback = result.error || 'Unknown error';
3475
+ testResults.tools_failing++;
3476
+ }
3477
+ else {
3478
+ status = '⚠️ UNCLEAR';
3479
+ feedback = 'No clear success/failure indication';
3480
+ testResults.tools_unclear++;
3481
+ }
3482
+ testResults.detailed_results.push({
3483
+ tool: toolTest.name,
3484
+ category: toolTest.category,
3485
+ status: status,
3486
+ feedback: feedback,
3487
+ execution_time_ms: testDuration,
3488
+ expects_sys_id: toolTest.expects_sys_id,
3489
+ actual_result: result
3490
+ });
3491
+ }
3492
+ catch (error) {
3493
+ testResults.tools_tested++;
3494
+ testResults.tools_failing++;
3495
+ testResults.detailed_results.push({
3496
+ tool: toolTest.name,
3497
+ category: toolTest.category,
3498
+ status: '❌ FAILED',
3499
+ feedback: `Exception: ${error}`,
3500
+ execution_time_ms: 0,
3501
+ error_type: 'EXCEPTION'
3502
+ });
3503
+ }
3504
+ }
3505
+ // Generate recommendations
3506
+ if (testResults.tools_working === 0) {
3507
+ testResults.recommendations.push('No tools are working - check authentication and instance setup');
3508
+ }
3509
+ if (testResults.tools_unclear > 0) {
3510
+ testResults.recommendations.push('Some tools have unclear status - implement better response validation');
3511
+ }
3512
+ this.logger.info(`✅ Tool health test completed: ${testResults.tools_working}/${testResults.tools_tested} working`);
3513
+ return {
3514
+ success: true,
3515
+ test_summary: testResults,
3516
+ message: `Tool health test completed: ${testResults.tools_working}/${testResults.tools_tested} tools working properly`,
3517
+ detailed_report: testResults.detailed_results
3518
+ };
3519
+ }
3520
+ catch (error) {
3521
+ this.logger.error('Failed to test workspace tools:', error);
3522
+ throw error;
3523
+ }
3524
+ }
3525
+ /**
3526
+ * CHECK PLUGIN AVAILABILITY
3527
+ * Comprehensive plugin and licensing status check
3528
+ */
3529
+ async checkPluginAvailability(args) {
3530
+ try {
3531
+ this.logger.info('🔌 Checking ServiceNow plugin availability...');
3532
+ const pluginChecks = [];
3533
+ if (args.check_ui_builder) {
3534
+ const uiBuilderCheck = await this.client.searchRecords('sys_ux_page', '', 1);
3535
+ pluginChecks.push({
3536
+ name: 'UI Builder',
3537
+ table: 'sys_ux_page',
3538
+ available: uiBuilderCheck.success,
3539
+ error: uiBuilderCheck.success ? null : uiBuilderCheck.error,
3540
+ status: uiBuilderCheck.success ? '✅ Available' : '❌ Not Available',
3541
+ recommendation: uiBuilderCheck.success ? 'UI Builder tools should work' : 'Install UI Builder plugin from ServiceNow Store'
3542
+ });
3543
+ }
3544
+ if (args.check_uxf) {
3545
+ const uxfCheck = await this.client.searchRecords('sys_ux_experience', '', 1);
3546
+ pluginChecks.push({
3547
+ name: 'Now Experience Framework',
3548
+ table: 'sys_ux_experience',
3549
+ available: uxfCheck.success,
3550
+ error: uxfCheck.success ? null : uxfCheck.error,
3551
+ status: uxfCheck.success ? '✅ Available' : '❌ Not Available',
3552
+ recommendation: uxfCheck.success ? 'UX workspace creation should work' : 'Enable Now Experience Framework in instance'
3553
+ });
3554
+ }
3555
+ if (args.check_agent_workspace) {
3556
+ const agentCheck = await this.client.searchRecords('sys_ux_screen_type', '', 1);
3557
+ pluginChecks.push({
3558
+ name: 'Agent Workspace',
3559
+ table: 'sys_ux_screen_type',
3560
+ available: agentCheck.success,
3561
+ error: agentCheck.success ? null : agentCheck.error,
3562
+ status: agentCheck.success ? '✅ Available' : '❌ Not Available',
3563
+ recommendation: agentCheck.success ? 'Agent workspace tools should work' : 'Install Agent Workspace plugin'
3564
+ });
3565
+ }
3566
+ if (args.check_mobile) {
3567
+ const mobileCheck = await this.client.searchRecords('sys_push_notif_msg', '', 1);
3568
+ pluginChecks.push({
3569
+ name: 'Mobile Publishing',
3570
+ table: 'sys_push_notif_msg',
3571
+ available: mobileCheck.success,
3572
+ error: mobileCheck.success ? null : mobileCheck.error,
3573
+ status: mobileCheck.success ? '✅ Available' : '❌ Not Available',
3574
+ recommendation: mobileCheck.success ? 'Mobile tools should work' : 'Install Mobile Publishing plugin (requires additional licensing)'
3575
+ });
3576
+ }
3577
+ const availableCount = pluginChecks.filter(p => p.available).length;
3578
+ const totalCount = pluginChecks.length;
3579
+ this.logger.info(`✅ Plugin check completed: ${availableCount}/${totalCount} plugins available`);
3580
+ return {
3581
+ success: true,
3582
+ plugin_summary: {
3583
+ total_checked: totalCount,
3584
+ available: availableCount,
3585
+ unavailable: totalCount - availableCount,
3586
+ percentage: Math.round((availableCount / totalCount) * 100)
3587
+ },
3588
+ plugins: pluginChecks,
3589
+ message: `Plugin availability check: ${availableCount}/${totalCount} plugins available`,
3590
+ overall_status: availableCount === totalCount ? 'All plugins available' :
3591
+ availableCount > 0 ? 'Partial plugin availability' : 'No plugins available'
3592
+ };
3593
+ }
3594
+ catch (error) {
3595
+ this.logger.error('Failed to check plugin availability:', error);
3596
+ throw error;
3597
+ }
3598
+ }
3295
3599
  /**
3296
3600
  * CONFIGURABLE AGENT WORKSPACE: Create using UX App architecture
3297
3601
  */
@@ -3398,6 +3702,141 @@ ${configList}${layoutsText}${offlineText}
3398
3702
  .replace(/^-|-$/g, '') // Trim leading/trailing hyphens
3399
3703
  .substring(0, 80); // Max 80 chars (ServiceNow field limit)
3400
3704
  }
3705
+ /**
3706
+ * ENHANCED RESPONSE VALIDATION SYSTEM
3707
+ * Provides comprehensive feedback for all tool operations
3708
+ */
3709
+ async validateAndConfirmOperation(operationType, result, details) {
3710
+ try {
3711
+ // Standard validation for ServiceNow API responses
3712
+ if (!result || typeof result !== 'object') {
3713
+ return {
3714
+ success: false,
3715
+ error: `No response received from ServiceNow API for ${operationType}`,
3716
+ suggestion: 'Check ServiceNow instance connectivity and authentication',
3717
+ validation_result: 'NO_RESPONSE'
3718
+ };
3719
+ }
3720
+ // Check for API success/failure
3721
+ if (result.success === false) {
3722
+ return {
3723
+ success: false,
3724
+ error: result.error || `${operationType} operation failed`,
3725
+ suggestion: this.getErrorSuggestion(result.error || ''),
3726
+ validation_result: 'API_FAILURE'
3727
+ };
3728
+ }
3729
+ // Validate response data structure
3730
+ if (result.success && (!result.data || !result.data.result)) {
3731
+ return {
3732
+ success: false,
3733
+ error: `${operationType} succeeded but returned invalid data structure`,
3734
+ suggestion: 'Check ServiceNow table permissions and field access',
3735
+ validation_result: 'INVALID_DATA_STRUCTURE'
3736
+ };
3737
+ }
3738
+ // Extract sys_id for verification
3739
+ const sys_id = result.data?.result?.sys_id;
3740
+ if (result.success && !sys_id) {
3741
+ return {
3742
+ success: false,
3743
+ error: `${operationType} succeeded but no sys_id returned`,
3744
+ suggestion: 'Record may have been created but sys_id is not accessible',
3745
+ validation_result: 'MISSING_SYS_ID'
3746
+ };
3747
+ }
3748
+ // VERIFICATION STEP: Confirm record actually exists
3749
+ if (sys_id && details.table) {
3750
+ const verification = await this.client.getRecord(details.table, sys_id);
3751
+ if (!verification.success) {
3752
+ return {
3753
+ success: false,
3754
+ error: `${operationType} reported success but record not found in ${details.table}`,
3755
+ suggestion: 'Record creation may have failed silently or been rolled back',
3756
+ validation_result: 'RECORD_NOT_FOUND',
3757
+ reported_sys_id: sys_id
3758
+ };
3759
+ }
3760
+ // SUCCESS with verification!
3761
+ return {
3762
+ success: true,
3763
+ sys_id: sys_id,
3764
+ verified: true,
3765
+ operation_type: operationType,
3766
+ table: details.table,
3767
+ message: `${operationType} completed successfully`,
3768
+ confirmation: `Record verified in ${details.table} with sys_id: ${sys_id}`,
3769
+ validation_result: 'VERIFIED_SUCCESS'
3770
+ };
3771
+ }
3772
+ // Success without verification (no sys_id or table)
3773
+ return {
3774
+ success: true,
3775
+ operation_type: operationType,
3776
+ message: `${operationType} completed`,
3777
+ validation_result: 'SUCCESS_NO_VERIFICATION'
3778
+ };
3779
+ }
3780
+ catch (error) {
3781
+ this.logger.error('Validation error:', error);
3782
+ return {
3783
+ success: false,
3784
+ error: `Validation failed for ${operationType}: ${error}`,
3785
+ suggestion: 'Check ServiceNow connectivity and permissions',
3786
+ validation_result: 'VALIDATION_ERROR'
3787
+ };
3788
+ }
3789
+ }
3790
+ /**
3791
+ * Get actionable suggestions based on error type
3792
+ */
3793
+ getErrorSuggestion(error) {
3794
+ const errorLower = error.toLowerCase();
3795
+ if (errorLower.includes('403') || errorLower.includes('forbidden')) {
3796
+ return 'Check user permissions. May need ui_builder_admin or workspace_admin roles.';
3797
+ }
3798
+ if (errorLower.includes('404') || errorLower.includes('not found')) {
3799
+ return 'Table/endpoint not available. Check if required plugin is installed and activated.';
3800
+ }
3801
+ if (errorLower.includes('400') || errorLower.includes('bad request')) {
3802
+ return 'Invalid parameters or missing required fields. Check API documentation.';
3803
+ }
3804
+ if (errorLower.includes('401') || errorLower.includes('unauthorized')) {
3805
+ return 'Authentication issue. Run snow-flow auth login to re-authenticate.';
3806
+ }
3807
+ if (errorLower.includes('plugin') || errorLower.includes('license')) {
3808
+ return 'Required plugin not installed. Check ServiceNow Store for required plugins.';
3809
+ }
3810
+ return 'Check ServiceNow system logs for detailed error information.';
3811
+ }
3812
+ /**
3813
+ * Enhanced tool execution wrapper with comprehensive feedback
3814
+ */
3815
+ async executeWithFeedback(operationType, operation, details) {
3816
+ try {
3817
+ this.logger.info(`🔄 Executing ${operationType}...`);
3818
+ const startTime = Date.now();
3819
+ const result = await operation();
3820
+ const executionTime = Date.now() - startTime;
3821
+ const validation = await this.validateAndConfirmOperation(operationType, result, details);
3822
+ return {
3823
+ ...validation,
3824
+ execution_time_ms: executionTime,
3825
+ timestamp: new Date().toISOString()
3826
+ };
3827
+ }
3828
+ catch (error) {
3829
+ this.logger.error(`❌ ${operationType} failed:`, error);
3830
+ return {
3831
+ success: false,
3832
+ operation_type: operationType,
3833
+ error: error instanceof Error ? error.message : String(error),
3834
+ suggestion: this.getErrorSuggestion(String(error)),
3835
+ validation_result: 'EXECUTION_ERROR',
3836
+ timestamp: new Date().toISOString()
3837
+ };
3838
+ }
3839
+ }
3401
3840
  /**
3402
3841
  * Validate workspace configuration (fix from user feedback)
3403
3842
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "4.5.48",
3
+ "version": "4.5.49",
4
4
  "description": "Conversational ServiceNow development platform using Claude Code. Multi-agent orchestration with 20+ MCP servers providing 245+ ServiceNow tools including complete UX + Agent Workspace creation with official APIs.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",