snow-flow 1.3.0 → 1.3.2

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.
Files changed (42) hide show
  1. package/.claude-flow/queen/queen-memory.db +0 -0
  2. package/.env.example +249 -14
  3. package/CLAUDE.md +185 -24
  4. package/README.md +55 -5
  5. package/dist/api/error-handling.js +898 -4
  6. package/dist/api/performance-optimizer.js +3 -2
  7. package/dist/cli.js +590 -200
  8. package/dist/config/snow-flow-config.js +320 -8
  9. package/dist/health/system-health.js +288 -21
  10. package/dist/mcp/base-mcp-server.js +2 -0
  11. package/dist/mcp/http-transport-wrapper.js +65 -4
  12. package/dist/mcp/servicenow-automation-mcp-refactored.js +90 -9
  13. package/dist/mcp/servicenow-deployment-mcp-refactored.js +151 -2
  14. package/dist/mcp/servicenow-deployment-mcp.js +828 -15
  15. package/dist/mcp/servicenow-integration-mcp-refactored.js +100 -9
  16. package/dist/mcp/servicenow-intelligent-mcp.js +198 -7
  17. package/dist/mcp/servicenow-memory-mcp.js +2 -1
  18. package/dist/mcp/servicenow-operations-mcp-refactored.js +3 -2
  19. package/dist/mcp/servicenow-xml-flow-mcp.js +671 -0
  20. package/dist/mcp/shared/base-mcp-server.js +1356 -8
  21. package/dist/mcp/shared/mcp-resource-manager.js +304 -0
  22. package/dist/queen/parallel-agent-engine.js +26 -8
  23. package/dist/queen/servicenow-queen.js +47 -44
  24. package/dist/sparc/sparc-help.js +37 -26
  25. package/dist/sparc/team-sparc.js +60 -16
  26. package/dist/utils/action-type-cache.js +2 -1
  27. package/dist/utils/mcp-config-manager.js +7 -3
  28. package/dist/utils/mcp-server-manager.js +7 -3
  29. package/dist/utils/servicenow-client.js +134 -107
  30. package/dist/utils/servicenow-id-generator.js +171 -0
  31. package/dist/utils/snow-oauth.js +13 -8
  32. package/dist/utils/widget-template-generator.js +1690 -0
  33. package/dist/utils/xml-first-flow-generator.js +473 -0
  34. package/dist/version.js +7 -1
  35. package/flow-update-sets/flow_build_automated_approval_flow_with_notifications_flow.xml +203 -0
  36. package/flow-update-sets/flow_create_approval_flow_for_equipment_requests_flow.xml +206 -0
  37. package/flow-update-sets/flow_create_equipment_approval_flow_with_manager_approv_flow.xml +254 -0
  38. package/flow-update-sets/iphone_15_pro_approval_flow.xml +203 -0
  39. package/flow-update-sets/test_iphone_approval_flow_flow.xml +303 -0
  40. package/package.json +2 -1
  41. package/test-config.js +55 -0
  42. package/test-real-monitoring.js +184 -0
@@ -12,13 +12,17 @@ exports.ServiceNowClient = void 0;
12
12
  const axios_1 = __importDefault(require("axios"));
13
13
  const snow_oauth_1 = require("./snow-oauth");
14
14
  const action_type_cache_1 = require("./action-type-cache");
15
+ const snow_flow_config_js_1 = require("../config/snow-flow-config.js");
16
+ const widget_template_generator_js_1 = require("./widget-template-generator.js");
17
+ const logger_1 = require("./logger");
15
18
  const flow_structure_builder_1 = require("./flow-structure-builder");
