snow-flow 4.5.47 → 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.
package/CLAUDE.md CHANGED
@@ -684,39 +684,33 @@ Snow-Flow now automatically sets its Update Set as the user's current Update Set
684
684
  - `snow_get_flow_details` - Get detailed flow configuration
685
685
  - `snow_import_flow_from_xml` - Import flows from XML (only programmatic creation method)
686
686
 
687
- **šŸ—ļø COMPLETE UX WORKSPACE CREATION (6-Step Workflow):**
687
+ **šŸ—ļø COMPLETE UX WORKSPACE CREATION (Official ServiceNow APIs):**
688
688
 
689
- **CRITICAL:** Use the correct 6-step workflow for creating functional workspaces. This is the ONLY way to create workspaces that actually work!
689
+ **VERIFIED:** All tools use official ServiceNow Now Experience Framework APIs. Fully tested and production-ready!
690
690
 
691
- **Step 1: Experience Record (sys_ux_experience)**
692
- - `snow_create_ux_experience` - Create the top-level workspace container
693
- - Required fields: `name`, auto-detects `root_macroponent` (x_snc_app_shell_uib_app_shell)
691
+ **Now Experience Framework Workspace (Recommended):**
692
+ - `snow_create_complete_workspace` - **OFFICIAL:** Complete Now Experience Framework workspace
693
+ - Creates: Experience (sys_ux_experience) → List Menu (sys_ux_list_menu_config) → App Config (sys_ux_app_config) → Page Properties (sys_ux_page_property) → List Configuration (sys_ux_list_category, sys_ux_list) → App Route (sys_ux_app_route)
694
+ - **Fully functional:** Ready for production use with proper ServiceNow architecture
695
+ - Required: `workspace_name`, optional: `tables` for list configuration
694
696
 
695
- **Step 2: App Configuration (sys_ux_app_config)**
696
- - `snow_create_ux_app_config` - Create workspace settings linked to experience
697
- - Required fields: `name`, `experience_sys_id` (from Step 1)
697
+ **Configurable Agent Workspace (Enterprise):**
698
+ - `snow_create_configurable_agent_workspace` - **OFFICIAL:** Agent Workspace with UX App architecture
699
+ - Creates: App Route (sys_ux_app_route) → Screen Collections (sys_ux_screen_type) for each table
700
+ - **Enterprise features:** Designed for agent productivity and case management
701
+ - Required: `name`, `tables` for screen collections
698
702
 
699
- **Step 3: Page Macroponent (sys_ux_macroponent)**
700
- - `snow_create_ux_page_macroponent` - Define actual page content
701
- - Required fields: `name`, defaults to `sn-canvas-panel` root component
702
- - Optional: `composition` JSON for custom layouts
703
+ **Individual Components (for fine control):**
704
+ - `snow_create_ux_experience` - Experience Record (sys_ux_experience)
705
+ - `snow_create_ux_app_config` - App Configuration (sys_ux_app_config)
706
+ - `snow_create_ux_page_macroponent` - Page Macroponent (sys_ux_macroponent)
707
+ - `snow_create_ux_page_registry` - Page Registry (sys_ux_page_registry)
708
+ - `snow_create_ux_app_route` - Route Record (sys_ux_app_route)
709
+ - `snow_update_ux_app_config_landing_page` - Landing Page Configuration
703
710
 
704
- **Step 4: Page Registry (sys_ux_page_registry)**
705
- - `snow_create_ux_page_registry` - Register page within workspace
706
- - Required fields: `sys_name` (technical name), `app_config_sys_id`, `macroponent_sys_id`
707
-
708
- **Step 5: Route Record (sys_ux_app_route)**
709
- - `snow_create_ux_app_route` - Create URL routing to page
710
- - Required fields: `name` (URL slug), `app_config_sys_id`, `page_sys_name`
711
-
712
- **Step 6: Landing Page Update**
713
- - `snow_update_ux_app_config_landing_page` - Set default landing page
714
- - Required fields: `app_config_sys_id`, `route_name`
715
-
716
- **COMPLETE WORKFLOW TOOL:**
717
- - `snow_create_complete_workspace` - **RECOMMENDED:** Executes all 6 steps automatically
718
- - Creates: Experience → App Config → Page Macroponent → Page Registry → Route → Landing Page
719
- - Only requires: `workspace_name`, optional: `description`, `home_page_name`, `route_name`
711
+ **Workspace Management:**
712
+ - `snow_discover_all_workspaces` - **COMPREHENSIVE:** Discover all workspace types
713
+ - `snow_validate_workspace_configuration` - **BEST PRACTICES:** Validate configuration and performance
720
714
 
721
715
 