16
19
  class ServiceNowClient {
17
20
  constructor() {
18
21
  this.credentials = null;
22
+ this.logger = new logger_1.Logger('ServiceNowClient');
19
23
  this.oauth = new snow_oauth_1.ServiceNowOAuth();
20
24
  this.client = axios_1.default.create({
21
- timeout: 30000,
25
+ timeout: snow_flow_config_js_1.snowFlowConfig.servicenow.timeout,
22
26
  headers: {
23
27
  'Content-Type': 'application/json',
24
28
  'Accept': 'application/json'
@@ -27,8 +31,8 @@ class ServiceNowClient {
27
31
  // 🔧 CRITICAL FIX: Add makeRequest method to Axios instance to fix phantom calls
28
32
  // Some code expects makeRequest to exist on this.client (the Axios instance)
29
33
  this.client.makeRequest = async (config) => {
30
- console.log('🔧 AXIOS makeRequest called! Config:', config);
31
- console.log('🔧 Routing to appropriate HTTP method...');
34
+ this.logger.debug('🔧 AXIOS makeRequest called! Config:', config);
35
+ this.logger.debug('🔧 Routing to appropriate HTTP method...');
32
36
  // Route to the appropriate Axios method based on the request config
33
37
  const method = (config.method || 'GET').toLowerCase();
34
38
  const url = config.url || config.endpoint;
@@ -72,10 +76,10 @@ class ServiceNowClient {
72
76
  // Check if this is a 401 error and we haven't already tried to refresh
73
77
  if (error.response?.status === 401 && !originalRequest._retry) {
74
78
  originalRequest._retry = true;
75
- console.log('🔄 Received 401 error, attempting token refresh...');
79
+ this.logger.info('🔄 Received 401 error, attempting token refresh...');
76
80
  const refreshResult = await this.oauth.refreshAccessToken();
77
81
  if (refreshResult.success && refreshResult.accessToken) {
78
- console.log('✅ Token refreshed successfully, retrying request...');
82
+ this.logger.info('✅ Token refreshed successfully, retrying request...');
79
83
  // Update local credentials
80
84
  if (this.credentials) {
81
85
  this.credentials.accessToken = refreshResult.accessToken;
@@ -87,7 +91,7 @@ class ServiceNowClient {
87
91
  }
88
92
  else {
89
93
  console.error('❌ Token refresh failed:', refreshResult.error);
90
- console.log('💡 Please run "snow-flow auth login" to re-authenticate');
94
+ this.logger.warn('💡 Please run "snow-flow auth login" to re-authenticate');
91
95
  }
92
96
  }
93
97
  // Log other errors for debugging
@@ -147,7 +151,7 @@ class ServiceNowClient {
147
151
  // Try to refresh the token
148
152
  const refreshResult = await this.oauth.refreshAccessToken();
149
153
  if (refreshResult.success && refreshResult.accessToken) {
150
- console.log('✅ Token refreshed successfully');
154
+ this.logger.info('✅ Token refreshed successfully');
151
155
  // Update local credentials
152
156
  this.credentials.accessToken = refreshResult.accessToken;
153
157
  return; // Success!
@@ -175,10 +179,10 @@ class ServiceNowClient {
175
179
  const fiveMinutesFromNow = new Date(now.getTime() + 5 * 60 * 1000);
176
180
  // If token expires in the next 5 minutes, refresh it
177
181
  if (expiresAt <= fiveMinutesFromNow) {
178
- console.log('🔄 Token expiring soon, refreshing proactively...');
182
+ this.logger.info('🔄 Token expiring soon, refreshing proactively...');
179
183
  const refreshResult = await this.oauth.refreshAccessToken();
180
184
  if (refreshResult.success) {
181
- console.log('✅ Token refreshed proactively');
185
+ this.logger.info('✅ Token refreshed proactively');
182
186
  if (this.credentials && refreshResult.accessToken) {
183
187
  this.credentials.accessToken = refreshResult.accessToken;
184
188
  }
@@ -290,7 +294,7 @@ class ServiceNowClient {
290
294
  ];
291
295
  for (const test of tests) {
292
296
  try {
293
- console.log(`Running diagnostic: ${test.name}...`);
297
+ this.logger.info(`Running diagnostic: ${test.name}...`);
294
298
  const result = await test.test();
295
299
  diagnostics.tests[test.name] = {
296
300
  status: '✅ PASS',
@@ -412,8 +416,8 @@ class ServiceNowClient {
412
416
  */
413
417
  async createWidget(widget) {
414
418
  try {
415
- console.log('🎨 Creating ServiceNow widget...');
416
- console.log(`📋 Widget Name: ${widget.name}`);
419
+ this.logger.info('🎨 Creating ServiceNow widget...');
420
+ this.logger.info(`📋 Widget Name: ${widget.name}`);
417
421
  // Add pre-deployment validation for widgets
418
422
  if (!widget.name || widget.name.trim() === '') {
419
423
  throw new Error('Widget name is required');
@@ -422,7 +426,30 @@ class ServiceNowClient {
422
426
  throw new Error('Widget title is required');
423
427
  }
424
428
  if (!widget.template || widget.template.trim() === '') {
425
- console.warn('⚠️ Widget has no template content - this may result in an empty widget');
429
+ console.warn('⚠️ Widget has no template content - generating functional template automatically');
430
+ // Generate a functional template instead of deploying an empty widget
431
+ const generatedWidget = widget_template_generator_js_1.widgetTemplateGenerator.generateWidget({
432
+ title: widget.title,
433
+ instruction: widget.description || widget.name || 'auto-generated widget',
434
+ type: 'info', // Default to info widget for auto-generated templates
435
+ theme: 'default',
436
+ responsive: true
437
+ });
438
+ // Apply generated components to the widget
439
+ widget.template = generatedWidget.template;
440
+ if (!widget.css || widget.css.trim() === '') {
441
+ widget.css = generatedWidget.css;
442
+ }
443
+ if (!widget.client_script || widget.client_script.trim() === '') {
444
+ widget.client_script = generatedWidget.clientScript;
445
+ }
446
+ if (!widget.server_script || widget.server_script.trim() === '') {
447
+ widget.server_script = generatedWidget.serverScript;
448
+ }
449
+ if (!widget.option_schema || widget.option_schema.trim() === '' || widget.option_schema === '[]') {
450
+ widget.option_schema = generatedWidget.optionSchema;
451
+ }
452
+ this.logger.info('✅ Generated functional widget template automatically');
426
453
  }
427
454
  // Ensure we have credentials before making the API call
428
455
  await this.ensureAuthenticated();
@@ -440,8 +467,8 @@ class ServiceNowClient {
440
467
  has_preview: widget.has_preview || false,
441
468
  category: widget.category || 'custom'
442
469
  });
443
- console.log('✅ Widget created successfully!');
444
- console.log(`🆔 Widget ID: ${response.data.result.sys_id}`);
470
+ this.logger.info('✅ Widget created successfully!');
471
+ this.logger.info(`🆔 Widget ID: ${response.data.result.sys_id}`);
445
472
  // Add post-deployment verification
446
473
  await this.verifyDeployment(response.data.result.sys_id, 'widget');
447
474
  return {
@@ -462,7 +489,7 @@ class ServiceNowClient {
462
489
  */
463
490
  async updateWidget(sysId, widget) {
464
491
  try {
465
- console.log(`🔄 Updating widget ${sysId}...`);
492
+ this.logger.info(`🔄 Updating widget ${sysId}...`);
466
493
  // Ensure we have credentials before making the API call
467
494
  await this.ensureAuthenticated();
468
495
  // Map fields for Service Portal widget API
@@ -472,7 +499,7 @@ class ServiceNowClient {
472
499
  delete mappedWidget.server_script;
473
500
  }
474
501
  const response = await this.client.patch(`${this.getBaseUrl()}/api/now/table/sp_widget/${sysId}`, mappedWidget);
475
- console.log('✅ Widget updated successfully!');
502
+ this.logger.info('✅ Widget updated successfully!');
476
503
  return {
477
504
  success: true,
478
505
  data: response.data.result
@@ -517,8 +544,8 @@ class ServiceNowClient {
517
544
  */
518
545
  async createWorkflow(workflow) {
519
546
  try {
520
- console.log('🔄 Creating ServiceNow workflow...');
521
- console.log(`📋 Workflow Name: ${workflow.name}`);
547
+ this.logger.info('🔄 Creating ServiceNow workflow...');
548
+ this.logger.info(`📋 Workflow Name: ${workflow.name}`);
522
549
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/wf_workflow`, {
523
550
  name: workflow.name,
524
551
  description: workflow.description,
@@ -527,8 +554,8 @@ class ServiceNowClient {
527
554
  table: workflow.table || '',
528
555
  condition: workflow.condition || ''
529
556
  });
530
- console.log('✅ Workflow created successfully!');
531
- console.log(`🆔 Workflow ID: ${response.data.result.sys_id}`);
557
+ this.logger.info('✅ Workflow created successfully!');
558
+ this.logger.info(`🆔 Workflow ID: ${response.data.result.sys_id}`);
532
559
  return {
533
560
  success: true,
534
561
  data: response.data.result
@@ -547,8 +574,8 @@ class ServiceNowClient {
547
574
  */
548
575
  async createApplication(application) {
549
576
  try {
550
- console.log('🏗️ Creating ServiceNow application...');
551
- console.log(`📋 Application Name: ${application.name}`);
577
+ this.logger.info('🏗️ Creating ServiceNow application...');
578
+ this.logger.info(`📋 Application Name: ${application.name}`);
552
579
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_app`, {
553
580
  name: application.name,
554
581
  scope: application.scope,
@@ -561,8 +588,8 @@ class ServiceNowClient {
561
588
  logo: application.logo || '',
562
589
  active: application.active
563
590
  });
564
- console.log('✅ Application created successfully!');
565
- console.log(`🆔 Application ID: ${response.data.result.sys_id}`);
591
+ this.logger.info('✅ Application created successfully!');
592
+ this.logger.info(`🆔 Application ID: ${response.data.result.sys_id}`);
566
593
  return {
567
594
  success: true,
568
595
  data: response.data.result
@@ -581,12 +608,12 @@ class ServiceNowClient {
581
608
  */
582
609
  async executeScript(script) {
583
610
  try {
584
- console.log('⚡ Executing ServiceNow script...');
611
+ this.logger.info('⚡ Executing ServiceNow script...');
585
612
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_script_execution`, {
586
613
  script: script,
587
614
  type: 'server'
588
615
  });
589
- console.log('✅ Script executed successfully!');
616
+ this.logger.info('✅ Script executed successfully!');
590
617
  return {
591
618
  success: true,
592
619
  data: response.data.result
@@ -675,7 +702,7 @@ class ServiceNowClient {
675
702
  }
676
703
  }
677
704
  catch (error) {
678
- console.log('Could not fetch flow defaults, using minimal defaults');
705
+ this.logger.warn('Could not fetch flow defaults, using minimal defaults');
679
706
  }
680
707
  // Return minimal defaults if we can't get from ServiceNow
681
708
  return {
@@ -831,14 +858,14 @@ class ServiceNowClient {
831
858
  */
832
859
  async searchFlowActions(searchTerm) {
833
860
  try {
834
- console.log(`🔍 Searching for flow actions: ${searchTerm}`);
861
+ this.logger.info(`🔍 Searching for flow actions: ${searchTerm}`);
835
862
  // Search in sys_hub_action_type_base for available action types
836
863
  const results = await this.searchRecords('sys_hub_action_type_base', `nameLIKE${searchTerm}^ORlabelLIKE${searchTerm}^ORdescriptionLIKE${searchTerm}`, 20);
837
864
  // Also search in sys_hub_action_instance for existing actions
838
865
  const instanceResults = await this.searchRecords('sys_hub_action_instance', `action_nameLIKE${searchTerm}^ORdescriptionLIKE${searchTerm}`, 10);
839
866
  const actionTypes = results.success ? results.data.result : [];
840
867
  const actionInstances = instanceResults.success ? instanceResults.data.result : [];
841
- console.log(`✅ Found ${actionTypes.length} action types and ${actionInstances.length} action instances`);
868
+ this.logger.info(`✅ Found ${actionTypes.length} action types and ${actionInstances.length} action instances`);
842
869
  return {
843
870
  actionTypes,
844
871
  actionInstances
@@ -960,7 +987,7 @@ snow_create_flow({
960
987
  `);
961
988
  }
962
989
  else {
963
- console.log(`✅ ${expectedType} has ${activities.length} activities`);
990
+ this.logger.info(`✅ ${expectedType} has ${activities.length} activities`);
964
991
  }
965
992
  }
966
993
  else if (expectedType === 'widget') {
@@ -969,7 +996,7 @@ snow_create_flow({
969
996
  console.warn(`⚠️ Widget deployed but appears to have no content: ${artifact.name}`);
970
997
  }
971
998
  }
972
- console.log(`✅ Deployment verified: ${artifact.name} (${sysId})`);
999
+ this.logger.info(`✅ Deployment verified: ${artifact.name} (${sysId})`);
973
1000
  }
974
1001
  catch (error) {
975
1002
  console.error(`❌ Deployment verification failed for ${sysId}:`, error);
@@ -1008,8 +1035,8 @@ snow_create_flow({
1008
1035
  */
1009
1036
  async createFlowWithStructureBuilder(flowDefinition) {
1010
1037
  try {
1011
- console.log('🏗️ Creating flow with structure builder...');
1012
- console.log(`📋 Flow: ${flowDefinition.name}`);
1038
+ this.logger.info('🏗️ Creating flow with structure builder...');
1039
+ this.logger.info(`📋 Flow: ${flowDefinition.name}`);
1013
1040
  await this.ensureAuthenticated();
1014
1041
  // Generate all flow components with proper structure
1015
1042
  const components = (0, flow_structure_builder_1.generateFlowComponents)(flowDefinition);
@@ -1023,32 +1050,32 @@ snow_create_flow({
1023
1050
  validation.warnings.forEach(warning => console.warn(` • ${warning}`));
1024
1051
  }
1025
1052
  // Deploy all components in correct order
1026
- console.log('🚀 Deploying flow components...');
1053
+ this.logger.info('🚀 Deploying flow components...');
1027
1054
  // 1. Create main flow record
1028
1055
  const flowResponse = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow`, components.flowRecord);
1029
1056
  if (!flowResponse.data?.result) {
1030
1057
  throw new Error('Failed to create flow record');
1031
1058
  }
1032
1059
  const flowSysId = flowResponse.data.result.sys_id;
1033
- console.log(`✅ Flow record created: ${flowSysId}`);
1060
+ this.logger.info(`✅ Flow record created: ${flowSysId}`);
1034
1061
  // 2. Create trigger instance
1035
1062
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_trigger_instance`, components.triggerInstance);
1036
- console.log(`✅ Trigger created: ${components.triggerInstance.sys_id}`);
1063
+ this.logger.info(`✅ Trigger created: ${components.triggerInstance.sys_id}`);
1037
1064
  // 3. Create action instances
1038
1065
  for (const action of components.actionInstances) {
1039
1066
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_instance`, action);
1040
1067
  }
1041
- console.log(`✅ Created ${components.actionInstances.length} action instances`);
1068
+ this.logger.info(`✅ Created ${components.actionInstances.length} action instances`);
1042
1069
  // 4. Create logic chain (connections)
1043
1070
  for (const logic of components.logicChain) {
1044
1071
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_logic`, logic);
1045
1072
  }
1046
- console.log(`✅ Created logic chain with ${components.logicChain.length} connections`);
1073
+ this.logger.info(`✅ Created logic chain with ${components.logicChain.length} connections`);
1047
1074
  // 5. Create variables
1048
1075
  for (const variable of components.variables) {
1049
1076
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variable);
1050
1077
  }
1051
- console.log(`✅ Created ${components.variables.length} flow variables`);
1078
+ this.logger.info(`✅ Created ${components.variables.length} flow variables`);
1052
1079
  // Verify deployment
1053
1080
  await this.verifyDeployment(flowSysId, 'flow');
1054
1081
  const credentials = await this.oauth.loadCredentials();
@@ -1085,10 +1112,10 @@ snow_create_flow({
1085
1112
  */
1086
1113
  async createFlow(flow) {
1087
1114
  try {
1088
- console.log('🔄 Creating Flow Designer flow...');
1089
- console.log(`📋 Flow: ${flow.name}`);
1115
+ this.logger.info('🔄 Creating Flow Designer flow...');
1116
+ this.logger.info(`📋 Flow: ${flow.name}`);
1090
1117
  // 🔧 CRITICAL DEBUG: Check if makeRequest exists on this instance
1091
- console.log('🔧 CRITICAL DEBUG - Client methods check:', {
1118
+ this.logger.debug('🔧 CRITICAL DEBUG - Client methods check:', {
1092
1119
  hasCreateFlow: typeof this.createFlow === 'function',
1093
1120
  hasMakeRequest: typeof this.makeRequest === 'function',
1094
1121
  clientPrototype: Object.getOwnPropertyNames(Object.getPrototypeOf(this)),
@@ -1181,37 +1208,37 @@ snow_create_flow({
1181
1208
  throw new Error('No response data from flow creation');
1182
1209
  }
1183
1210
  const flowId = response.data.result.sys_id;
1184
- console.log('✅ Flow created successfully with complete snapshot!');
1185
- console.log(`🆔 Flow sys_id: ${flowId}`);
1211
+ this.logger.info('✅ Flow created successfully with complete snapshot!');
1212
+ this.logger.info(`🆔 Flow sys_id: ${flowId}`);
1186
1213
  // 🔧 CRITICAL FIX: Create action instances after flow creation
1187
1214
  // While the flow definition contains the structure, ServiceNow also needs
1188
1215
  // actual sys_hub_action_instance records for proper execution
1189
- console.log('📋 Flow components included in definition:');
1190
- console.log(`- Trigger: ${flowDefinition.trigger.type}`);
1191
- console.log(`- Activities: ${flowDefinition.activities.length}`);
1192
- console.log(`- Inputs: ${flowDefinition.inputs.length}`);
1193
- console.log(`- Outputs: ${flowDefinition.outputs.length}`);
1216
+ this.logger.info('📋 Flow components included in definition:');
1217
+ this.logger.info(`- Trigger: ${flowDefinition.trigger.type}`);
1218
+ this.logger.info(`- Activities: ${flowDefinition.activities.length}`);
1219
+ this.logger.info(`- Inputs: ${flowDefinition.inputs.length}`);
1220
+ this.logger.info(`- Outputs: ${flowDefinition.outputs.length}`);
1194
1221
  // Create action instances for each activity
1195
1222
  if (activitiesToProcess.length > 0) {
1196
- console.log('🔧 Creating action instances for activities...');
1223
+ this.logger.info('🔧 Creating action instances for activities...');
1197
1224
  for (let i = 0; i < activitiesToProcess.length; i++) {
1198
1225
  const activity = activitiesToProcess[i];
1199
1226
  try {
1200
1227
  await this.createFlowActionInstance(flowId, activity, (i + 1) * 100);
1201
- console.log(`✅ Action instance created: ${activity.name}`);
1228
+ this.logger.info(`✅ Action instance created: ${activity.name}`);
1202
1229
  }
1203
1230
  catch (activityError) {
1204
1231
  console.warn(`⚠️ Failed to create action instance ${activity.name}:`, activityError);
1205
1232
  // Continue with other activities even if one fails
1206
1233
  }
1207
1234
  }
1208
- console.log(`✅ Created ${activitiesToProcess.length} action instances`);
1235
+ this.logger.info(`✅ Created ${activitiesToProcess.length} action instances`);
1209
1236
  }
1210
1237
  // 🔧 NEW: Only need to activate the flow since it already has complete definition
1211
1238
  try {
1212
- console.log('⚡ Activating flow...');
1239
+ this.logger.info('⚡ Activating flow...');
1213
1240
  await this.activateFlow(flowId);
1214
- console.log('✅ Flow activated successfully!');
1241
+ this.logger.info('✅ Flow activated successfully!');
1215
1242
  }
1216
1243
  catch (activationError) {
1217
1244
  console.warn('⚠️ Flow activation failed:', activationError);
@@ -1219,7 +1246,7 @@ snow_create_flow({
1219
1246
  }
1220
1247
  // 🔧 CRITICAL FIX: Create actual ServiceNow records after flow creation
1221
1248
  // The JSON definition alone is not enough - we need component records
1222
- console.log('🔧 Creating actual ServiceNow flow component records...');
1249
+ this.logger.info('🔧 Creating actual ServiceNow flow component records...');
1223
1250
  try {
1224
1251
  // 1. Create trigger instance if trigger is specified
1225
1252
  if (flow.trigger_type && flow.trigger_type !== 'manual') {
@@ -1229,7 +1256,7 @@ snow_create_flow({
1229
1256
  condition: flow.trigger_condition || flow.condition || ''
1230
1257
  };
1231
1258
  const triggerResult = await this.createFlowTrigger(flowId, triggerData);
1232
- console.log(`✅ Trigger created: ${triggerResult.sys_id}`);
1259
+ this.logger.info(`✅ Trigger created: ${triggerResult.sys_id}`);
1233
1260
  }
1234
1261
  // 2. Create action instances for each activity
1235
1262
  if (activitiesToProcess && activitiesToProcess.length > 0) {
@@ -1240,7 +1267,7 @@ snow_create_flow({
1240
1267
  try {
1241
1268
  const actionResult = await this.createFlowActionInstance(flowId, activity, order);
1242
1269
  actionResults.push(actionResult);
1243
- console.log(`✅ Action created: ${activity.name} (${actionResult.sys_id})`);
1270
+ this.logger.info(`✅ Action created: ${activity.name} (${actionResult.sys_id})`);
1244
1271
  }
1245
1272
  catch (actionError) {
1246
1273
  console.warn(`⚠️ Failed to create action ${activity.name}:`, actionError);
@@ -1258,7 +1285,7 @@ snow_create_flow({
1258
1285
  };
1259
1286
  try {
1260
1287
  const logicResult = await this.createFlowLogic(flowId, logicData);
1261
- console.log(`✅ Flow logic created: ${logicResult.sys_id}`);
1288
+ this.logger.info(`✅ Flow logic created: ${logicResult.sys_id}`);
1262
1289
  }
1263
1290
  catch (logicError) {
1264
1291
  console.warn(`⚠️ Failed to create flow logic for ${action.action_name}:`, logicError);
@@ -1266,7 +1293,7 @@ snow_create_flow({
1266
1293
  }
1267
1294
  }
1268
1295
  }
1269
- console.log('✅ All flow component records created successfully!');
1296
+ this.logger.info('✅ All flow component records created successfully!');
1270
1297
  }
1271
1298
  catch (componentError) {
1272
1299
  console.warn('⚠️ Some flow components may not have been created properly:', componentError);
@@ -1359,8 +1386,8 @@ snow_create_flow({
1359
1386
  */
1360
1387
  async createSubflow(subflow) {
1361
1388
  try {
1362
- console.log('🔄 Creating Subflow...');
1363
- console.log(`📋 Subflow: ${subflow.name}`);
1389
+ this.logger.info('🔄 Creating Subflow...');
1390
+ this.logger.info(`📋 Subflow: ${subflow.name}`);
1364
1391
  // Add pre-deployment validation
1365
1392
  this.validateFlowBeforeDeployment(subflow);
1366
1393
  // Ensure Update Set
@@ -1426,8 +1453,8 @@ snow_create_flow({
1426
1453
  */
1427
1454
  async createFlowAction(action) {
1428
1455
  try {
1429
- console.log('⚡ Creating Flow Action...');
1430
- console.log(`📋 Action: ${action.name}`);
1456
+ this.logger.info('⚡ Creating Flow Action...');
1457
+ this.logger.info(`📋 Action: ${action.name}`);
1431
1458
  // Add pre-deployment validation (adapted for actions)
1432
1459
  if (!action.name || action.name.trim() === '') {
1433
1460
  throw new Error('Flow Action name is required');
@@ -1454,7 +1481,7 @@ snow_create_flow({
1454
1481
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_type_definition`, actionData);
1455
1482
  // Add basic verification for action creation
1456
1483
  if (response.data.result?.sys_id) {
1457
- console.log(`✅ Flow Action created: ${action.name} (${response.data.result.sys_id})`);
1484
+ this.logger.info(`✅ Flow Action created: ${action.name} (${response.data.result.sys_id})`);
1458
1485
  }
1459
1486
  return {
1460
1487
  success: true,
@@ -1474,7 +1501,7 @@ snow_create_flow({
1474
1501
  */
1475
1502
  async createFlowActionPrivate(flowId, action, order) {
1476
1503
  try {
1477
- console.log(`Creating flow action: ${action.type} - ${action.name}`);
1504
+ this.logger.info(`Creating flow action: ${action.type} - ${action.name}`);
1478
1505
  // If we have a discovered action type, use it
1479
1506
  let actionTypeId = action.action_type_id;
1480
1507
  // If no specific action type provided, search for one
@@ -1482,7 +1509,7 @@ snow_create_flow({
1482
1509
  const searchResults = await this.searchFlowActions(action.type);
1483
1510
  if (searchResults.actionTypes && searchResults.actionTypes.length > 0) {
1484
1511
  actionTypeId = searchResults.actionTypes[0].sys_id;
1485
- console.log(`📋 Using discovered action type: ${searchResults.actionTypes[0].name}`);
1512
+ this.logger.info(`📋 Using discovered action type: ${searchResults.actionTypes[0].name}`);
1486
1513
  }
1487
1514
  else {
1488
1515
  // Fallback to common action types
@@ -1495,7 +1522,7 @@ snow_create_flow({
1495
1522
  'approval': 'com.glideapp.servicenow_common.approval'
1496
1523
  };
1497
1524
  actionTypeId = fallbackMap[action.type] || 'com.glideapp.servicenow_common.script';
1498
- console.log(`📋 Using fallback action type: ${actionTypeId}`);
1525
+ this.logger.info(`📋 Using fallback action type: ${actionTypeId}`);
1499
1526
  }
1500
1527
  }
1501
1528
  // Get action details to understand inputs/outputs
@@ -1513,7 +1540,7 @@ snow_create_flow({
1513
1540
  configuration: this.buildActionConfiguration(action)
1514
1541
  };
1515
1542
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_instance`, actionData);
1516
- console.log(`✅ Flow action created: ${action.name}`);
1543
+ this.logger.info(`✅ Flow action created: ${action.name}`);
1517
1544
  return response.data.result;
1518
1545
  }
1519
1546
  catch (error) {
@@ -1677,13 +1704,13 @@ try {
1677
1704
  description: `Auto-generated trigger for Flow Designer flow: ${flowId}`
1678
1705
  };
1679
1706
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_trigger`, sysTriggerData);
1680
- console.log('✅ sys_trigger record created for proper flow execution');
1707
+ this.logger.info('✅ sys_trigger record created for proper flow execution');
1681
1708
  }
1682
1709
  catch (sysTriggerError) {
1683
1710
  console.warn('Could not create sys_trigger record, flow may not trigger properly:', sysTriggerError);
1684
1711
  }
1685
1712
  }
1686
- console.log('✅ Trigger created successfully');
1713
+ this.logger.info('✅ Trigger created successfully');
1687
1714
  return response.data.result;
1688
1715
  }
1689
1716
  catch (error) {
@@ -1696,7 +1723,7 @@ try {
1696
1723
  */
1697
1724
  async createFlowVariables(flowId, flow) {
1698
1725
  try {
1699
- console.log('📋 Creating flow variables...');
1726
+ this.logger.info('📋 Creating flow variables...');
1700
1727
  // Process inputs
1701
1728
  const inputs = flow.inputs || [];
1702
1729
  if (inputs.length > 0) {
@@ -1714,7 +1741,7 @@ try {
1714
1741
  };
1715
1742
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variableData);
1716
1743
  }
1717
- console.log(`✅ Created ${inputs.length} input variables`);
1744
+ this.logger.info(`✅ Created ${inputs.length} input variables`);
1718
1745
  }
1719
1746
  // Process outputs
1720
1747
  const outputs = flow.outputs || [];
@@ -1733,7 +1760,7 @@ try {
1733
1760
  };
1734
1761
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variableData);
1735
1762
  }
1736
- console.log(`✅ Created ${outputs.length} output variables`);
1763
+ this.logger.info(`✅ Created ${outputs.length} output variables`);
1737
1764
  }
1738
1765
  // Extract variables from flow_definition if available
1739
1766
  if (flow.flow_definition) {
@@ -1755,7 +1782,7 @@ try {
1755
1782
  };
1756
1783
  await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_flow_variable`, variableData);
1757
1784
  }
1758
- console.log(`✅ Created ${flowDef.variables.length} flow definition variables`);
1785
+ this.logger.info(`✅ Created ${flowDef.variables.length} flow definition variables`);
1759
1786
  }
1760
1787
  }
1761
1788
  catch (parseError) {
@@ -1773,7 +1800,7 @@ try {
1773
1800
  */
1774
1801
  async createFlowActionInstance(flowId, action, order) {
1775
1802
  try {
1776
- console.log(`Creating action instance: ${action.name}`);
1803
+ this.logger.info(`Creating action instance: ${action.name}`);
1777
1804
  // Map action types to search terms
1778
1805
  const actionSearchMap = {
1779
1806
  'notification': 'Send Email',
@@ -1848,7 +1875,7 @@ try {
1848
1875
  inputs: JSON.stringify(inputs)
1849
1876
  };
1850
1877
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_hub_action_instance`, actionData);
1851
- console.log(`✅ Action created: ${action.name}`);
1878
+ this.logger.info(`✅ Action created: ${action.name}`);
1852
1879
  return response.data.result;
1853
1880
  }
1854
1881
  catch (error) {
@@ -1887,7 +1914,7 @@ try {
1887
1914
  */
1888
1915
  async createScriptInclude(scriptInclude) {
1889
1916
  try {
1890
- console.log('📝 Creating Script Include...');
1917
+ this.logger.info('📝 Creating Script Include...');
1891
1918
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_script_include`, {
1892
1919
  name: scriptInclude.name,
1893
1920
  api_name: scriptInclude.api_name,
@@ -1896,7 +1923,7 @@ try {
1896
1923
  active: scriptInclude.active,
1897
1924
  access: scriptInclude.access || 'public'
1898
1925
  });
1899
- console.log('✅ Script Include created successfully!');
1926
+ this.logger.info('✅ Script Include created successfully!');
1900
1927
  return {
1901
1928
  success: true,
1902
1929
  data: response.data.result
@@ -1915,7 +1942,7 @@ try {
1915
1942
  */
1916
1943
  async createBusinessRule(businessRule) {
1917
1944
  try {
1918
- console.log('📋 Creating Business Rule...');
1945
+ this.logger.info('📋 Creating Business Rule...');
1919
1946
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_script`, {
1920
1947
  name: businessRule.name,
1921
1948
  collection: businessRule.table,
@@ -1926,7 +1953,7 @@ try {
1926
1953
  active: businessRule.active,
1927
1954
  order: businessRule.order || 100
1928
1955
  });
1929
- console.log('✅ Business Rule created successfully!');
1956
+ this.logger.info('✅ Business Rule created successfully!');
1930
1957
  return {
1931
1958
  success: true,
1932
1959
  data: response.data.result
@@ -1945,7 +1972,7 @@ try {
1945
1972
  */
1946
1973
  async createTable(table) {
1947
1974
  try {
1948
- console.log('🗄️ Creating Table...');
1975
+ this.logger.info('🗄️ Creating Table...');
1949
1976
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_db_object`, {
1950
1977
  name: table.name,
1951
1978
  label: table.label,
@@ -1954,7 +1981,7 @@ try {
1954
1981
  access: table.access || 'public',
1955
1982
  create_access_controls: table.create_access_controls !== false
1956
1983
  });
1957
- console.log('✅ Table created successfully!');
1984
+ this.logger.info('✅ Table created successfully!');
1958
1985
  return {
1959
1986
  success: true,
1960
1987
  data: response.data.result
@@ -1973,7 +2000,7 @@ try {
1973
2000
  */
1974
2001
  async createTableField(field) {
1975
2002
  try {
1976
- console.log('📊 Creating Table Field...');
2003
+ this.logger.info('📊 Creating Table Field...');
1977
2004
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_dictionary`, {
1978
2005
  name: `${field.table}.${field.element}`,
1979
2006
  element: field.element,
@@ -1982,7 +2009,7 @@ try {
1982
2009
  max_length: field.max_length || 255,
1983
2010
  active: true
1984
2011
  });
1985
- console.log('✅ Table Field created successfully!');
2012
+ this.logger.info('✅ Table Field created successfully!');
1986
2013
  return {
1987
2014
  success: true,
1988
2015
  data: response.data.result
@@ -2001,7 +2028,7 @@ try {
2001
2028
  */
2002
2029
  async createUpdateSet(updateSet) {
2003
2030
  try {
2004
- console.log('📦 Creating Update Set...');
2031
+ this.logger.info('📦 Creating Update Set...');
2005
2032
  // Ensure we have credentials before making the API call
2006
2033
  await this.ensureAuthenticated();
2007
2034
  const response = await this.client.post(`${this.getBaseUrl()}/api/now/table/sys_update_set`, {
@@ -2011,7 +2038,7 @@ try {
2011
2038
  state: updateSet.state || 'in_progress',
2012
2039
  application: updateSet.application || 'global'
2013
2040
  });
2014
- console.log('✅ Update Set created successfully!');
2041
+ this.logger.info('✅ Update Set created successfully!');
2015
2042
  return {
2016
2043
  success: true,
2017
2044
  data: response.data.result
@@ -2030,7 +2057,7 @@ try {
2030
2057
  */
2031
2058
  async setCurrentUpdateSet(updateSetId) {
2032
2059
  try {
2033
- console.log('🔄 Setting current Update Set...');
2060
+ this.logger.info('🔄 Setting current Update Set...');
2034
2061
  // Ensure we have credentials before making the API call
2035
2062
  await this.ensureAuthenticated();
2036
2063
  // Use the sys_user_preference table to set the current update set
@@ -2056,7 +2083,7 @@ try {
2056
2083
  user: 'javascript:gs.getUserID()'
2057
2084
  });
2058
2085
  }
2059
- console.log('✅ Current Update Set changed successfully!');
2086
+ this.logger.info('✅ Current Update Set changed successfully!');
2060
2087
  return {
2061
2088
  success: true,
2062
2089
  data: response.data.result
@@ -2075,7 +2102,7 @@ try {
2075
2102
  */
2076
2103
  async getCurrentUpdateSet() {
2077
2104
  try {
2078
- console.log('📋 Getting current Update Set...');
2105
+ this.logger.info('📋 Getting current Update Set...');
2079
2106
  // Ensure we have credentials before making the API call
2080
2107
  await this.ensureAuthenticated();
2081
2108
  // Try to get the current update set using sys_user_preference table
@@ -2098,7 +2125,7 @@ try {
2098
2125
  }
2099
2126
  }
2100
2127
  catch (prefError) {
2101
- console.log('⚠️ User preference lookup failed, trying fallback...');
2128
+ this.logger.info('⚠️ User preference lookup failed, trying fallback...');
2102
2129
  }
2103
2130
  // Fallback: Get the most recent in-progress update set for the current user
2104
2131
  const response = await this.client.get(`${this.getBaseUrl()}/api/now/table/sys_update_set`, {
@@ -2132,7 +2159,7 @@ try {
2132
2159
  */
2133
2160
  async getUpdateSet(updateSetId) {
2134
2161
  try {
2135
- console.log(`📋 Getting Update Set ${updateSetId}...`);
2162
+ this.logger.info(`📋 Getting Update Set ${updateSetId}...`);
2136
2163
  // Ensure we have credentials before making the API call
2137
2164
  await this.ensureAuthenticated();
2138
2165
  const response = await this.client.get(`${this.getBaseUrl()}/api/now/table/sys_update_set/${updateSetId}`);
@@ -2154,7 +2181,7 @@ try {
2154
2181
  */
2155
2182
  async listUpdateSets(options) {
2156
2183
  try {
2157
- console.log('📋 Listing Update Sets...');
2184
+ this.logger.info('📋 Listing Update Sets...');
2158
2185
  // Ensure we have credentials before making the API call
2159
2186
  await this.ensureAuthenticated();
2160
2187
  let query = 'sys_created_by=javascript:gs.getUserName()';
@@ -2186,14 +2213,14 @@ try {
2186
2213
  */
2187
2214
  async completeUpdateSet(updateSetId, notes) {
2188
2215
  try {
2189
- console.log('✅ Completing Update Set...');
2216
+ this.logger.info('✅ Completing Update Set...');
2190
2217
  // Ensure we have credentials before making the API call
2191
2218
  await this.ensureAuthenticated();
2192
2219
  const response = await this.client.patch(`${this.getBaseUrl()}/api/now/table/sys_update_set/${updateSetId}`, {
2193
2220
  state: 'complete',
2194
2221
  description: notes ? `${notes}\n\nCompleted: ${new Date().toISOString()}` : undefined
2195
2222
  });
2196
- console.log('✅ Update Set completed successfully!');
2223
+ this.logger.info('✅ Update Set completed successfully!');
2197
2224
  return {
2198
2225
  success: true,
2199
2226
  data: response.data.result
@@ -2212,7 +2239,7 @@ try {
2212
2239
  */
2213
2240
  async activateUpdateSet(updateSetId) {
2214
2241
  try {
2215
- console.log('🔄 Activating Update Set...');
2242
+ this.logger.info('🔄 Activating Update Set...');
2216
2243
  // Set the update set as current
2217
2244
  const result = await this.setCurrentUpdateSet(updateSetId);
2218
2245
  if (result.success) {
@@ -2220,7 +2247,7 @@ try {
2220
2247
  const updateResponse = await this.client.patch(`${this.getBaseUrl()}/api/now/table/sys_update_set/${updateSetId}`, {
2221
2248
  state: 'in_progress'
2222
2249
  });
2223
- console.log('✅ Update Set activated successfully!');
2250
+ this.logger.info('✅ Update Set activated successfully!');
2224
2251
  return {
2225
2252
  success: true,
2226
2253
  data: updateResponse.data.result
@@ -2241,7 +2268,7 @@ try {
2241
2268
  */
2242
2269
  async previewUpdateSet(updateSetId) {
2243
2270
  try {
2244
- console.log('🔍 Previewing Update Set changes...');
2271
+ this.logger.info('🔍 Previewing Update Set changes...');
2245
2272
  // Get Update Set details
2246
2273
  const updateSetResponse = await this.getUpdateSet(updateSetId);
2247
2274
  if (!updateSetResponse.success) {
@@ -2281,12 +2308,12 @@ try {
2281
2308
  // Check if we have a current Update Set
2282
2309
  const currentUpdateSet = await this.getCurrentUpdateSet();
2283
2310
  if (currentUpdateSet.success && currentUpdateSet.data) {
2284
- console.log(`📦 Using existing Update Set: ${currentUpdateSet.data.name}`);
2311
+ this.logger.info(`📦 Using existing Update Set: ${currentUpdateSet.data.name}`);
2285
2312
  return currentUpdateSet;
2286
2313
  }
2287
2314
  // Create a new Update Set if none exists
2288
2315
  const updateSetName = `Snow-Flow Changes ${new Date().toISOString().split('T')[0]}`;
2289
- console.log(`📦 Creating new Update Set: ${updateSetName}`);
2316
+ this.logger.info(`📦 Creating new Update Set: ${updateSetName}`);
2290
2317
  const newUpdateSet = await this.createUpdateSet({
2291
2318
  name: updateSetName,
2292
2319
  description: 'Automated changes from Snow-Flow MCP',
@@ -2308,7 +2335,7 @@ try {
2308
2335
  }
2309
2336
  async exportUpdateSet(updateSetId) {
2310
2337
  try {
2311
- console.log('📤 Exporting Update Set...');
2338
+ this.logger.info('📤 Exporting Update Set...');
2312
2339
  // Get Update Set details first
2313
2340
  const updateSetResponse = await this.getUpdateSet(updateSetId);
2314
2341
  if (!updateSetResponse.success) {
@@ -2345,7 +2372,7 @@ try {
2345
2372
  */
2346
2373
  async debugFlow(flowId) {
2347
2374
  try {
2348
- console.log('🔍 Debugging flow structure...');
2375
+ this.logger.info('🔍 Debugging flow structure...');
2349
2376
  // Get the flow record
2350
2377
  const flowResponse = await this.client.get(`${this.getBaseUrl()}/api/now/table/sys_hub_flow/${flowId}`);
2351
2378
  if (!flowResponse.data.result) {
@@ -2501,17 +2528,17 @@ try {
2501
2528
  * This method provides compatibility for code that expects makeRequest
2502
2529
  */
2503
2530
  async makeRequest(config) {
2504
- console.log('🔧 MAKEQUEST CALLED! Stack trace:', new Error().stack);
2505
- console.log('🔧 TEMP FIX: makeRequest called with config:', config);
2506
- console.log('🔧 This instance constructor:', this.constructor.name);
2507
- console.log('🔧 This instance methods:', Object.getOwnPropertyNames(Object.getPrototypeOf(this)));
2531
+ this.logger.info('🔧 MAKEQUEST CALLED! Stack trace:', new Error().stack);
2532
+ this.logger.info('🔧 TEMP FIX: makeRequest called with config:', config);
2533
+ this.logger.info('🔧 This instance constructor:', this.constructor.name);
2534
+ this.logger.info('🔧 This instance methods:', Object.getOwnPropertyNames(Object.getPrototypeOf(this)));
2508
2535
  try {
2509
2536
  await this.ensureAuthenticated();
2510
2537
  // Route the request to the appropriate HTTP method
2511
2538
  const method = (config.method || 'GET').toLowerCase();
2512
2539
  const url = config.url || config.endpoint;
2513
2540
  const data = config.data || config.body;
2514
- console.log(`🔧 Routing ${method.toUpperCase()} request to: ${url}`);
2541
+ this.logger.info(`🔧 Routing ${method.toUpperCase()} request to: ${url}`);
2515
2542
  switch (method) {
2516
2543
  case 'get':
2517
2544
  return await this.get(url, config.params);