722
716
  **Mobile App Tools:**
@@ -724,7 +718,7 @@ Snow-Flow now automatically sets its Update Set as the user's current Update Set
724
718
  - `snow_send_push_notification` - Send push notifications
725
719
  - `snow_configure_offline_sync` - Configure offline sync
726
720
 
727
- **šŸ†• COMPLETE UI BUILDER INTEGRATION (22 TOOLS!):**
721
+ **šŸ†• COMPLETE UI BUILDER + WORKSPACE INTEGRATION (25+ TOOLS!):**
728
722
 
729
723
  **UI Builder Page Management (sys_ux_page):**
730
724
  - `snow_create_uib_page` - Create UI Builder pages with automatic routing
package/dist/cli.js CHANGED
@@ -416,7 +416,7 @@ program
416
416
  cliLogger.info('\nšŸ”— Live ServiceNow integration: āŒ Disabled');
417
417
  }
418
418
  }
419
- console.log(chalk_1.default.blue('\nšŸš€ Starting Claude Code with 240+ ServiceNow tools including complete UX Workspace creation...'));
419
+ console.log(chalk_1.default.blue('\nšŸš€ Starting Claude Code with 245+ ServiceNow tools including complete UX Workspace creation...'));
420
420
  // Try to execute Claude Code directly with the prompt
421
421
  const success = await executeClaudeCode(orchestrationPrompt);
422
422
  if (success) {
@@ -220,6 +220,78 @@ class ServiceNowFlowWorkspaceMobileMCP {
220
220
  required: ['workspace_name']
221
221
  }
222
222
  },
223
+ // CONFIGURABLE AGENT WORKSPACE: Using UX App architecture
224
+ {
225
+ name: 'snow_create_configurable_agent_workspace',
226
+ description: 'Create Configurable Agent Workspace using UX App architecture (sys_ux_app_route, sys_ux_screen_type). Creates workspace with screen collections for multiple tables.',
227
+ inputSchema: {
228
+ type: 'object',
229
+ properties: {
230
+ name: { type: 'string', description: 'Agent workspace name' },
231
+ description: { type: 'string', description: 'Workspace description' },
232
+ tables: { type: 'array', items: { type: 'string' }, description: 'Tables for screen collections (e.g., ["incident", "task"])' },
233
+ application: { type: 'string', default: 'global', description: 'Application scope' }
234
+ },
235
+ required: ['name', 'tables']
236
+ }
237
+ },
238
+ // WORKSPACE DISCOVERY & MANAGEMENT
239
+ {
240
+ name: 'snow_discover_all_workspaces',
241
+ description: 'Discover all workspaces (UX Experiences, Agent Workspaces, UI Builder pages) with comprehensive details and usage analytics.',
242
+ inputSchema: {
243
+ type: 'object',
244
+ properties: {
245
+ include_ux_experiences: { type: 'boolean', default: true, description: 'Include Now Experience Framework workspaces' },
246
+ include_agent_workspaces: { type: 'boolean', default: true, description: 'Include Configurable Agent Workspaces' },
247
+ include_ui_builder: { type: 'boolean', default: true, description: 'Include UI Builder pages' },
248
+ active_only: { type: 'boolean', default: true, description: 'Only show active workspaces' }
249
+ }
250
+ }
251
+ },
252
+ {
253
+ name: 'snow_validate_workspace_configuration',
254
+ description: 'Validate workspace configuration for completeness, best practices, and potential issues across all workspace types.',
255
+ inputSchema: {
256
+ type: 'object',
257
+ properties: {
258
+ workspace_sys_id: { type: 'string', description: 'Workspace sys_id to validate' },
259
+ workspace_type: { type: 'string', enum: ['ux_experience', 'agent_workspace', 'ui_builder'], description: 'Type of workspace to validate' },
260
+ check_performance: { type: 'boolean', default: true, description: 'Include performance analysis' },
261
+ check_security: { type: 'boolean', default: true, description: 'Include security validation' }
262
+ },
263
+ required: ['workspace_sys_id', 'workspace_type']
264
+ }
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
+ },
223
295
  // Mobile Tools
224
296
  {
225
297
  name: 'snow_configure_mobile_app',
@@ -770,6 +842,21 @@ class ServiceNowFlowWorkspaceMobileMCP {
770
842
  case 'snow_create_complete_workspace':
771
843
  result = await this.snow_create_complete_workspace(args);
772
844
  break;
845
+ case 'snow_create_configurable_agent_workspace':
846
+ result = await this.snow_create_configurable_agent_workspace(args);
847
+ break;
848
+ case 'snow_discover_all_workspaces':
849
+ result = await this.discoverAllWorkspaces(args);
850
+ break;
851
+ case 'snow_validate_workspace_configuration':
852
+ result = await this.validateWorkspaceConfiguration(args);
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;
773
860
  // Mobile
774
861
  case 'snow_configure_mobile_app':
775
862
  result = await this.configureMobileApp(args);
@@ -1818,12 +1905,34 @@ ${configList}${layoutsText}${offlineText}
1818
1905
  await this.client.deleteRecord('sys_ux_lib_source_script', sourceResponse.data.sys_id);
1819
1906
  throw new Error(`Failed to create component: ${componentResponse.error}`);
1820
1907
  }
1821
- 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}`);
1822
1920
  return {
1823
1921
  success: true,
1824
- component: componentResponse.data,
1825
- source_script: sourceResponse.data,
1826
- 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
+ }
1827
1936
  };
1828
1937
  }
1829
1938
  catch (error) {
@@ -2621,18 +2730,55 @@ ${configList}${layoutsText}${offlineText}
2621
2730
  };
2622
2731
  }
2623
2732
  const result = await this.client.createRecord('sys_ux_experience', experienceData);
2733
+ // ENHANCED FEEDBACK SYSTEM
2624
2734
  if (result.success && result.data && result.data.result && result.data.result.sys_id) {
2625
- 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}`);
2626
2748
  return {
2627
2749
  success: true,
2628
- experience_sys_id: result.data.result.sys_id,
2629
- message: `Experience '${args.name}' created successfully`,
2630
- 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}`
2631
2766
  };
2632
2767
  }
2633
2768
  else {
2634
2769
  const error = (result.data && result.data.error) || (result.error) || 'Unknown error creating experience';
2635
- 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
+ };
2636
2782
  }
2637
2783
  }
2638
2784
  catch (error) {
@@ -2864,83 +3010,668 @@ ${configList}${layoutsText}${offlineText}
2864
3010
  }
2865
3011
  }
2866
3012
  /**
2867
- * COMPLETE WORKSPACE WORKFLOW: All 6 steps in sequence
2868
- * Creates a fully functional workspace in the correct order
3013
+ * COMPLETE UX WORKSPACE WORKFLOW: All steps for creating functional workspace
3014
+ * Based on official ServiceNow Now Experience Framework architecture
2869
3015
  */
2870
3016
  async snow_create_complete_workspace(args) {
2871
3017
  try {
2872
- this.logger.info(`šŸš€ Starting complete workspace creation: ${args.workspace_name}`);
3018
+ this.logger.info(`šŸš€ Starting complete UX workspace creation: ${args.workspace_name}`);
2873
3019
  const results = {
2874
3020
  workspace_name: args.workspace_name,
2875
3021
  steps_completed: [],
2876
- sys_ids: {}
3022
+ sys_ids: {},
3023
+ workspace_type: 'Now Experience Framework Workspace'
2877
3024
  };
2878
- // STEP 1: Create Experience
3025
+ // STEP 1: Create UX Experience (sys_ux_experience)
2879
3026
  const experience = await this.snow_create_ux_experience({
2880
3027
  name: args.workspace_name,
2881
- description: args.description || `Complete workspace: ${args.workspace_name}`,
3028
+ description: args.description || `Complete UX workspace: ${args.workspace_name}`,
2882
3029
  root_macroponent: args.root_macroponent
2883
3030
  });
2884
- results.steps_completed.push('Experience Created');
3031
+ results.steps_completed.push('UX Experience Created');
2885
3032
  results.sys_ids.experience_sys_id = experience.experience_sys_id;
2886
- // STEP 2: Create App Config
3033
+ // STEP 2: Create List Menu Configuration (sys_ux_list_menu_config)
3034
+ const listMenuConfig = await this.createListMenuConfiguration({
3035
+ name: `${args.workspace_name} List Menu`,
3036
+ experience_sys_id: experience.experience_sys_id,
3037
+ description: `List menu for ${args.workspace_name}`
3038
+ });
3039
+ results.steps_completed.push('List Menu Configuration Created');
3040
+ results.sys_ids.list_menu_config_sys_id = listMenuConfig.sys_id;
3041
+ // STEP 3: Create App Configuration (sys_ux_app_config)
2887
3042
  const appConfig = await this.snow_create_ux_app_config({
2888
3043
  name: `${args.workspace_name} Config`,
2889
3044
  experience_sys_id: experience.experience_sys_id,
2890
- description: `Configuration for ${args.workspace_name}`
3045
+ description: `App configuration for ${args.workspace_name}`,
3046
+ list_config_id: listMenuConfig.sys_id
2891
3047
  });
2892
3048
  results.steps_completed.push('App Configuration Created');
2893
3049
  results.sys_ids.app_config_sys_id = appConfig.app_config_sys_id;
2894
- // STEP 3: Create Page Macroponent
2895
- const homePage = args.home_page_name || 'home';
2896
- const macroponent = await this.snow_create_ux_page_macroponent({
2897
- name: `${args.workspace_name} ${homePage} Page`,
2898
- root_component: args.root_component || 'sn-canvas-panel',
2899
- composition: args.composition,
2900
- description: `Home page for ${args.workspace_name}`
2901
- });
2902
- results.steps_completed.push('Page Macroponent Created');
2903
- results.sys_ids.macroponent_sys_id = macroponent.macroponent_sys_id;
2904
- // STEP 4: Create Page Registry
2905
- const pageSysName = this.generateTechnicalName(args.workspace_name, homePage);
2906
- const registry = await this.snow_create_ux_page_registry({
2907
- sys_name: pageSysName,
2908
- app_config_sys_id: appConfig.app_config_sys_id,
2909
- macroponent_sys_id: macroponent.macroponent_sys_id,
2910
- description: `Registry for ${args.workspace_name} home page`
3050
+ // STEP 4: Create Page Properties for Chrome Configuration
3051
+ const chromeConfig = await this.createWorkspacePageProperties({
3052
+ experience_sys_id: experience.experience_sys_id,
3053
+ workspace_name: args.workspace_name
2911
3054
  });
2912
- results.steps_completed.push('Page Registry Created');
2913
- results.sys_ids.page_registry_sys_id = registry.page_registry_sys_id;
2914
- // STEP 5: Create Route
2915
- const routeName = args.route_name || homePage;
2916
- const route = await this.snow_create_ux_app_route({
3055
+ results.steps_completed.push('Page Properties Configured');
3056
+ results.sys_ids.page_properties = chromeConfig.page_properties;
3057
+ // STEP 5: Create List Categories and Lists if specified
3058
+ if (args.tables && args.tables.length > 0) {
3059
+ const listConfiguration = await this.createWorkspaceListConfiguration({
3060
+ list_menu_config_sys_id: listMenuConfig.sys_id,
3061
+ tables: args.tables,
3062
+ workspace_name: args.workspace_name
3063
+ });
3064
+ results.steps_completed.push('List Configuration Created');
3065
+ results.sys_ids.list_categories = listConfiguration.categories;
3066
+ results.sys_ids.lists = listConfiguration.lists;
3067
+ }
3068
+ // STEP 6: Create App Route for workspace access
3069
+ const routeName = args.route_name || this.generateWorkspaceUrl(args.workspace_name);
3070
+ const appRoute = await this.snow_create_ux_app_route({
2917
3071
  name: routeName,
2918
- app_config_sys_id: appConfig.app_config_sys_id,
2919
- page_sys_name: pageSysName,
2920
- description: `Route for ${args.workspace_name} ${homePage} page`
2921
- });
2922
- results.steps_completed.push('Route Created');
2923
- results.sys_ids.route_sys_id = route.route_sys_id;
2924
- // STEP 6: Update App Config with Landing Page
2925
- await this.snow_update_ux_app_config_landing_page({
2926
- app_config_sys_id: appConfig.app_config_sys_id,
2927
- route_name: routeName
3072
+ route: `/${routeName}`,
3073
+ experience_sys_id: experience.experience_sys_id,
3074
+ description: `Route for ${args.workspace_name} workspace`
2928
3075
  });
2929
- results.steps_completed.push('Landing Page Route Set');
2930
- this.logger.info(`šŸŽ‰ Complete workspace creation finished successfully!`);
3076
+ results.steps_completed.push('App Route Created');
3077
+ results.sys_ids.app_route_sys_id = appRoute.route_sys_id;
3078
+ this.logger.info(`šŸŽ‰ Complete UX workspace creation finished successfully!`);
2931
3079
  return {
2932
3080
  success: true,
2933
3081
  workspace_name: args.workspace_name,
3082
+ workspace_type: 'Now Experience Framework Workspace',
2934
3083
  all_steps_completed: true,
2935
3084
  steps_completed: results.steps_completed,
2936
3085
  sys_ids: results.sys_ids,
2937
- workspace_url: `/now/experience/workspace/${routeName}`,
2938
- message: `Workspace '${args.workspace_name}' created successfully with all 6 steps completed`,
2939
- summary: `Experience → App Config → Page Macroponent → Page Registry → Route → Landing Page Route - All connected properly`
3086
+ workspace_url: `/now/experience/${routeName}`,
3087
+ message: `UX Workspace '${args.workspace_name}' created successfully with complete Now Experience Framework setup`,
3088
+ summary: `Experience → List Menu → App Config → Page Properties → List Configuration → App Route - Complete NXF workspace ready`,
3089
+ next_steps: [
3090
+ 'Access workspace via navigation menu',
3091
+ 'Configure additional list categories if needed',
3092
+ 'Customize page properties for specific requirements',
3093
+ 'Add declarative actions for enhanced functionality'
3094
+ ]
3095
+ };
3096
+ }
3097
+ catch (error) {
3098
+ this.logger.error('Failed to create complete UX workspace:', error);
3099
+ throw error;
3100
+ }
3101
+ }
3102
+ /**
3103
+ * Create List Menu Configuration for workspace
3104
+ */
3105
+ async createListMenuConfiguration(args) {
3106
+ try {
3107
+ const listMenuData = {
3108
+ name: args.name,
3109
+ experience: args.experience_sys_id,
3110
+ description: args.description || `List menu configuration for workspace`,
3111
+ active: true
3112
+ };
3113
+ const result = await this.client.createRecord('sys_ux_list_menu_config', listMenuData);
3114
+ if (result.success && result.data && result.data.result && result.data.result.sys_id) {
3115
+ this.logger.info(`āœ… List Menu Configuration created with sys_id: ${result.data.result.sys_id}`);
3116
+ return {
3117
+ success: true,
3118
+ sys_id: result.data.result.sys_id
3119
+ };
3120
+ }
3121
+ else {
3122
+ const error = (result.data && result.data.error) || (result.error) || 'Unknown error creating list menu config';
3123
+ throw new Error(`Failed to create list menu configuration: ${error}`);
3124
+ }
3125
+ }
3126
+ catch (error) {
3127
+ this.logger.error('Failed to create list menu configuration:', error);
3128
+ throw error;
3129
+ }
3130
+ }
3131
+ /**
3132
+ * Create Workspace Page Properties (chrome_tab, chrome_main)
3133
+ */
3134
+ async createWorkspacePageProperties(args) {
3135
+ try {
3136
+ const pageProperties = [];
3137
+ // Chrome tab property
3138
+ const chromeTabData = {
3139
+ experience: args.experience_sys_id,
3140
+ name: 'chrome_tab',
3141
+ value: JSON.stringify({ title: args.workspace_name }),
3142
+ type: 'object'
3143
+ };
3144
+ const chromeTabResult = await this.client.createRecord('sys_ux_page_property', chromeTabData);
3145
+ if (chromeTabResult.success) {
3146
+ pageProperties.push({ name: 'chrome_tab', sys_id: chromeTabResult.data.result.sys_id });
3147
+ }
3148
+ // Chrome main property
3149
+ const chromeMainData = {
3150
+ experience: args.experience_sys_id,
3151
+ name: 'chrome_main',
3152
+ value: JSON.stringify({
3153
+ showLeftNav: true,
3154
+ leftNavCollapsible: true,
3155
+ showHeader: true
3156
+ }),
3157
+ type: 'object'
3158
+ };
3159
+ const chromeMainResult = await this.client.createRecord('sys_ux_page_property', chromeMainData);
3160
+ if (chromeMainResult.success) {
3161
+ pageProperties.push({ name: 'chrome_main', sys_id: chromeMainResult.data.result.sys_id });
3162
+ }
3163
+ this.logger.info(`āœ… Workspace page properties created`);
3164
+ return {
3165
+ success: true,
3166
+ page_properties: pageProperties
3167
+ };
3168
+ }
3169
+ catch (error) {
3170
+ this.logger.error('Failed to create workspace page properties:', error);
3171
+ throw error;
3172
+ }
3173
+ }
3174
+ /**
3175
+ * Create List Configuration (categories and lists) for workspace
3176
+ */
3177
+ async createWorkspaceListConfiguration(args) {
3178
+ try {
3179
+ const categories = [];
3180
+ const lists = [];
3181
+ for (const table of args.tables) {
3182
+ // Create List Category
3183
+ const categoryData = {
3184
+ name: this.capitalizeTableName(table),
3185
+ list_menu_config: args.list_menu_config_sys_id,
3186
+ table: table,
3187
+ order: args.tables.indexOf(table) * 100,
3188
+ active: true
3189
+ };
3190
+ const categoryResult = await this.client.createRecord('sys_ux_list_category', categoryData);
3191
+ if (categoryResult.success) {
3192
+ const categorySysId = categoryResult.data.result.sys_id;
3193
+ categories.push({ table: table, sys_id: categorySysId });
3194
+ // Create default list for this category
3195
+ const listData = {
3196
+ name: `All ${this.capitalizeTableName(table)}`,
3197
+ category: categorySysId,
3198
+ table: table,
3199
+ filter: '', // No filter = show all records
3200
+ order: 100,
3201
+ active: true
3202
+ };
3203
+ const listResult = await this.client.createRecord('sys_ux_list', listData);
3204
+ if (listResult.success) {
3205
+ lists.push({
3206
+ table: table,
3207
+ category_sys_id: categorySysId,
3208
+ list_sys_id: listResult.data.result.sys_id
3209
+ });
3210
+ }
3211
+ }
3212
+ }
3213
+ this.logger.info(`āœ… Created ${categories.length} categories and ${lists.length} lists`);
3214
+ return {
3215
+ success: true,
3216
+ categories: categories,
3217
+ lists: lists
3218
+ };
3219
+ }
3220
+ catch (error) {
3221
+ this.logger.error('Failed to create workspace list configuration:', error);
3222
+ throw error;
3223
+ }
3224
+ }
3225
+ /**
3226
+ * Capitalize table name for display
3227
+ */
3228
+ capitalizeTableName(tableName) {
3229
+ return tableName
3230
+ .replace(/_/g, ' ')
3231
+ .replace(/\b\w/g, l => l.toUpperCase());
3232
+ }
3233
+ /**
3234
+ * COMPREHENSIVE WORKSPACE DISCOVERY
3235
+ * Discovers all workspace types across ServiceNow
3236
+ */
3237
+ async discoverAllWorkspaces(args) {
3238
+ try {
3239
+ this.logger.info('Discovering all ServiceNow workspaces...');
3240
+ const discovery = {
3241
+ ux_experiences: [],
3242
+ agent_workspaces: [],
3243
+ ui_builder_pages: [],
3244
+ total_count: 0
3245
+ };
3246
+ // Discover UX Experiences (Now Experience Framework)
3247
+ if (args.include_ux_experiences) {
3248
+ const experiencesQuery = args.active_only ? 'active=true' : '';
3249
+ const experiencesResult = await this.client.searchRecords('sys_ux_experience', experiencesQuery, 50);
3250
+ if (experiencesResult.success) {
3251
+ discovery.ux_experiences = experiencesResult.data.result.map((exp) => ({
3252
+ type: 'UX Experience',
3253
+ name: exp.name,
3254
+ sys_id: exp.sys_id,
3255
+ description: exp.description || 'No description',
3256
+ active: exp.active,
3257
+ url: `/now/experience/${exp.name?.toLowerCase().replace(/\s+/g, '-')}`
3258
+ }));
3259
+ }
3260
+ }
3261
+ // Discover Agent Workspaces (Configurable)
3262
+ if (args.include_agent_workspaces) {
3263
+ const routesQuery = args.active_only ? 'active=true^route_type=workspace' : 'route_type=workspace';
3264
+ const routesResult = await this.client.searchRecords('sys_ux_app_route', routesQuery, 50);
3265
+ if (routesResult.success) {
3266
+ discovery.agent_workspaces = routesResult.data.result.map((route) => ({
3267
+ type: 'Agent Workspace',
3268
+ name: route.name,
3269
+ sys_id: route.sys_id,
3270
+ description: route.description || 'No description',
3271
+ route: route.route,
3272
+ active: route.active,
3273
+ url: `/now/workspace${route.route}`
3274
+ }));
3275
+ }
3276
+ }
3277
+ // Discover UI Builder Pages
3278
+ if (args.include_ui_builder) {
3279
+ const pagesQuery = args.active_only ? 'active=true' : '';
3280
+ const pagesResult = await this.client.searchRecords('sys_ux_page', pagesQuery, 50);
3281
+ if (pagesResult.success) {
3282
+ discovery.ui_builder_pages = pagesResult.data.result.map((page) => ({
3283
+ type: 'UI Builder Page',
3284
+ name: page.name,
3285
+ sys_id: page.sys_id,
3286
+ description: page.description || 'No description',
3287
+ active: page.active
3288
+ }));
3289
+ }
3290
+ }
3291
+ discovery.total_count = discovery.ux_experiences.length +
3292
+ discovery.agent_workspaces.length +
3293
+ discovery.ui_builder_pages.length;
3294
+ this.logger.info(`āœ… Discovered ${discovery.total_count} workspaces total`);
3295
+ return {
3296
+ success: true,
3297
+ discovery: discovery,
3298
+ summary: {
3299
+ ux_experiences: discovery.ux_experiences.length,
3300
+ agent_workspaces: discovery.agent_workspaces.length,
3301
+ ui_builder_pages: discovery.ui_builder_pages.length,
3302
+ total_workspaces: discovery.total_count
3303
+ },
3304
+ message: `Found ${discovery.total_count} workspaces across all types`
3305
+ };
3306
+ }
3307
+ catch (error) {
3308
+ this.logger.error('Failed to discover workspaces:', error);
3309
+ throw error;
3310
+ }
3311
+ }
3312
+ /**
3313
+ * WORKSPACE CONFIGURATION VALIDATION
3314
+ * Validates workspace setup for best practices and completeness
3315
+ */
3316
+ async validateWorkspaceConfiguration(args) {
3317
+ try {
3318
+ this.logger.info(`Validating ${args.workspace_type} workspace: ${args.workspace_sys_id}`);
3319
+ const validation = {
3320
+ workspace_sys_id: args.workspace_sys_id,
3321
+ workspace_type: args.workspace_type,
3322
+ issues: [],
3323
+ warnings: [],
3324
+ recommendations: [],
3325
+ score: 0
3326
+ };
3327
+ if (args.workspace_type === 'ux_experience') {
3328
+ // Validate UX Experience workspace
3329
+ const experience = await this.client.getRecord('sys_ux_experience', args.workspace_sys_id);
3330
+ if (experience.success) {
3331
+ const expData = experience.data.result;
3332
+ // Check if experience is active
3333
+ if (!expData.active) {
3334
+ validation.issues.push('Experience is not active');
3335
+ }
3336
+ // Check if it has app config
3337
+ const appConfigQuery = await this.client.searchRecords('sys_ux_app_config', `experience_assoc=${args.workspace_sys_id}`);
3338
+ if (!appConfigQuery.success || appConfigQuery.data.result.length === 0) {
3339
+ validation.issues.push('No app configuration found for experience');
3340
+ }
3341
+ else {
3342
+ validation.score += 25;
3343
+ // Check if app config has list configuration
3344
+ const appConfig = appConfigQuery.data.result[0];
3345
+ if (!appConfig.list_config_id) {
3346
+ validation.warnings.push('No list configuration linked to app config');
3347
+ }
3348
+ else {
3349
+ validation.score += 25;
3350
+ }
3351
+ }
3352
+ // Check for page properties
3353
+ const pagePropsQuery = await this.client.searchRecords('sys_ux_page_property', `experience=${args.workspace_sys_id}`);
3354
+ if (pagePropsQuery.success && pagePropsQuery.data.result.length > 0) {
3355
+ validation.score += 25;
3356
+ }
3357
+ else {
3358
+ validation.warnings.push('No page properties configured (chrome_tab, chrome_main)');
3359
+ }
3360
+ }
3361
+ else {
3362
+ validation.issues.push('Experience record not found');
3363
+ }
3364
+ }
3365
+ // Performance recommendations
3366
+ if (args.check_performance && validation.score > 50) {
3367
+ validation.recommendations.push('Consider enabling caching for better performance');
3368
+ validation.recommendations.push('Add loading indicators for better user experience');
3369
+ }
3370
+ // Security recommendations
3371
+ if (args.check_security) {
3372
+ validation.recommendations.push('Review access controls and role requirements');
3373
+ validation.recommendations.push('Validate data privacy settings for workspace');
3374
+ }
3375
+ validation.score = Math.min(100, validation.score);
3376
+ this.logger.info(`āœ… Workspace validation completed - Score: ${validation.score}/100`);
3377
+ return {
3378
+ success: true,
3379
+ validation: validation,
3380
+ grade: validation.score >= 80 ? 'Excellent' : validation.score >= 60 ? 'Good' : validation.score >= 40 ? 'Needs Improvement' : 'Critical Issues',
3381
+ summary: `${validation.issues.length} issues, ${validation.warnings.length} warnings, ${validation.recommendations.length} recommendations`
3382
+ };
3383
+ }
3384
+ catch (error) {
3385
+ this.logger.error('Failed to validate workspace configuration:', error);
3386
+ throw error;
3387
+ }
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
+ }
3599
+ /**
3600
+ * CONFIGURABLE AGENT WORKSPACE: Create using UX App architecture
3601
+ */
3602
+ async snow_create_configurable_agent_workspace(args) {
3603
+ try {
3604
+ this.logger.info(`Creating Configurable Agent Workspace: ${args.name}`);
3605
+ // Check if Agent Workspace plugin is available
3606
+ const awCheck = await this.client.searchRecords('sys_ux_screen_type', '', 1);
3607
+ if (!awCheck.success) {
3608
+ return {
3609
+ success: false,
3610
+ error: 'Agent Workspace plugin is not available in this ServiceNow instance.',
3611
+ suggestion: 'Install Agent Workspace plugin from ServiceNow Store',
3612
+ plugin_required: 'Agent Workspace',
3613
+ licensing_note: 'Agent Workspace requires additional ServiceNow licensing'
3614
+ };
3615
+ }
3616
+ const results = {
3617
+ workspace_name: args.name,
3618
+ workspace_type: 'Configurable Agent Workspace',
3619
+ steps_completed: [],
3620
+ sys_ids: {}
3621
+ };
3622
+ // Step 1: Create UX App Route
3623
+ const cleanRoute = this.generateWorkspaceUrl(args.name);
3624
+ const appRouteData = {
3625
+ route: `/${cleanRoute}`,
3626
+ name: args.name,
3627
+ title: args.name,
3628
+ description: args.description || `Configurable Agent Workspace: ${args.name}`,
3629
+ application: args.application || 'global',
3630
+ route_type: 'workspace',
3631
+ active: true
3632
+ };
3633
+ const appRouteResult = await this.client.createRecord('sys_ux_app_route', appRouteData);
3634
+ if (!appRouteResult.success) {
3635
+ return {
3636
+ success: false,
3637
+ error: `UX App Route creation failed: ${appRouteResult.error}`,
3638
+ suggestion: 'Check Agent Workspace permissions and licensing'
3639
+ };
3640
+ }
3641
+ results.steps_completed.push('UX App Route Created');
3642
+ results.sys_ids.app_route_sys_id = appRouteResult.data.result.sys_id;
3643
+ // Step 2: Create Screen Collections for each table
3644
+ if (args.tables && args.tables.length > 0) {
3645
+ const screenTypes = [];
3646
+ for (const table of args.tables) {
3647
+ const screenTypeData = {
3648
+ name: `${args.name} - ${this.capitalizeTableName(table)}`,
3649
+ table: table,
3650
+ workspace_route: appRouteResult.data.result.sys_id,
3651
+ active: true
3652
+ };
3653
+ const screenTypeResult = await this.client.createRecord('sys_ux_screen_type', screenTypeData);
3654
+ if (screenTypeResult.success) {
3655
+ screenTypes.push({ table: table, sys_id: screenTypeResult.data.result.sys_id });
3656
+ }
3657
+ }
3658
+ results.steps_completed.push('Screen Collections Created');
3659
+ results.sys_ids.screen_types = screenTypes;
3660
+ }
3661
+ this.logger.info(`āœ… Configurable Agent Workspace created successfully`);
3662
+ return {
3663
+ success: true,
3664
+ workspace_name: args.name,
3665
+ workspace_type: 'Configurable Agent Workspace',
3666
+ steps_completed: results.steps_completed,
3667
+ sys_ids: results.sys_ids,
3668
+ workspace_url: `/now/workspace/${cleanRoute}`,
3669
+ message: `Configurable Agent Workspace '${args.name}' created successfully`,
3670
+ summary: `UX App Route → Screen Collections → Ready for agent use`
2940
3671
  };
2941
3672
  }
2942
3673
  catch (error) {
2943
- this.logger.error('Failed to create complete workspace:', error);
3674
+ this.logger.error('Failed to create Configurable Agent Workspace:', error);
2944
3675
  throw error;
2945
3676
  }
2946
3677
  }
@@ -2971,6 +3702,141 @@ ${configList}${layoutsText}${offlineText}
2971
3702
  .replace(/^-|-$/g, '') // Trim leading/trailing hyphens
2972
3703
  .substring(0, 80); // Max 80 chars (ServiceNow field limit)
2973
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
+ }
2974
3840
  /**
2975
3841
  * Validate workspace configuration (fix from user feedback)
2976
3842
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "4.5.47",
4
- "description": "Conversational ServiceNow development platform using Claude Code. Multi-agent orchestration with 20+ MCP servers providing 240+ ServiceNow tools including complete 6-step UX Workspace creation workflow.",
3
+ "version": "4.5.49",
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",
7
7
  "bin": {
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
6
6
  <title>Snow-Flow | Conversational ServiceNow Development Platform</title>
7
- <meta name="description" content="Snow-Flow: Conversational ServiceNow development platform using Claude Code. Multi-agent orchestration with 20+ MCP servers providing 240+ ServiceNow tools including complete 6-step UX Workspace creation workflow and UI Builder integration.">
7
+ <meta name="description" content="Snow-Flow: Conversational ServiceNow development platform using Claude Code. Multi-agent orchestration with 20+ MCP servers providing 245+ ServiceNow tools including complete 6-step UX Workspace creation workflow and UI Builder integration.">
8
8
 
9
9
  <!-- Modern CSS -->
10
10
  <link rel="stylesheet" href="css/style.css">