snow-flow 3.0.9 → 3.0.13

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 (302) hide show
  1. package/claude-flow.bat +0 -0
  2. package/claude-flow.ps1 +0 -0
  3. package/dist/mcp/intelligent-reporting-mcp.d.ts +7 -0
  4. package/dist/mcp/intelligent-reporting-mcp.js +379 -0
  5. package/dist/mcp/servicenow-automation-mcp.js +0 -0
  6. package/dist/mcp/servicenow-deployment-mcp.js +0 -0
  7. package/dist/mcp/servicenow-integration-mcp.js +0 -0
  8. package/dist/mcp/servicenow-mcp-server.js +0 -0
  9. package/dist/mcp/servicenow-operations-mcp.js +0 -0
  10. package/dist/mcp/servicenow-platform-development-mcp.js +0 -0
  11. package/dist/mcp/servicenow-progressive-indexer.js +0 -0
  12. package/dist/mcp/servicenow-reporting-analytics-mcp.js +280 -29
  13. package/dist/mcp/servicenow-security-compliance-mcp.js +0 -0
  14. package/dist/mcp/servicenow-update-set-mcp.js +0 -0
  15. package/dist/mcp/start-all-mcp-servers.js +0 -0
  16. package/dist/mcp/start-servicenow-mcp.js +0 -0
  17. package/dist/services/widget-deployment-service.d.ts +2 -1
  18. package/dist/services/widget-deployment-service.js +17 -16
  19. package/dist/utils/anti-mock-data-validator.d.ts +66 -0
  20. package/dist/utils/anti-mock-data-validator.js +316 -0
  21. package/dist/utils/servicenow-eventual-consistency.d.ts +120 -0
  22. package/dist/utils/servicenow-eventual-consistency.js +220 -0
  23. package/memory/agents/README.md +1 -1
  24. package/memory/claude-flow-data.json +1 -1
  25. package/memory/sessions/README.md +1 -1
  26. package/package.json +4 -3
  27. package/.mcp.json +0 -22
  28. package/claude-flow.config.json +0 -20
  29. package/dist/agents/app-creator.agent.d.ts +0 -55
  30. package/dist/agents/app-creator.agent.js +0 -1292
  31. package/dist/agents/base/base-snow-agent.d.ts +0 -75
  32. package/dist/agents/base/base-snow-agent.js +0 -169
  33. package/dist/agents/base-snow-agent.d.ts +0 -63
  34. package/dist/agents/base-snow-agent.js +0 -296
  35. package/dist/agents/coordinator.d.ts +0 -200
  36. package/dist/agents/coordinator.js +0 -777
  37. package/dist/agents/flow-builder-agent.d.ts +0 -18
  38. package/dist/agents/flow-builder-agent.js +0 -197
  39. package/dist/agents/queen-403-handler.d.ts +0 -47
  40. package/dist/agents/queen-403-handler.js +0 -175
  41. package/dist/agents/queen-agent-example.d.ts +0 -23
  42. package/dist/agents/queen-agent-example.js +0 -240
  43. package/dist/agents/queen-agent.test.d.ts +0 -6
  44. package/dist/agents/script-generator.agent.d.ts +0 -32
  45. package/dist/agents/script-generator.agent.js +0 -772
  46. package/dist/agents/script-writer-agent.d.ts +0 -22
  47. package/dist/agents/script-writer-agent.js +0 -695
  48. package/dist/agents/security-agent.d.ts +0 -23
  49. package/dist/agents/security-agent.js +0 -619
  50. package/dist/agents/specialists/automation-specialist.agent.d.ts +0 -44
  51. package/dist/agents/specialists/automation-specialist.agent.js +0 -204
  52. package/dist/agents/specialists/data-specialist.agent.d.ts +0 -165
  53. package/dist/agents/specialists/data-specialist.agent.js +0 -484
  54. package/dist/agents/specialists/integration-specialist.agent.d.ts +0 -227
  55. package/dist/agents/specialists/integration-specialist.agent.js +0 -725
  56. package/dist/agents/specialists/reporting-specialist.agent.d.ts +0 -54
  57. package/dist/agents/specialists/reporting-specialist.agent.js +0 -193
  58. package/dist/agents/specialists/security-specialist.agent.d.ts +0 -85
  59. package/dist/agents/specialists/security-specialist.agent.js +0 -309
  60. package/dist/agents/teams/adaptive/adaptive-coordinator.agent.d.ts +0 -111
  61. package/dist/agents/teams/adaptive/adaptive-coordinator.agent.js +0 -383
  62. package/dist/agents/teams/base-team.d.ts +0 -72
  63. package/dist/agents/teams/base-team.js +0 -253
  64. package/dist/agents/teams/team-types.d.ts +0 -265
  65. package/dist/agents/teams/team-types.js +0 -3
  66. package/dist/agents/teams/widget/widget-architect.agent.d.ts +0 -61
  67. package/dist/agents/teams/widget/widget-architect.agent.js +0 -436
  68. package/dist/agents/teams/widget/widget-backend.agent.d.ts +0 -74
  69. package/dist/agents/teams/widget/widget-backend.agent.js +0 -1531
  70. package/dist/agents/teams/widget/widget-frontend.agent.d.ts +0 -67
  71. package/dist/agents/teams/widget/widget-frontend.agent.js +0 -1014
  72. package/dist/agents/teams/widget/widget-platform.agent.d.ts +0 -90
  73. package/dist/agents/teams/widget/widget-platform.agent.js +0 -1190
  74. package/dist/agents/teams/widget/widget-uiux.agent.d.ts +0 -107
  75. package/dist/agents/teams/widget/widget-uiux.agent.js +0 -1033
  76. package/dist/agents/test-agent.d.ts +0 -26
  77. package/dist/agents/test-agent.js +0 -734
  78. package/dist/agents/test-agents.d.ts +0 -7
  79. package/dist/agents/test-agents.js +0 -64
  80. package/dist/agents/ui-builder.agent.d.ts +0 -50
  81. package/dist/agents/ui-builder.agent.js +0 -1539
  82. package/dist/agents/widget-builder.agent.d.ts +0 -32
  83. package/dist/agents/widget-builder.agent.js +0 -439
  84. package/dist/agents/widget-creator-agent.d.ts +0 -18
  85. package/dist/agents/widget-creator-agent.js +0 -498
  86. package/dist/agents/workflow-designer.agent.d.ts +0 -31
  87. package/dist/agents/workflow-designer.agent.js +0 -583
  88. package/dist/api/error-handling.d.ts +0 -325
  89. package/dist/api/error-handling.js +0 -1488
  90. package/dist/api/flow-designer-api.d.ts +0 -167
  91. package/dist/api/flow-designer-api.js +0 -554
  92. package/dist/api/natural-language-mapper.d.ts +0 -124
  93. package/dist/api/natural-language-mapper.js +0 -501
  94. package/dist/api/performance-optimizer.d.ts +0 -240
  95. package/dist/api/performance-optimizer.js +0 -706
  96. package/dist/api/transaction-manager.d.ts +0 -189
  97. package/dist/api/transaction-manager.js +0 -576
  98. package/dist/assembly/team-assembler.d.ts +0 -140
  99. package/dist/assembly/team-assembler.js +0 -502
  100. package/dist/benchmark-performance.d.ts +0 -41
  101. package/dist/benchmark-performance.js +0 -230
  102. package/dist/cli/snow-flow-cli-integration.d.ts +0 -30
  103. package/dist/cli/snow-flow-cli-integration.js +0 -396
  104. package/dist/coordination/coordination-engine.d.ts +0 -41
  105. package/dist/coordination/coordination-engine.js +0 -324
  106. package/dist/coordination/coordination.test.d.ts +0 -6
  107. package/dist/coordination/example.d.ts +0 -31
  108. package/dist/coordination/example.js +0 -394
  109. package/dist/coordination/execution-patterns.d.ts +0 -43
  110. package/dist/coordination/execution-patterns.js +0 -507
  111. package/dist/coordination/factory.d.ts +0 -94
  112. package/dist/coordination/factory.js +0 -433
  113. package/dist/coordination/index.d.ts +0 -71
  114. package/dist/coordination/index.js +0 -135
  115. package/dist/coordination/progress-monitor.d.ts +0 -71
  116. package/dist/coordination/progress-monitor.js +0 -505
  117. package/dist/coordination/quality-gates.d.ts +0 -124
  118. package/dist/coordination/quality-gates.js +0 -577
  119. package/dist/coordination/shared-memory.d.ts +0 -39
  120. package/dist/coordination/shared-memory.js +0 -289
  121. package/dist/coordination/task-dependencies.d.ts +0 -50
  122. package/dist/coordination/task-dependencies.js +0 -407
  123. package/dist/coordination/team-coordinator.d.ts +0 -59
  124. package/dist/coordination/team-coordinator.js +0 -550
  125. package/dist/coordination/types.d.ts +0 -152
  126. package/dist/coordination/types.js +0 -3
  127. package/dist/mcp/mcp-wrapper.d.ts +0 -8
  128. package/dist/mcp/mcp-wrapper.js +0 -77
  129. package/dist/mcp/servicenow-flow-composer-enhanced.js +0 -396
  130. package/dist/mcp/servicenow-flow-composer-mcp.d.ts +0 -7
  131. package/dist/mcp/servicenow-flow-composer-mcp.js +0 -3103
  132. package/dist/mcp/servicenow-graph-memory-mcp.d.ts +0 -7
  133. package/dist/mcp/servicenow-intelligent-mcp.d.ts +0 -143
  134. package/dist/mcp/servicenow-intelligent-mcp.js +0 -4156
  135. package/dist/mcp/servicenow-xml-flow-mcp.d.ts +0 -53
  136. package/dist/mcp/servicenow-xml-flow-mcp.js +0 -1704
  137. package/dist/mcp/singleton-check.js +0 -31
  138. package/dist/mcp/test-simple-mcp.d.ts +0 -6
  139. package/dist/mcp/test-simple-mcp.js +0 -63
  140. package/dist/memory/hierarchical-memory-system.d.ts +0 -90
  141. package/dist/memory/hierarchical-memory-system.js +0 -400
  142. package/dist/memory/index.d.ts +0 -9
  143. package/dist/memory/index.js +0 -20
  144. package/dist/memory/mcp-integration-example.d.ts +0 -6
  145. package/dist/memory/mcp-integration-example.js +0 -281
  146. package/dist/memory/memory-client.d.ts +0 -199
  147. package/dist/memory/memory-client.js +0 -364
  148. package/dist/memory/memory-manager.d.ts +0 -29
  149. package/dist/memory/memory-manager.js +0 -280
  150. package/dist/memory/memory-operations.d.ts +0 -179
  151. package/dist/memory/memory-operations.js +0 -691
  152. package/dist/memory/memory-system.d.ts +0 -153
  153. package/dist/memory/memory-system.js +0 -651
  154. package/dist/memory/memory-test.d.ts +0 -6
  155. package/dist/memory/memory-test.js +0 -161
  156. package/dist/memory/snow-flow-memory-patterns.d.ts +0 -213
  157. package/dist/memory/snow-flow-memory-patterns.js +0 -200
  158. package/dist/memory/snow-memory.d.ts +0 -54
  159. package/dist/memory/snow-memory.js +0 -301
  160. package/dist/memory/swarm-memory.d.ts +0 -135
  161. package/dist/memory/swarm-memory.js +0 -378
  162. package/dist/optimization/flow-performance-optimizer.js +0 -723
  163. package/dist/orchestration/discovery/service-discovery.d.ts +0 -81
  164. package/dist/orchestration/discovery/service-discovery.js +0 -808
  165. package/dist/orchestration/distributed-orchestrator.d.ts +0 -131
  166. package/dist/orchestration/distributed-orchestrator.js +0 -712
  167. package/dist/orchestration/distribution/task-distribution-engine.d.ts +0 -53
  168. package/dist/orchestration/distribution/task-distribution-engine.js +0 -586
  169. package/dist/orchestration/flow-update-orchestrator.js +0 -648
  170. package/dist/orchestration/interfaces/distributed-orchestration.interface.d.ts +0 -606
  171. package/dist/orchestration/interfaces/distributed-orchestration.interface.js +0 -65
  172. package/dist/orchestration/protocols/mcpx-protocol.d.ts +0 -71
  173. package/dist/orchestration/protocols/mcpx-protocol.js +0 -668
  174. package/dist/orchestration/state/distributed-state-manager.d.ts +0 -89
  175. package/dist/orchestration/state/distributed-state-manager.js +0 -716
  176. package/dist/orchestrator/flow-composer.d.ts +0 -105
  177. package/dist/orchestrator/flow-composer.js +0 -404
  178. package/dist/orchestrator/flow-pattern-templates.d.ts +0 -260
  179. package/dist/orchestrator/flow-pattern-templates.js +0 -908
  180. package/dist/orchestrator/flow-subflow-decision-engine.d.ts +0 -202
  181. package/dist/orchestrator/flow-subflow-decision-engine.js +0 -769
  182. package/dist/orchestrator/flow-validation-engine.d.ts +0 -169
  183. package/dist/orchestrator/flow-validation-engine.js +0 -913
  184. package/dist/orchestrator/snow-orchestrator.d.ts +0 -49
  185. package/dist/orchestrator/snow-orchestrator.js +0 -235
  186. package/dist/orchestrator/subflow-creation-handler.d.ts +0 -230
  187. package/dist/orchestrator/subflow-creation-handler.js +0 -791
  188. package/dist/patterns/adaptive-patterns.d.ts +0 -140
  189. package/dist/patterns/adaptive-patterns.js +0 -549
  190. package/dist/queen/advanced-integration-test.d.ts +0 -48
  191. package/dist/queen/advanced-integration-test.js +0 -473
  192. package/dist/queen/integration-example.d.ts +0 -82
  193. package/dist/queen/integration-example.js +0 -219
  194. package/dist/queen/integration-test.d.ts +0 -72
  195. package/dist/queen/integration-test.js +0 -563
  196. package/dist/queen/mock-mcp-client.d.ts +0 -71
  197. package/dist/queen/mock-mcp-client.js +0 -317
  198. package/dist/queen/run-integration-tests.d.ts +0 -9
  199. package/dist/queen/run-integration-tests.js +0 -27
  200. package/dist/sparc/coordinators/adaptive-coordinator.d.ts +0 -54
  201. package/dist/sparc/coordinators/adaptive-coordinator.js +0 -367
  202. package/dist/sparc/coordinators/team-coordinator.d.ts +0 -66
  203. package/dist/sparc/coordinators/team-coordinator.js +0 -402
  204. package/dist/sparc/modes/team-modes.d.ts +0 -33
  205. package/dist/sparc/modes/team-modes.js +0 -399
  206. package/dist/sparc/teams/application-team.d.ts +0 -73
  207. package/dist/sparc/teams/application-team.js +0 -463
  208. package/dist/sparc/teams/flow-team.d.ts +0 -67
  209. package/dist/sparc/teams/flow-team.js +0 -373
  210. package/dist/sparc/teams/widget-team.d.ts +0 -61
  211. package/dist/sparc/teams/widget-team.js +0 -280
  212. package/dist/specialists/app-specialists.d.ts +0 -93
  213. package/dist/specialists/app-specialists.js +0 -1639
  214. package/dist/specialists/base-specialist.d.ts +0 -19
  215. package/dist/specialists/base-specialist.js +0 -54
  216. package/dist/specialists/flow-specialists.d.ts +0 -113
  217. package/dist/specialists/flow-specialists.js +0 -1787
  218. package/dist/specialists/individual-specialists.d.ts +0 -67
  219. package/dist/specialists/individual-specialists.js +0 -632
  220. package/dist/specialists/widget-specialists.d.ts +0 -70
  221. package/dist/specialists/widget-specialists.js +0 -1264
  222. package/dist/src/utils/agent-detector.js +0 -655
  223. package/dist/teams/adaptive-team.d.ts +0 -81
  224. package/dist/teams/adaptive-team.js +0 -1153
  225. package/dist/teams/application-team.d.ts +0 -30
  226. package/dist/teams/application-team.js +0 -547
  227. package/dist/teams/base-team.d.ts +0 -55
  228. package/dist/teams/base-team.js +0 -243
  229. package/dist/teams/flow-team.d.ts +0 -28
  230. package/dist/teams/flow-team.js +0 -525
  231. package/dist/teams/widget-team.d.ts +0 -26
  232. package/dist/teams/widget-team.js +0 -459
  233. package/dist/templates/flow-template-system.js +0 -625
  234. package/dist/test-fetch-incidents.d.ts +0 -2
  235. package/dist/test-fetch-incidents.js +0 -84
  236. package/dist/test-incident-access.d.ts +0 -2
  237. package/dist/test-incident-access.js +0 -72
  238. package/dist/test-iphone-flow.js +0 -189
  239. package/dist/test-limit-problem.d.ts +0 -2
  240. package/dist/test-limit-problem.js +0 -60
  241. package/dist/test-ml-batch-fix.d.ts +0 -2
  242. package/dist/test-ml-batch-fix.js +0 -104
  243. package/dist/test-ml-batch.d.ts +0 -2
  244. package/dist/test-ml-batch.js +0 -87
  245. package/dist/test-ml-query.d.ts +0 -2
  246. package/dist/test-ml-query.js +0 -100
  247. package/dist/test-ml-training-fix.d.ts +0 -12
  248. package/dist/test-ml-training-fix.js +0 -113
  249. package/dist/test-ml-training.d.ts +0 -2
  250. package/dist/test-ml-training.js +0 -32
  251. package/dist/test-operations-query.d.ts +0 -2
  252. package/dist/test-operations-query.js +0 -84
  253. package/dist/test-performance-query.d.ts +0 -2
  254. package/dist/test-performance-query.js +0 -52
  255. package/dist/test-singleton-protection.d.ts +0 -8
  256. package/dist/test-singleton-protection.js +0 -110
  257. package/dist/test-smart-limits.d.ts +0 -13
  258. package/dist/test-smart-limits.js +0 -100
  259. package/dist/test-snow-query-incidents.d.ts +0 -2
  260. package/dist/test-snow-query-incidents.js +0 -66
  261. package/dist/test-universal-query.d.ts +0 -2
  262. package/dist/test-universal-query.js +0 -106
  263. package/dist/testing/flow-testing-automation.js +0 -641
  264. package/dist/utils/complete-flow-xml-generator.js +0 -1285
  265. package/dist/utils/file-storage-fallback.d.ts +0 -62
  266. package/dist/utils/file-storage-fallback.js +0 -289
  267. package/dist/utils/flow-api-discovery.d.ts +0 -151
  268. package/dist/utils/flow-api-discovery.js +0 -439
  269. package/dist/utils/flow-examples.js +0 -720
  270. package/dist/utils/flow-structure-builder.js +0 -677
  271. package/dist/utils/flow-xml-generator.d.ts +0 -41
  272. package/dist/utils/flow-xml-generator.js +0 -258
  273. package/dist/utils/improved-flow-xml-generator.js +0 -820
  274. package/dist/utils/mcp-process-manager.backup.d.ts +0 -58
  275. package/dist/utils/mcp-process-manager.backup.js +0 -220
  276. package/dist/utils/mcp-singleton-enforcer.d.ts +0 -36
  277. package/dist/utils/mcp-singleton-enforcer.js +0 -201
  278. package/dist/utils/mcp-timeout-fix.d.ts +0 -53
  279. package/dist/utils/mcp-timeout-fix.js +0 -221
  280. package/dist/utils/migrate-claude-flow.d.ts +0 -22
  281. package/dist/utils/migrate-claude-flow.js +0 -120
  282. package/dist/utils/scope-utils.d.ts +0 -72
  283. package/dist/utils/scope-utils.js +0 -386
  284. package/dist/utils/snow-oauth-old.d.ts +0 -65
  285. package/dist/utils/snow-oauth-old.js +0 -345
  286. package/dist/utils/xml-first-flow-generator.js +0 -513
  287. package/memory/servicenow_artifacts/000d9224c895221055906c7518aa2d3d.json +0 -30
  288. package/memory/servicenow_artifacts/0196b66173303010e46b4a2214f6a7a2.json +0 -36
  289. package/memory/servicenow_artifacts/125e5d1d837e2a102a7ea130ceaad397.json +0 -30
  290. package/memory/servicenow_artifacts/7637c1f2b7112210a5e5911cde11a972.json +0 -30
  291. package/memory/servicenow_artifacts/default_documentation_tables_1754056582292.json +0 -55
  292. package/memory/servicenow_artifacts/default_documentation_tables_1754057477189.json +0 -55
  293. package/memory/update-set-sessions/01f82af583faea102a7ea130ceaad3d4.json +0 -9
  294. package/memory/update-set-sessions/27718fb983faea102a7ea130ceaad34b.json +0 -9
  295. package/memory/update-set-sessions/412e9bf6833e22502a7ea130ceaad30a.json +0 -8
  296. package/memory/update-set-sessions/66fc5a79837aea102a7ea130ceaad3ab.json +0 -9
  297. package/memory/update-set-sessions/71a30ff5837eea102a7ea130ceaad37f.json +0 -9
  298. package/memory/update-set-sessions/74fba27983faea102a7ea130ceaad3bd.json +0 -9
  299. package/memory/update-set-sessions/a0b147b5837eea102a7ea130ceaad344.json +0 -58
  300. package/memory/update-set-sessions/b13f5eb983baea102a7ea130ceaad33e.json +0 -9
  301. package/reports/swarm-auto-centralized-1752649029776.json +0 -13
  302. package/src/memory/README.md +0 -240
@@ -1,3103 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * ServiceNow Flow Composer MCP Server
5
- * Natural language flow creation with multi-artifact orchestration
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- Object.defineProperty(exports, "__esModule", { value: true });
41
- const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
42
- const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
43
- const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
44
- const servicenow_client_js_1 = require("../utils/servicenow-client.js");
45
- const snow_oauth_js_1 = require("../utils/snow-oauth.js");
46
- const logger_js_1 = require("../utils/logger.js");
47
- const flow_composer_js_1 = require("../orchestrator/flow-composer.js");
48
- const complete_flow_xml_generator_js_1 = require("../utils/complete-flow-xml-generator.js");
49
- const update_set_importer_js_1 = require("../utils/update-set-importer.js");
50
- const mcp_tool_registry_js_1 = require("../utils/mcp-tool-registry.js");
51
- const deployment_metadata_handler_js_1 = require("../utils/deployment-metadata-handler.js");
52
- class ServiceNowFlowComposerMCP {
53
- constructor() {
54
- this.server = new index_js_1.Server({
55
- name: 'servicenow-flow-composer-enhanced',
56
- version: '2.0.0',
57
- description: 'Enhanced Flow Composer with Complete Solution - Fixes all critical issues: empty flows, tool registry mapping, and metadata failures',
58
- }, {
59
- capabilities: {
60
- tools: {},
61
- },
62
- });
63
- this.client = new servicenow_client_js_1.ServiceNowClient();
64
- this.oauth = new snow_oauth_js_1.ServiceNowOAuth();
65
- this.logger = new logger_js_1.Logger('ServiceNowFlowComposerMCP');
66
- this.composer = new flow_composer_js_1.EnhancedFlowComposer();
67
- this.setupHandlers();
68
- }
69
- setupHandlers() {
70
- this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
71
- tools: [
72
- {
73
- name: 'snow_create_flow',
74
- description: '🚀 ENHANCED FLOW TOOL v2.0 - Creates COMPLETE flows with ALL features working! Uses CompleteFlowXMLGenerator for proper v2 tables, Base64+gzip encoding, and full metadata. Fixes all deployment issues. ZERO MANUAL STEPS!',
75
- inputSchema: {
76
- type: 'object',
77
- properties: {
78
- instruction: {
79
- type: 'string',
80
- description: 'Natural language instruction for the flow (e.g., "maak een flow waarbij we het script include gebruiken waar we de localizatie met LLMs gebruiken om dan de berichten van het support desk mee te vertalen naar engels en deze op te slaan in een tabel aan de hand van een business rule")'
81
- },
82
- deploy_immediately: {
83
- type: 'boolean',
84
- description: '⚠️ DEPLOYMENT MODE - true: Deploy REAL flow to ServiceNow immediately | false: Planning mode only',
85
- default: true
86
- },
87
- create_missing_artifacts: {
88
- type: 'boolean',
89
- description: 'Create missing artifacts as fallbacks',
90
- default: true
91
- },
92
- scope_preference: {
93
- type: 'string',
94
- enum: ['global', 'application', 'auto'],
95
- description: 'Preferred deployment scope',
96
- default: 'auto'
97
- },
98
- enable_intelligent_analysis: {
99
- type: 'boolean',
100
- description: 'Enable intelligent flow vs subflow analysis',
101
- default: true
102
- },
103
- validation_level: {
104
- type: 'string',
105
- enum: ['basic', 'standard', 'comprehensive'],
106
- description: 'Level of validation to perform',
107
- default: 'standard'
108
- },
109
- },
110
- required: ['instruction'],
111
- },
112
- },
113
- {
114
- name: 'snow_analyze_flow_instruction',
115
- description: 'AUTONOMOUS analysis - understands complex requirements, identifies all needed artifacts, plans optimal flow structure. SELF-LEARNING from patterns.',
116
- inputSchema: {
117
- type: 'object',
118
- properties: {
119
- instruction: {
120
- type: 'string',
121
- description: 'Natural language instruction to analyze'
122
- },
123
- },
124
- required: ['instruction'],
125
- },
126
- },
127
- {
128
- name: 'snow_discover_flow_artifacts',
129
- description: 'AUTONOMOUS discovery - finds all required artifacts, creates missing ones, ensures compatibility. INTELLIGENT DEPENDENCY RESOLUTION!',
130
- inputSchema: {
131
- type: 'object',
132
- properties: {
133
- instruction: {
134
- type: 'string',
135
- description: 'Natural language instruction'
136
- },
137
- artifact_types: {
138
- type: 'array',
139
- items: {
140
- type: 'string',
141
- enum: ['script_include', 'business_rule', 'table', 'widget', 'ui_script']
142
- },
143
- description: 'Specific artifact types to search for'
144
- },
145
- },
146
- required: ['instruction'],
147
- },
148
- },
149
- {
150
- name: 'snow_preview_flow_structure',
151
- description: 'Preview the flow structure before deployment',
152
- inputSchema: {
153
- type: 'object',
154
- properties: {
155
- instruction: {
156
- type: 'string',
157
- description: 'Natural language instruction'
158
- },
159
- },
160
- required: ['instruction'],
161
- },
162
- },
163
- {
164
- name: 'snow_deploy_composed_flow',
165
- description: 'Deploy a previously composed flow with all its artifacts',
166
- inputSchema: {
167
- type: 'object',
168
- properties: {
169
- flow_instruction: {
170
- type: 'object',
171
- description: 'Previously composed flow instruction object'
172
- },
173
- validation_required: {
174
- type: 'boolean',
175
- description: 'Validate all artifacts before deployment',
176
- default: true
177
- },
178
- },
179
- required: ['flow_instruction'],
180
- },
181
- },
182
- {
183
- name: 'snow_intelligent_flow_analysis',
184
- description: 'INTELLIGENT ANALYSIS - Performs comprehensive flow vs subflow analysis with decision rationale and recommendations',
185
- inputSchema: {
186
- type: 'object',
187
- properties: {
188
- instruction: {
189
- type: 'string',
190
- description: 'Natural language instruction to analyze'
191
- },
192
- include_templates: {
193
- type: 'boolean',
194
- description: 'Include template matching analysis',
195
- default: true
196
- },
197
- include_validation: {
198
- type: 'boolean',
199
- description: 'Include validation analysis',
200
- default: true
201
- },
202
- },
203
- required: ['instruction'],
204
- },
205
- },
206
- {
207
- name: 'snow_scope_optimization',
208
- description: 'SCOPE OPTIMIZATION - Analyzes and recommends optimal deployment scope with fallback strategies',
209
- inputSchema: {
210
- type: 'object',
211
- properties: {
212
- artifact_type: {
213
- type: 'string',
214
- description: 'Type of artifact to analyze'
215
- },
216
- artifact_data: {
217
- type: 'object',
218
- description: 'Artifact data for analysis'
219
- },
220
- environment_type: {
221
- type: 'string',
222
- enum: ['development', 'testing', 'production'],
223
- description: 'Target environment type',
224
- default: 'development'
225
- },
226
- },
227
- required: ['artifact_type', 'artifact_data'],
228
- },
229
- },
230
- {
231
- name: 'snow_template_matching',
232
- description: 'TEMPLATE MATCHING - Finds and applies best matching flow templates for common patterns',
233
- inputSchema: {
234
- type: 'object',
235
- properties: {
236
- instruction: {
237
- type: 'string',
238
- description: 'Natural language instruction'
239
- },
240
- template_categories: {
241
- type: 'array',
242
- items: {
243
- type: 'string',
244
- enum: ['approval', 'fulfillment', 'notification', 'integration', 'utility']
245
- },
246
- description: 'Template categories to search'
247
- },
248
- minimum_confidence: {
249
- type: 'number',
250
- description: 'Minimum confidence threshold for template matching',
251
- default: 0.6
252
- },
253
- },
254
- required: ['instruction'],
255
- },
256
- },
257
- {
258
- name: 'snow_performance_analysis',
259
- description: '🚀 BUG-007 FIX: PERFORMANCE ANALYSIS - Analyzes flows for performance bottlenecks and provides database index recommendations',
260
- inputSchema: {
261
- type: 'object',
262
- properties: {
263
- flow_definition: {
264
- type: 'object',
265
- description: 'Flow definition to analyze for performance'
266
- },
267
- table_name: {
268
- type: 'string',
269
- description: 'Specific table to analyze (optional)'
270
- },
271
- include_database_indexes: {
272
- type: 'boolean',
273
- description: 'Include database index recommendations',
274
- default: true
275
- },
276
- include_code_analysis: {
277
- type: 'boolean',
278
- description: 'Include flow script performance analysis',
279
- default: true
280
- },
281
- detailed_report: {
282
- type: 'boolean',
283
- description: 'Generate detailed performance report',
284
- default: false
285
- }
286
- },
287
- required: ['flow_definition'],
288
- },
289
- },
290
- {
291
- name: 'snow_comprehensive_requirements_analysis',
292
- description: '🚀 BUG-006 FIX: MULTI-PASS REQUIREMENTS ANALYSIS - Comprehensive 4-pass analysis to ensure no requirements are missed',
293
- inputSchema: {
294
- type: 'object',
295
- properties: {
296
- objective: {
297
- type: 'string',
298
- description: 'The objective or requirement to analyze comprehensively (e.g., "iPhone provisioning workflow for new employees")'
299
- },
300
- include_dependencies: {
301
- type: 'boolean',
302
- description: 'Include dependency analysis (pass 2)',
303
- default: true
304
- },
305
- include_context_analysis: {
306
- type: 'boolean',
307
- description: 'Include context and implication analysis (pass 3)',
308
- default: true
309
- },
310
- include_validation: {
311
- type: 'boolean',
312
- description: 'Include validation and completeness check (pass 4)',
313
- default: true
314
- },
315
- detailed_report: {
316
- type: 'boolean',
317
- description: 'Generate detailed multi-pass analysis report',
318
- default: false
319
- }
320
- },
321
- required: ['objective'],
322
- },
323
- },
324
- ],
325
- }));
326
- this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
327
- const { name, arguments: args } = request.params;
328
- try {
329
- switch (name) {
330
- case 'snow_create_flow':
331
- return await this.createFlow(args);
332
- case 'snow_analyze_flow_instruction':
333
- return await this.analyzeFlowInstruction(args);
334
- case 'snow_discover_flow_artifacts':
335
- return await this.discoverFlowArtifacts(args);
336
- case 'snow_preview_flow_structure':
337
- return await this.previewFlowStructure(args);
338
- case 'snow_deploy_composed_flow':
339
- return await this.deployComposedFlow(args);
340
- case 'snow_intelligent_flow_analysis':
341
- return await this.intelligentFlowAnalysis(args);
342
- case 'snow_scope_optimization':
343
- return await this.scopeOptimization(args);
344
- case 'snow_template_matching':
345
- return await this.templateMatching(args);
346
- case 'snow_performance_analysis':
347
- return await this.performanceAnalysis(args);
348
- case 'snow_comprehensive_requirements_analysis':
349
- return await this.comprehensiveRequirementsAnalysis(args);
350
- default:
351
- throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
352
- }
353
- }
354
- catch (error) {
355
- this.logger.error(`Tool execution failed: ${name}`, error);
356
- throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, error instanceof Error ? error.message : String(error));
357
- }
358
- });
359
- }
360
- async createFlow(args) {
361
- console.log('🎯 INTELLIGENT FLOW CREATION STARTED');
362
- console.log('📝 Instruction:', args.instruction);
363
- // Input validation
364
- if (!args.instruction || typeof args.instruction !== 'string' || args.instruction.trim().length === 0) {
365
- return {
366
- content: [
367
- {
368
- type: 'text',
369
- text: '❌ Invalid Input: Instruction is required and must be a non-empty string.\n\nPlease provide a clear, descriptive instruction for your flow.',
370
- },
371
- ],
372
- };
373
- }
374
- if (args.instruction.length > 2000) {
375
- return {
376
- content: [
377
- {
378
- type: 'text',
379
- text: '❌ Invalid Input: Instruction is too long (maximum 2000 characters).\n\nPlease provide a more concise instruction.',
380
- },
381
- ],
382
- };
383
- }
384
- // Check authentication first
385
- const isAuth = await this.oauth.isAuthenticated();
386
- if (!isAuth) {
387
- return {
388
- content: [
389
- {
390
- type: 'text',
391
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
392
- },
393
- ],
394
- };
395
- }
396
- try {
397
- this.logger.info('🧠 Starting intelligent flow creation', { instruction: args.instruction });
398
- // 🧠 STEP 1: Parse natural language instruction intelligently
399
- const parsedIntent = await this.parseFlowInstruction(args.instruction);
400
- console.log('🧠 Parsed intent:', parsedIntent);
401
- // 🧠 STEP 2: Find matching templates based on intent
402
- const templateMatch = await this.findBestTemplate(parsedIntent);
403
- console.log('🧠 Template match:', templateMatch);
404
- // 🧠 STEP 3: Discover required artifacts
405
- const artifacts = await this.discoverRequiredArtifacts(parsedIntent);
406
- console.log('🧠 Discovered artifacts:', artifacts);
407
- // 🧠 STEP 4: Generate complete flow definition
408
- const flowDefinition = await this.generateFlowDefinition(parsedIntent, templateMatch, artifacts);
409
- console.log('🧠 Generated flow definition:', JSON.stringify(flowDefinition, null, 2));
410
- // 🧠 STEP 5: Deploy using XML-first approach for maximum reliability
411
- let deploymentResult = null;
412
- let xmlResult = null; // 🔴 FIX: Declare outside try block to avoid scope issues
413
- let performanceAnalysis = null; // 🚀 BUG-007 FIX: Performance analysis results
414
- if (args.deploy_immediately !== false) {
415
- console.log('🚀 DEPLOYING flow using XML-first approach...');
416
- try {
417
- // 🚀 ENHANCED: Use CompleteFlowXMLGenerator for proper flow generation
418
- // 🔒 BUG-004 FIX: Apply SECURE DEFAULTS - NEVER allow public access by default
419
- const SECURE_FLOW_DEFAULTS = {
420
- run_as: 'user', // Always run as user, not system
421
- accessible_from: 'package_private', // NEVER public by default
422
- requires_authentication: true,
423
- requires_role: true
424
- };
425
- // Convert to CompleteFlowDefinition format with ENFORCED secure defaults
426
- const completeFlowDef = {
427
- name: parsedIntent.flowName,
428
- description: parsedIntent.description,
429
- table: parsedIntent.table,
430
- trigger_type: this.mapTriggerTypeToXML(parsedIntent.trigger.type),
431
- trigger_condition: parsedIntent.trigger.condition || '',
432
- activities: this.convertActivitiesToCompleteFormat(flowDefinition.activities || []),
433
- // 🛡️ SECURITY: These defaults CANNOT be overridden accidentally
434
- run_as: SECURE_FLOW_DEFAULTS.run_as,
435
- accessible_from: SECURE_FLOW_DEFAULTS.accessible_from,
436
- category: 'custom',
437
- tags: ['auto-generated', 'enhanced']
438
- };
439
- // 🔒 Log security configuration for audit trail
440
- this.logger.info('🛡️ Applying secure flow defaults', {
441
- flowName: parsedIntent.flowName,
442
- accessible_from: completeFlowDef.accessible_from,
443
- run_as: completeFlowDef.run_as,
444
- table: completeFlowDef.table,
445
- trigger_type: completeFlowDef.trigger_type
446
- });
447
- console.log('🔒 SECURITY: Flow created with secure defaults:');
448
- console.log(` • Access Level: ${completeFlowDef.accessible_from} (secure)`);
449
- console.log(` • Run As: ${completeFlowDef.run_as} (secure)`);
450
- console.log(` • Authentication: Required`);
451
- console.log(` • Role-based Access: Required`);
452
- // Generate production-ready XML with CompleteFlowXMLGenerator
453
- xmlResult = (0, complete_flow_xml_generator_js_1.generateCompleteFlowXML)(completeFlowDef);
454
- console.log('✅ XML generated:', xmlResult.filePath);
455
- // 🚀 BUG-007 FIX: Performance analysis and recommendations
456
- const { PerformanceRecommendationsEngine } = await Promise.resolve().then(() => __importStar(require('../intelligence/performance-recommendations-engine.js')));
457
- const performanceEngine = new PerformanceRecommendationsEngine();
458
- console.log('🔍 Running performance analysis...');
459
- performanceAnalysis = await performanceEngine.analyzeFlowPerformance(xmlFlowDef);
460
- if (performanceAnalysis.summary.criticalIssues > 0) {
461
- console.log(`⚠️ PERFORMANCE: ${performanceAnalysis.summary.criticalIssues} critical issues found`);
462
- console.log(`📈 Potential improvement: ${performanceAnalysis.summary.estimatedImprovementPercent}%`);
463
- // Show top 3 most critical recommendations
464
- const topRecommendations = [
465
- ...performanceAnalysis.databaseIndexes.filter(idx => idx.priority === 'critical').slice(0, 2),
466
- ...performanceAnalysis.performanceRecommendations.filter(rec => rec.impact === 'high').slice(0, 1)
467
- ];
468
- if (topRecommendations.length > 0) {
469
- console.log('🎯 Top performance recommendations:');
470
- topRecommendations.forEach((rec, i) => {
471
- if ('fields' in rec) {
472
- // Database index recommendation
473
- console.log(` ${i + 1}. INDEX: ${rec.table} (${rec.fields.join(', ')}) - ${rec.reason}`);
474
- console.log(` 💻 ${rec.createStatement}`);
475
- }
476
- else {
477
- // Performance recommendation
478
- console.log(` ${i + 1}. ${rec.type.toUpperCase()}: ${rec.description}`);
479
- console.log(` 💡 ${rec.recommendation}`);
480
- }
481
- });
482
- }
483
- }
484
- else {
485
- console.log('✅ Performance analysis: No critical issues detected');
486
- }
487
- // 🔴 CRITICAL FIX: Auto-deploy with INTEGRATED verification
488
- // SNOW-001: Verification is now MANDATORY within each deployment strategy
489
- const deployResult = await this.deployWithFallback(xmlResult.filePath, flowDefinition);
490
- // 🔴 FIXED: No duplicate verification needed - it's integrated into deployment strategies
491
- // deployResult.verification contains the comprehensive verification results
492
- // Success with integrated verification
493
- deploymentResult = {
494
- success: true,
495
- method: deployResult.strategy,
496
- xml_file: xmlResult.filePath,
497
- message: `✅ Flow deployed via ${deployResult.strategy} and verified in ServiceNow!`,
498
- flow_sys_id: deployResult.verification.sys_id,
499
- flow_url: deployResult.verification.url,
500
- verification_score: deployResult.verification.completeness_score,
501
- verification_details: {
502
- has_flow: true,
503
- has_snapshot: deployResult.verification.has_snapshot,
504
- has_trigger: deployResult.verification.has_trigger,
505
- attempts_needed: deployResult.verification.verification_attempt,
506
- deployment_verified: deployResult.deployment_verified
507
- },
508
- snow_001_fix: 'Deployment includes mandatory verification - no false positives possible'
509
- };
510
- }
511
- catch (xmlError) {
512
- console.error('❌ XML deployment failed:', xmlError);
513
- // Extract detailed error information
514
- let errorDetails = 'Unknown error';
515
- if (xmlError instanceof Error) {
516
- errorDetails = xmlError.message;
517
- // Check for specific error types
518
- if (xmlError.message.includes('400')) {
519
- errorDetails = 'ServiceNow rejected the request. Check permissions and Update Set.';
520
- }
521
- else if (xmlError.message.includes('401') || xmlError.message.includes('403')) {
522
- errorDetails = 'Authentication failed. Run: snow-flow auth login';
523
- }
524
- }
525
- deploymentResult = {
526
- success: false,
527
- error: errorDetails,
528
- xml_generated: xmlResult !== null, // 🔴 FIX: Check if XML was actually generated
529
- xml_path: xmlResult?.filePath,
530
- deployment_failed: true,
531
- manual_steps: this.generateManualImportGuide(xmlResult?.filePath || ''),
532
- fallback_instructions: 'Use snow-flow deploy-xml command for manual deployment'
533
- };
534
- }
535
- }
536
- const credentials = await this.oauth.loadCredentials();
537
- const flowUrl = `https://${credentials?.instance}/flow-designer/flow/${parsedIntent.flowName}`;
538
- // 🔴 BUG-001 FIX: Return structured data with sys_id and all identifiers
539
- const flowSysId = deploymentResult?.verification?.sys_id || deploymentResult?.sys_id || null;
540
- const actualFlowUrl = flowSysId ?
541
- `https://${credentials?.instance}/flow-designer/designer/${flowSysId}` :
542
- flowUrl;
543
- const structuredResult = {
544
- success: deploymentResult?.success || false,
545
- flow: {
546
- sys_id: flowSysId,
547
- name: parsedIntent.flowName,
548
- table: parsedIntent.table,
549
- trigger_type: parsedIntent.trigger.type,
550
- active: true,
551
- description: parsedIntent.description,
552
- url: actualFlowUrl,
553
- api_endpoint: flowSysId ?
554
- `https://${credentials?.instance}/api/now/table/sys_hub_flow/${flowSysId}` : null
555
- },
556
- deployment: {
557
- method: deploymentResult?.deployment_method || 'XML Update Set',
558
- xml_file: xmlResult?.file || deploymentResult?.xml_path || null,
559
- update_set_id: deploymentResult?.update_set_id || null,
560
- success: deploymentResult?.success || false,
561
- error: deploymentResult?.error || null
562
- },
563
- analysis: {
564
- intents: parsedIntent.intents,
565
- template: templateMatch?.name || 'Custom implementation',
566
- confidence: templateMatch?.confidence || 0,
567
- activities_count: flowDefinition.activities?.length || 0,
568
- variables_count: flowDefinition.variables?.length || 0
569
- },
570
- // 🚀 BUG-007 FIX: Performance analysis results
571
- performance: {
572
- database_indexes: performanceAnalysis?.databaseIndexes || [],
573
- recommendations: performanceAnalysis?.performanceRecommendations || [],
574
- summary: {
575
- critical_issues: performanceAnalysis?.summary?.criticalIssues || 0,
576
- estimated_improvement_percent: performanceAnalysis?.summary?.estimatedImprovementPercent || 0,
577
- top_actions: performanceAnalysis?.summary?.recommendedActions || []
578
- },
579
- report_available: true
580
- }
581
- };
582
- // Log structured result for debugging
583
- this.logger.info('🔴 BUG-001 FIX: Returning structured flow data', structuredResult);
584
- return {
585
- content: [
586
- {
587
- type: 'text',
588
- text: deploymentResult?.success ?
589
- `✅ FLOW SUCCESSFULLY CREATED AND DEPLOYED!
590
-
591
- 🚀 **VERIFIED DEPLOYMENT** - Flow is now live in ServiceNow!
592
-
593
- 🆔 **Flow Identifiers** (BUG-001 FIX):
594
- - **Sys ID**: ${structuredResult.flow.sys_id}
595
- - **Name**: ${structuredResult.flow.name}
596
- - **API Endpoint**: ${structuredResult.flow.api_endpoint}
597
-
598
- 🔗 **Direct Access**: ${structuredResult.flow.url}` :
599
- deploymentResult?.deployment_failed ?
600
- `⚠️ FLOW XML GENERATED BUT DEPLOYMENT FAILED
601
-
602
- ❌ **Deployment Error**: ${deploymentResult.error}
603
-
604
- 🆔 **Flow Details** (BUG-001 FIX):
605
- - **Name**: ${structuredResult.flow.name}
606
- - **Table**: ${structuredResult.flow.table}
607
- - **Sys ID**: ${structuredResult.flow.sys_id || 'Not yet available'}
608
-
609
- 📁 **XML File**: ${deploymentResult.xml_path}
610
-
611
- 📋 **Manual Import Steps**:
612
- ${deploymentResult.manual_steps || '1. Navigate to System Update Sets > Retrieved Update Sets\n2. Import Update Set from XML\n3. Preview and Commit'}` :
613
- `🎯 FLOW CREATED WITH XML-FIRST APPROACH!
614
-
615
- ${args.deploy_immediately !== false ? `🚀 **DEPLOYMENT STATUS** - Processing...` : `📋 **PLANNING MODE** - Flow structure generated`}
616
-
617
- 🆔 **Flow Identifiers** (BUG-001 FIX):
618
- - **Sys ID**: ${structuredResult.flow.sys_id || 'Pending deployment'}
619
- - **Name**: ${structuredResult.flow.name}
620
- - **Table**: ${structuredResult.flow.table}
621
- - **API Endpoint**: ${structuredResult.flow.api_endpoint || 'Not yet available'}
622
-
623
- 🧠 **Intelligent Analysis:**
624
- - **Flow Name**: ${parsedIntent.flowName}
625
- - **Primary Table**: ${parsedIntent.table}
626
- - **Trigger Type**: ${parsedIntent.trigger.type}
627
- - **Intent Categories**: ${parsedIntent.intents.join(', ')}
628
- - **Template Match**: ${templateMatch?.name || 'Custom implementation'}
629
- - **Confidence**: ${templateMatch?.confidence ? Math.round(templateMatch.confidence * 100) + '%' : 'N/A'}
630
-
631
- 📋 **Flow Structure:**
632
- - **Activities**: ${flowDefinition.activities?.length || 0} intelligent actions
633
- - **Variables**: ${flowDefinition.variables?.length || 0} dynamic inputs/outputs
634
- - **Error Handling**: ${flowDefinition.error_handling?.length || 0} safety measures
635
- - **Artifacts Used**: ${artifacts.existing.length} found, ${artifacts.created.length} created
636
-
637
- 🚀 **XML-First Deployment:**
638
- ${deploymentResult ? (deploymentResult.success ?
639
- `✅ Successfully deployed using XML-first approach!
640
- - **Method**: Production-ready Update Set XML
641
- - **XML File**: ${deploymentResult.xml_file}
642
- - **Status**: Imported → Previewed → Committed ✅` :
643
- `❌ Auto-deployment failed: ${deploymentResult.error}
644
- - **Fallback**: ${deploymentResult.fallback_instructions}`) : '⏳ Ready for deployment'}
645
-
646
- 🔗 **ServiceNow Access:**
647
- - Flow Designer: ${actualFlowUrl}
648
- - Flow Designer Home: https://${credentials?.instance}/flow-designer
649
-
650
- 🧠 **NEW Features (v1.3.24):**
651
- - Structured flow data with sys_id (BUG-001 FIX) ✅
652
- - XML-first approach for maximum reliability ✅
653
- - Automatic Update Set deployment ✅
654
- - Zero manual steps required ✅
655
- - Production-ready Flow Designer format ✅
656
- - Intelligent error handling & fallbacks ✅
657
-
658
- Your flow is now ${structuredResult.success ? 'live' : 'ready'} in ServiceNow Flow Designer! 🎉`,
659
- },
660
- ],
661
- // 🔴 BUG-001 FIX: Include structured data in response
662
- ...structuredResult
663
- };
664
- }
665
- catch (error) {
666
- this.logger.error('❌ Intelligent flow creation failed:', error);
667
- return this.handleServiceNowError(error, 'Intelligent Flow Creation');
668
- }
669
- }
670
- /**
671
- * 🛡️ Check if user is trying to make flow public and warn them about security
672
- */
673
- checkSecurityIntent(instruction) {
674
- const warnings = [];
675
- const lowerInstruction = instruction.toLowerCase();
676
- const publicKeywords = [
677
- 'public', 'publicly', 'everyone', 'anyone', 'all users',
678
- 'no authentication', 'without login', 'guest access',
679
- 'anonymous', 'unauthenticated', 'open access'
680
- ];
681
- const hasPublicIntent = publicKeywords.some(keyword => lowerInstruction.includes(keyword));
682
- if (hasPublicIntent) {
683
- warnings.push('⚠️ SECURITY WARNING: Public access detected in request');
684
- warnings.push('🔒 For security, flows default to package_private access');
685
- warnings.push('💡 To make public, explicitly override accessible_from in config');
686
- warnings.push('🛡️ Consider using role-based access instead of public access');
687
- }
688
- return { hasPublicIntent, warnings };
689
- }
690
- /**
691
- * 🧠 INTELLIGENT NATURAL LANGUAGE PARSING
692
- * Analyzes instruction to understand flow intent, trigger, and requirements
693
- */
694
- async parseFlowInstruction(instruction) {
695
- console.log('🧠 Parsing flow instruction intelligently...');
696
- // 🔒 BUG-004 FIX: Check for security concerns first
697
- const securityCheck = this.checkSecurityIntent(instruction);
698
- if (securityCheck.warnings.length > 0) {
699
- securityCheck.warnings.forEach(warning => console.log(warning));
700
- this.logger.warn('🔒 Security warning in flow instruction', {
701
- instruction,
702
- hasPublicIntent: securityCheck.hasPublicIntent
703
- });
704
- }
705
- const words = instruction.toLowerCase();
706
- // 🎯 Intent Analysis - What is the user trying to achieve?
707
- const intents = [];
708
- if (words.includes('approval') || words.includes('goedkeuring'))
709
- intents.push('approval');
710
- if (words.includes('notification') || words.includes('email') || words.includes('mail'))
711
- intents.push('notification');
712
- if (words.includes('incident') || words.includes('problem'))
713
- intents.push('incident_management');
714
- if (words.includes('request') || words.includes('aanvraag'))
715
- intents.push('request_fulfillment');
716
- if (words.includes('user') || words.includes('gebruiker'))
717
- intents.push('user_management');
718
- if (words.includes('task') || words.includes('taak'))
719
- intents.push('task_management');
720
- if (words.includes('data') || words.includes('record') || words.includes('save'))
721
- intents.push('data_processing');
722
- if (words.includes('integrate') || words.includes('api'))
723
- intents.push('integration');
724
- // Default if no specific intent found
725
- if (intents.length === 0)
726
- intents.push('general_automation');
727
- // 🔴 BUG-003 FIX: Enhanced table detection with context awareness
728
- let table = 'incident'; // default
729
- // Priority-based table detection - more specific terms override generic ones
730
- if (words.includes('incident') && (words.includes('management') || words.includes('priority') || words.includes('severity'))) {
731
- table = 'incident'; // Explicitly keep incident table when incident context is strong
732
- }
733
- else if (words.includes('change') && words.includes('request')) {
734
- table = 'change_request';
735
- }
736
- else if (words.includes('user') || words.includes('gebruiker')) {
737
- table = 'sys_user';
738
- }
739
- else if (words.includes('request') || words.includes('aanvraag')) {
740
- table = 'sc_request';
741
- }
742
- else if (words.includes('task') || words.includes('sc_task')) {
743
- table = 'sc_task';
744
- }
745
- else if (words.includes('problem')) {
746
- table = 'problem';
747
- }
748
- else if (words.includes('catalog')) {
749
- table = 'sc_cat_item';
750
- }
751
- // Log table detection for debugging
752
- console.log(`🔴 BUG-003: Table detected as '${table}' from instruction: "${instruction}"`);
753
- // 🎯 Trigger Analysis - When should the flow run?
754
- const trigger = {
755
- type: 'manual', // default
756
- table: table,
757
- condition: ''
758
- };
759
- if (words.includes('when') || words.includes('created') || words.includes('new')) {
760
- trigger.type = 'record_created';
761
- trigger.condition = 'state=1'; // New state
762
- }
763
- if (words.includes('updated') || words.includes('changed')) {
764
- trigger.type = 'record_updated';
765
- trigger.condition = 'state!=6'; // Not closed
766
- }
767
- if (words.includes('schedule') || words.includes('daily') || words.includes('hourly')) {
768
- trigger.type = 'scheduled';
769
- }
770
- // 🎯 Flow Name Generation - Intelligent naming
771
- let flowName = 'Custom Flow';
772
- if (intents.includes('approval'))
773
- flowName = 'Approval Workflow';
774
- if (intents.includes('incident_management'))
775
- flowName = 'Incident Management Flow';
776
- if (intents.includes('request_fulfillment'))
777
- flowName = 'Request Fulfillment Process';
778
- if (intents.includes('notification'))
779
- flowName = 'Notification Service';
780
- if (intents.includes('user_management'))
781
- flowName = 'User Management Process';
782
- if (intents.includes('data_processing'))
783
- flowName = 'Data Processing Flow';
784
- if (intents.includes('integration'))
785
- flowName = 'Integration Flow';
786
- // 🎯 Data Flow Analysis - What data needs to move between steps?
787
- const dataFlow = [];
788
- if (words.includes('translate') || words.includes('vertalen'))
789
- dataFlow.push('translation_data');
790
- if (words.includes('email') || words.includes('mail'))
791
- dataFlow.push('email_recipients');
792
- if (words.includes('user') || words.includes('gebruiker'))
793
- dataFlow.push('user_details');
794
- if (words.includes('incident'))
795
- dataFlow.push('incident_details');
796
- if (words.includes('request'))
797
- dataFlow.push('request_details');
798
- const parsed = {
799
- flowName,
800
- description: instruction,
801
- table,
802
- trigger,
803
- intents,
804
- dataFlow,
805
- complexity: intents.length > 2 ? 'high' : intents.length > 1 ? 'medium' : 'simple',
806
- language: words.includes('vertalen') || words.includes('dutch') ? 'multilingual' : 'english'
807
- };
808
- console.log('🧠 Parsed intent:', parsed);
809
- return parsed;
810
- }
811
- /**
812
- * 🧠 INTELLIGENT TEMPLATE MATCHING
813
- * Finds the best matching template based on parsed intent
814
- */
815
- async findBestTemplate(parsedIntent) {
816
- console.log('🧠 Finding best template match...');
817
- // 🎯 Template Library - Predefined patterns that work
818
- const templates = [
819
- {
820
- name: 'Approval Workflow Template',
821
- intents: ['approval'],
822
- confidence: 0.95,
823
- structure: 'approval_with_notification',
824
- activities: ['approval_step', 'notification_approved', 'notification_rejected'],
825
- tables: ['sc_request', 'sc_task', 'change_request']
826
- },
827
- {
828
- name: 'Incident Notification Template',
829
- intents: ['incident_management', 'notification'],
830
- confidence: 0.90,
831
- structure: 'incident_notification',
832
- activities: ['field_check', 'send_email', 'log_activity'],
833
- tables: ['incident', 'problem']
834
- },
835
- {
836
- name: 'Request Fulfillment Template',
837
- intents: ['request_fulfillment', 'task_management'],
838
- confidence: 0.85,
839
- structure: 'request_processing',
840
- activities: ['validate_request', 'create_task', 'notify_requester'],
841
- tables: ['sc_request', 'sc_task']
842
- },
843
- {
844
- name: 'Data Processing Template',
845
- intents: ['data_processing', 'integration'],
846
- confidence: 0.80,
847
- structure: 'data_transformation',
848
- activities: ['fetch_data', 'transform_data', 'save_data'],
849
- tables: ['*']
850
- },
851
- {
852
- name: 'User Management Template',
853
- intents: ['user_management'],
854
- confidence: 0.75,
855
- structure: 'user_lifecycle',
856
- activities: ['validate_user', 'update_profile', 'send_notification'],
857
- tables: ['sys_user', 'sys_user_group']
858
- }
859
- ];
860
- // 🎯 Smart Matching Algorithm
861
- let bestMatch = null;
862
- let highestScore = 0;
863
- for (const template of templates) {
864
- let score = 0;
865
- // Intent matching (primary factor)
866
- const intentMatches = template.intents.filter(intent => parsedIntent.intents.includes(intent)).length;
867
- score += intentMatches * 40; // 40 points per intent match
868
- // Table compatibility
869
- if (template.tables.includes(parsedIntent.table) || template.tables.includes('*')) {
870
- score += 20;
871
- }
872
- // Complexity matching
873
- const expectedActivities = template.activities.length;
874
- if (parsedIntent.complexity === 'simple' && expectedActivities <= 3)
875
- score += 15;
876
- if (parsedIntent.complexity === 'medium' && expectedActivities <= 5)
877
- score += 15;
878
- if (parsedIntent.complexity === 'high' && expectedActivities > 5)
879
- score += 15;
880
- const finalConfidence = Math.min(0.95, score / 100); // Cap at 95%
881
- if (finalConfidence > highestScore && finalConfidence >= 0.6) {
882
- highestScore = finalConfidence;
883
- bestMatch = {
884
- ...template,
885
- confidence: finalConfidence,
886
- matchScore: score
887
- };
888
- }
889
- }
890
- console.log('🧠 Best template match:', bestMatch);
891
- return bestMatch;
892
- }
893
- /**
894
- * 🧠 INTELLIGENT ARTIFACT DISCOVERY
895
- * Discovers existing ServiceNow artifacts that can be reused
896
- */
897
- async discoverRequiredArtifacts(parsedIntent) {
898
- console.log('🧠 Discovering required artifacts...');
899
- const artifacts = {
900
- existing: [],
901
- created: [],
902
- required: []
903
- };
904
- // 🎯 Based on intents, determine what artifacts are needed
905
- if (parsedIntent.intents.includes('notification')) {
906
- artifacts.required.push({
907
- type: 'email_template',
908
- purpose: 'notification',
909
- priority: 'high'
910
- });
911
- }
912
- if (parsedIntent.intents.includes('approval')) {
913
- artifacts.required.push({
914
- type: 'approval_definition',
915
- purpose: 'approval_workflow',
916
- priority: 'critical'
917
- });
918
- }
919
- if (parsedIntent.intents.includes('data_processing')) {
920
- artifacts.required.push({
921
- type: 'script_include',
922
- purpose: 'data_transformation',
923
- priority: 'medium'
924
- });
925
- }
926
- if (parsedIntent.intents.includes('integration')) {
927
- artifacts.required.push({
928
- type: 'rest_message',
929
- purpose: 'external_integration',
930
- priority: 'high'
931
- });
932
- }
933
- // 🎯 Try to discover existing artifacts (simplified for now)
934
- try {
935
- // In a real implementation, we would search ServiceNow for existing components
936
- // For now, we'll simulate discovery
937
- artifacts.existing = [];
938
- artifacts.created = artifacts.required.map(req => ({
939
- ...req,
940
- status: 'will_be_created',
941
- fallback: true
942
- }));
943
- }
944
- catch (error) {
945
- console.log('⚠️ Artifact discovery failed, will create fallbacks');
946
- artifacts.created = artifacts.required;
947
- }
948
- console.log('🧠 Discovered artifacts:', artifacts);
949
- return artifacts;
950
- }
951
- /**
952
- * 🧠 INTELLIGENT FLOW DEFINITION GENERATION
953
- * Creates complete ServiceNow Flow Designer compatible structure
954
- */
955
- async generateFlowDefinition(parsedIntent, templateMatch, artifacts) {
956
- console.log('🧠 Generating complete flow definition...');
957
- // 🎯 Base Flow Structure
958
- const flowDefinition = {
959
- name: parsedIntent.flowName,
960
- description: parsedIntent.description,
961
- active: true,
962
- trigger_type: parsedIntent.trigger.type,
963
- table: parsedIntent.table,
964
- activities: [],
965
- variables: [],
966
- error_handling: [],
967
- connections: []
968
- };
969
- // 🎯 Generate Activities based on template and intent
970
- if (templateMatch) {
971
- console.log(`🧠 Using template: ${templateMatch.name}`);
972
- flowDefinition.activities = await this.generateActivitiesFromTemplate(templateMatch, parsedIntent, artifacts);
973
- }
974
- else {
975
- console.log('🧠 No template match - generating custom activities');
976
- flowDefinition.activities = await this.generateCustomActivities(parsedIntent, artifacts);
977
- }
978
- // 🔴 BUG-003 FIX: Validate all field references against the table schema
979
- flowDefinition.activities = await this.validateAndFixFieldReferences(flowDefinition.activities, parsedIntent.table);
980
- // 🎯 Generate Variables for data flow
981
- flowDefinition.variables = this.generateFlowVariables(parsedIntent);
982
- // 🎯 Generate Error Handling
983
- flowDefinition.error_handling = this.generateErrorHandling(parsedIntent);
984
- // 🎯 Generate Connections between activities
985
- flowDefinition.connections = this.generateActivityConnections(flowDefinition.activities);
986
- console.log('🧠 Complete flow definition generated');
987
- return flowDefinition;
988
- }
989
- /**
990
- * 🔴 BUG-003 FIX: Validate and fix field references against table schema
991
- */
992
- async validateAndFixFieldReferences(activities, tableName) {
993
- console.log(`🔴 BUG-003: Validating field references for table '${tableName}'`);
994
- // Common field mappings for different tables
995
- const tableFieldMappings = {
996
- incident: {
997
- caller_id: 'caller_id',
998
- severity: 'severity',
999
- priority: 'priority',
1000
- short_description: 'short_description',
1001
- description: 'description',
1002
- assigned_to: 'assigned_to',
1003
- state: 'state',
1004
- number: 'number',
1005
- work_notes: 'work_notes',
1006
- comments: 'comments',
1007
- category: 'category',
1008
- subcategory: 'subcategory',
1009
- resolved_by: 'resolved_by',
1010
- close_notes: 'close_notes'
1011
- },
1012
- change_request: {
1013
- requested_by: 'requested_by',
1014
- category: 'category',
1015
- priority: 'priority',
1016
- risk: 'risk',
1017
- impact: 'impact',
1018
- short_description: 'short_description',
1019
- description: 'description',
1020
- assigned_to: 'assigned_to',
1021
- state: 'state',
1022
- number: 'number',
1023
- work_notes: 'work_notes',
1024
- type: 'type',
1025
- // Change request doesn't have caller_id or severity
1026
- caller_id: 'requested_by', // Map to equivalent field
1027
- severity: 'impact' // Map severity to impact for change requests
1028
- },
1029
- sc_request: {
1030
- requested_for: 'requested_for',
1031
- opened_by: 'opened_by',
1032
- short_description: 'short_description',
1033
- description: 'description',
1034
- assigned_to: 'assigned_to',
1035
- state: 'state',
1036
- number: 'number',
1037
- work_notes: 'work_notes',
1038
- comments: 'comments',
1039
- priority: 'priority',
1040
- // Service catalog requests use different field names
1041
- caller_id: 'requested_for',
1042
- severity: 'priority'
1043
- },
1044
- problem: {
1045
- opened_by: 'opened_by',
1046
- short_description: 'short_description',
1047
- description: 'description',
1048
- assigned_to: 'assigned_to',
1049
- state: 'state',
1050
- number: 'number',
1051
- work_notes: 'work_notes',
1052
- priority: 'priority',
1053
- category: 'category',
1054
- subcategory: 'subcategory',
1055
- known_error: 'known_error',
1056
- workaround: 'workaround',
1057
- // Problems don't have caller_id
1058
- caller_id: 'opened_by',
1059
- severity: 'priority'
1060
- }
1061
- };
1062
- // Get field mappings for the current table
1063
- const fieldMap = tableFieldMappings[tableName] || tableFieldMappings.incident;
1064
- // Process each activity to fix field references
1065
- const fixedActivities = activities.map(activity => {
1066
- if (activity.inputs?.script) {
1067
- // Fix field references in scripts
1068
- let fixedScript = activity.inputs.script;
1069
- // Replace field references that don't exist on the target table
1070
- Object.keys(fieldMap).forEach(standardField => {
1071
- const tableField = fieldMap[standardField];
1072
- if (standardField !== tableField) {
1073
- // Replace current.caller_id with current.requested_by for change_request, etc.
1074
- const regex = new RegExp(`current\\.${standardField}`, 'g');
1075
- fixedScript = fixedScript.replace(regex, `current.${tableField}`);
1076
- // Also handle ${record.caller_id} style references
1077
- const regex2 = new RegExp(`\\$\\{record\\.${standardField}\\}`, 'g');
1078
- fixedScript = fixedScript.replace(regex2, `\${record.${tableField}}`);
1079
- }
1080
- });
1081
- activity.inputs.script = fixedScript;
1082
- }
1083
- // Fix field references in other input fields
1084
- if (activity.inputs) {
1085
- Object.keys(activity.inputs).forEach(inputKey => {
1086
- if (typeof activity.inputs[inputKey] === 'string' && inputKey !== 'script') {
1087
- let value = activity.inputs[inputKey];
1088
- // Fix ${record.field} references
1089
- Object.keys(fieldMap).forEach(standardField => {
1090
- const tableField = fieldMap[standardField];
1091
- if (standardField !== tableField) {
1092
- const regex = new RegExp(`\\$\\{record\\.${standardField}\\}`, 'g');
1093
- value = value.replace(regex, `\${record.${tableField}}`);
1094
- }
1095
- });
1096
- activity.inputs[inputKey] = value;
1097
- }
1098
- });
1099
- }
1100
- return activity;
1101
- });
1102
- console.log(`🔴 BUG-003: Field validation complete. Fixed field references for table '${tableName}'`);
1103
- return fixedActivities;
1104
- }
1105
- /**
1106
- * Generate activities from template
1107
- */
1108
- async generateActivitiesFromTemplate(templateMatch, parsedIntent, artifacts) {
1109
- const activities = [];
1110
- switch (templateMatch.structure) {
1111
- case 'approval_with_notification':
1112
- activities.push({
1113
- id: 'approval_step',
1114
- name: 'Request Approval',
1115
- type: 'approval',
1116
- inputs: {
1117
- approver: 'admin',
1118
- message: `Please approve: ${parsedIntent.description}`,
1119
- due_date: '+7 days'
1120
- },
1121
- outputs: {
1122
- approval_result: 'string',
1123
- approved_by: 'string'
1124
- }
1125
- }, {
1126
- id: 'notification_approved',
1127
- name: 'Send Approval Notification',
1128
- type: 'notification',
1129
- condition: '${approval_step.approval_result} == "approved"',
1130
- inputs: {
1131
- recipient: '${record.requested_for}',
1132
- subject: 'Request Approved',
1133
- message: 'Your request has been approved by ${approval_step.approved_by}'
1134
- }
1135
- }, {
1136
- id: 'notification_rejected',
1137
- name: 'Send Rejection Notification',
1138
- type: 'notification',
1139
- condition: '${approval_step.approval_result} == "rejected"',
1140
- inputs: {
1141
- recipient: '${record.requested_for}',
1142
- subject: 'Request Rejected',
1143
- message: 'Your request has been rejected. Please contact support for details.'
1144
- }
1145
- });
1146
- break;
1147
- case 'incident_notification':
1148
- activities.push({
1149
- id: 'field_check',
1150
- name: 'Check Incident Priority',
1151
- type: 'condition',
1152
- condition: '${record.priority} <= 2', // High or Critical
1153
- inputs: {
1154
- field_to_check: 'priority',
1155
- operator: 'less_than_or_equal',
1156
- value: '2'
1157
- }
1158
- }, {
1159
- id: 'send_email',
1160
- name: 'Send High Priority Alert',
1161
- type: 'notification',
1162
- condition: '${field_check.result} == true',
1163
- inputs: {
1164
- recipient: 'it-management@company.com',
1165
- subject: 'HIGH PRIORITY: ${record.short_description}',
1166
- message: 'Incident ${{record.number}} requires immediate attention.\\n\\nDescription: ${{record.description}}\\nPriority: ${{record.priority}}\\nAssignee: ${{record.assigned_to}}'
1167
- }
1168
- }, {
1169
- id: 'log_activity',
1170
- name: 'Log Notification Sent',
1171
- type: 'script',
1172
- inputs: {
1173
- script: `gs.log('High priority incident notification sent for ' + current.number, 'IncidentFlow');
1174
- current.work_notes = 'Automated notification sent to IT Management';
1175
- current.update();`
1176
- }
1177
- });
1178
- break;
1179
- case 'request_processing':
1180
- activities.push({
1181
- id: 'validate_request',
1182
- name: 'Validate Request Data',
1183
- type: 'script',
1184
- inputs: {
1185
- script: `var isValid = true;
1186
- var errors = [];
1187
-
1188
- if (!current.requested_for) {
1189
- errors.push('Requested for field is required');
1190
- isValid = false;
1191
- }
1192
-
1193
- if (!current.short_description) {
1194
- errors.push('Short description is required');
1195
- isValid = false;
1196
- }
1197
-
1198
- return { valid: isValid, errors: errors };`
1199
- },
1200
- outputs: {
1201
- validation_result: 'object'
1202
- }
1203
- }, {
1204
- id: 'create_task',
1205
- name: 'Create Fulfillment Task',
1206
- type: 'create_record',
1207
- condition: '${validate_request.validation_result.valid} == true',
1208
- inputs: {
1209
- table: 'sc_task',
1210
- fields: {
1211
- request: '${record.sys_id}',
1212
- short_description: 'Fulfill: ${record.short_description}',
1213
- description: '${record.description}',
1214
- assigned_to: 'fulfillment.team',
1215
- state: '1' // Open
1216
- }
1217
- }
1218
- }, {
1219
- id: 'notify_requester',
1220
- name: 'Notify Requester',
1221
- type: 'notification',
1222
- inputs: {
1223
- recipient: '${record.requested_for}',
1224
- subject: 'Request Processing Started',
1225
- message: 'Your request ${{record.number}} is being processed.\\n\\nTask ${{create_task.result.number}} has been created for fulfillment.'
1226
- }
1227
- });
1228
- break;
1229
- case 'data_transformation':
1230
- activities.push({
1231
- id: 'fetch_data',
1232
- name: 'Fetch Record Data',
1233
- type: 'script',
1234
- inputs: {
1235
- script: `var recordData = {
1236
- sys_id: current.sys_id,
1237
- table: current.sys_class_name,
1238
- fields: {}
1239
- };
1240
-
1241
- // Get all fields and values
1242
- var fields = current.getElements();
1243
- for (var i = 0; i < fields.size(); i++) {
1244
- var field = fields.get(i);
1245
- recordData.fields[field.getName()] = current.getValue(field.getName());
1246
- }
1247
-
1248
- return recordData;`
1249
- },
1250
- outputs: {
1251
- record_data: 'object'
1252
- }
1253
- }, {
1254
- id: 'transform_data',
1255
- name: 'Transform Data',
1256
- type: 'script',
1257
- inputs: {
1258
- script: `var transformedData = fetch_data.record_data;
1259
-
1260
- // Apply transformations based on business rules
1261
- if (transformedData.fields.description) {
1262
- transformedData.fields.description = transformedData.fields.description.toUpperCase();
1263
- }
1264
-
1265
- transformedData.transformed_at = new GlideDateTime().toString();
1266
- transformedData.transform_id = gs.generateGUID();
1267
-
1268
- return transformedData;`
1269
- },
1270
- outputs: {
1271
- transformed_data: 'object'
1272
- }
1273
- }, {
1274
- id: 'save_data',
1275
- name: 'Save Transformed Data',
1276
- type: 'create_record',
1277
- inputs: {
1278
- table: 'u_transformed_data', // Custom table
1279
- fields: {
1280
- original_record: '${fetch_data.record_data.sys_id}',
1281
- transformed_data: '${transform_data.transformed_data}',
1282
- processed_date: '${gs.nowDateTime()}'
1283
- }
1284
- }
1285
- });
1286
- break;
1287
- default:
1288
- // Fallback to custom activities
1289
- return await this.generateCustomActivities(parsedIntent, artifacts);
1290
- }
1291
- return activities;
1292
- }
1293
- /**
1294
- * Generate custom activities when no template matches
1295
- */
1296
- async generateCustomActivities(parsedIntent, artifacts) {
1297
- const activities = [];
1298
- // 🎯 Always start with validation for data integrity
1299
- activities.push({
1300
- id: 'validate_input',
1301
- name: 'Validate Input Data',
1302
- type: 'script',
1303
- inputs: {
1304
- script: `var result = { valid: true, message: 'Input validation passed' };
1305
-
1306
- // Basic validation logic
1307
- if (!current) {
1308
- result.valid = false;
1309
- result.message = 'No record context available';
1310
- }
1311
-
1312
- return result;`
1313
- },
1314
- outputs: {
1315
- validation_result: 'object'
1316
- }
1317
- });
1318
- // 🎯 Add activities based on detected intents
1319
- if (parsedIntent.intents.includes('notification')) {
1320
- activities.push({
1321
- id: 'send_notification',
1322
- name: 'Send Notification',
1323
- type: 'notification',
1324
- condition: '${validate_input.validation_result.valid} == true',
1325
- inputs: {
1326
- recipient: 'admin@company.com',
1327
- subject: 'Flow Notification: ${{record.short_description}}',
1328
- message: 'A flow has been triggered for record ${{record.number}}\\n\\nDetails: ${{record.description}}'
1329
- }
1330
- });
1331
- }
1332
- if (parsedIntent.intents.includes('data_processing')) {
1333
- activities.push({
1334
- id: 'process_data',
1335
- name: 'Process Record Data',
1336
- type: 'script',
1337
- inputs: {
1338
- script: `// Process the record data
1339
- current.work_notes = 'Processed by automated flow on ' + new GlideDateTime();
1340
- current.state = 2; // In Progress
1341
- current.update();
1342
-
1343
- gs.log('Record processed by flow: ' + current.number, 'CustomFlow');`
1344
- }
1345
- });
1346
- }
1347
- // 🎯 Always end with logging for audit trail
1348
- activities.push({
1349
- id: 'log_completion',
1350
- name: 'Log Flow Completion',
1351
- type: 'script',
1352
- inputs: {
1353
- script: `gs.log('Flow completed successfully for record: ' + current.number, 'FlowCompletion');
1354
-
1355
- // Update record with completion timestamp
1356
- current.u_flow_completed = new GlideDateTime();
1357
- current.update();`
1358
- }
1359
- });
1360
- return activities;
1361
- }
1362
- /**
1363
- * Generate flow variables for data passing
1364
- */
1365
- generateFlowVariables(parsedIntent) {
1366
- const variables = [
1367
- {
1368
- id: 'flow_start_time',
1369
- name: 'Flow Start Time',
1370
- type: 'datetime',
1371
- input: false,
1372
- output: true,
1373
- default_value: '${gs.nowDateTime()}'
1374
- },
1375
- {
1376
- id: 'record_context',
1377
- name: 'Record Context',
1378
- type: 'reference',
1379
- input: true,
1380
- output: false,
1381
- table: parsedIntent.table
1382
- }
1383
- ];
1384
- // Add intent-specific variables
1385
- if (parsedIntent.intents.includes('approval')) {
1386
- variables.push({
1387
- id: 'approval_result',
1388
- name: 'Approval Result',
1389
- type: 'string',
1390
- input: false,
1391
- output: true,
1392
- default_value: ''
1393
- });
1394
- }
1395
- if (parsedIntent.intents.includes('notification')) {
1396
- variables.push({
1397
- id: 'notification_sent',
1398
- name: 'Notification Sent',
1399
- type: 'boolean',
1400
- input: false,
1401
- output: true,
1402
- default_value: 'false'
1403
- });
1404
- }
1405
- return variables;
1406
- }
1407
- /**
1408
- * Generate error handling activities
1409
- */
1410
- generateErrorHandling(parsedIntent) {
1411
- return [
1412
- {
1413
- id: 'error_handler',
1414
- name: 'Handle Flow Errors',
1415
- type: 'script',
1416
- trigger: 'on_error',
1417
- inputs: {
1418
- script: `gs.error('Flow error occurred: ' + error.message, 'FlowError');
1419
-
1420
- // Send error notification
1421
- var email = new GlideEmailOutbound();
1422
- email.setSubject('Flow Error in ${parsedIntent.flowName}');
1423
- email.setBody('An error occurred during flow execution: ' + error.message);
1424
- email.addAddress('admin@company.com');
1425
- email.send();
1426
-
1427
- // Log to system log
1428
- gs.log('Flow error logged and notification sent', 'FlowError');`
1429
- }
1430
- }
1431
- ];
1432
- }
1433
- /**
1434
- * Generate connections between activities
1435
- */
1436
- generateActivityConnections(activities) {
1437
- const connections = [];
1438
- for (let i = 0; i < activities.length - 1; i++) {
1439
- connections.push({
1440
- from: activities[i].id,
1441
- to: activities[i + 1].id,
1442
- condition: activities[i + 1].condition || 'always'
1443
- });
1444
- }
1445
- return connections;
1446
- }
1447
- async analyzeFlowInstruction(args) {
1448
- // Check authentication first
1449
- const isAuth = await this.oauth.isAuthenticated();
1450
- if (!isAuth) {
1451
- return {
1452
- content: [
1453
- {
1454
- type: 'text',
1455
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
1456
- },
1457
- ],
1458
- };
1459
- }
1460
- try {
1461
- this.logger.info('Analyzing flow instruction', { instruction: args.instruction });
1462
- const flowInstruction = await this.composer.createFlowFromInstruction(args.instruction);
1463
- return {
1464
- content: [
1465
- {
1466
- type: 'text',
1467
- text: `🔍 Flow Instruction Analysis
1468
-
1469
- 📝 **Original Instruction:**
1470
- "${args.instruction}"
1471
-
1472
- 🧠 **Parsed Intent:**
1473
- - **Flow Name**: ${flowInstruction.parsedIntent?.flowName || 'Auto-generated'}
1474
- - **Table**: ${flowInstruction.parsedIntent?.table || 'Unknown'}
1475
- - **Trigger Type**: ${flowInstruction.parsedIntent?.trigger?.type || 'Unknown'}
1476
- - **Condition**: ${flowInstruction.parsedIntent?.trigger?.condition || 'None'}
1477
- - **Intents**: ${flowInstruction.parsedIntent?.intents?.join(', ') || 'None'}
1478
- - **Data Flow**: ${flowInstruction.parsedIntent?.dataFlow?.join(' → ') || 'None'}
1479
-
1480
- 🔧 **Required Artifacts:**
1481
- ${flowInstruction.requiredArtifacts?.map((artifact, index) => `${index + 1}. **${artifact.type}**
1482
- - Name: ${artifact.name}
1483
- - Sys ID: ${artifact.sys_id}
1484
- - Inputs: ${artifact.inputs?.length || 0} input(s)
1485
- - Outputs: ${artifact.outputs?.length || 0} output(s)`)?.join('\n\n') || 'No required artifacts'}
1486
-
1487
- 🏗️ **Flow Structure Preview:**
1488
- - **Name**: ${flowInstruction.flowStructure?.name || 'Unknown'}
1489
- - **Trigger**: ${flowInstruction.flowStructure?.trigger?.type || 'Unknown'} on ${flowInstruction.flowStructure?.trigger?.table || 'Unknown'}
1490
- - **Activities**: ${flowInstruction.flowStructure?.activities?.length || 0}
1491
- - **Variables**: ${flowInstruction.flowStructure?.variables?.length || 0}
1492
- - **Error Handling**: ${flowInstruction.flowStructure?.error_handling?.length || 0} rules
1493
-
1494
- 📊 **Complexity Analysis:**
1495
- - **Artifact Dependencies**: ${flowInstruction.requiredArtifacts?.length || 0}
1496
- - **Processing Steps**: ${flowInstruction.flowStructure?.activities?.length || 0}
1497
- - **Integration Points**: ${flowInstruction.requiredArtifacts?.length || 0}
1498
- - **Data Flow Steps**: ${flowInstruction.parsedIntent?.dataFlow?.length || 0}
1499
-
1500
- ✅ **Analysis Complete!** The instruction has been successfully parsed and all required components identified.`,
1501
- },
1502
- ],
1503
- };
1504
- }
1505
- catch (error) {
1506
- throw new Error(`Flow instruction analysis failed: ${error instanceof Error ? error.message : String(error)}`);
1507
- }
1508
- }
1509
- async discoverFlowArtifacts(args) {
1510
- // Check authentication first
1511
- const isAuth = await this.oauth.isAuthenticated();
1512
- if (!isAuth) {
1513
- return {
1514
- content: [
1515
- {
1516
- type: 'text',
1517
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
1518
- },
1519
- ],
1520
- };
1521
- }
1522
- try {
1523
- this.logger.info('Discovering flow artifacts', { instruction: args.instruction });
1524
- const flowInstruction = await this.composer.createFlowFromInstruction(args.instruction);
1525
- // Filter by specific artifact types if requested
1526
- let artifactsToShow = flowInstruction.requiredArtifacts;
1527
- if (args.artifact_types && args.artifact_types.length > 0) {
1528
- artifactsToShow = flowInstruction.requiredArtifacts?.filter((a) => args.artifact_types.includes(a.type));
1529
- }
1530
- const credentials = await this.oauth.loadCredentials();
1531
- return {
1532
- content: [
1533
- {
1534
- type: 'text',
1535
- text: `🔍 ServiceNow Artifact Discovery Results
1536
-
1537
- 🎯 **Instruction**: "${args.instruction}"
1538
-
1539
- 📦 **Discovered Artifacts** (${artifactsToShow.length} found):
1540
-
1541
- ${artifactsToShow.map((artifact, index) => `### ${index + 1}. ${artifact.type.toUpperCase()}
1542
- **Purpose**: ${artifact.purpose}
1543
- **Search Strategy**: "${artifact.searchQuery}"
1544
- **Required**: ${artifact.required ? '✅ Yes' : '❌ No'}
1545
- **Fallback**: ${artifact.fallbackAction || 'None'}
1546
-
1547
- **Search Details:**
1548
- - Table: ${this.getTableForArtifactType(artifact.type)}
1549
- - Search Fields: name, description, short_description
1550
- - Match Priority: Exact → Fuzzy → Semantic
1551
-
1552
- **Integration Points:**
1553
- - Used in flow step: ${this.getFlowStepForArtifact(artifact, flowInstruction)}
1554
- - Data inputs: ${this.getArtifactInputs(artifact)}
1555
- - Data outputs: ${this.getArtifactOutputs(artifact)}
1556
- `).join('\n')}
1557
-
1558
- 🔗 **ServiceNow Search Links:**
1559
- ${artifactsToShow.map((artifact) => `- ${artifact.type}: https://${credentials?.instance}/nav_to.do?uri=${this.getTableForArtifactType(artifact.type)}_list.do`).join('\n')}
1560
-
1561
- 💡 **Discovery Strategy:**
1562
- 1. **Intelligent Search**: Uses natural language processing to find relevant artifacts
1563
- 2. **Semantic Matching**: Matches purpose and functionality, not just names
1564
- 3. **Fallback Creation**: Creates missing artifacts automatically if needed
1565
- 4. **Dependency Mapping**: Identifies relationships between artifacts
1566
-
1567
- 🎯 **Next Steps:**
1568
- - Run \`snow_preview_flow_structure\` to see how these artifacts will be used
1569
- - Use \`snow_create_complex_flow\` to create and deploy the complete flow
1570
- - Individual artifacts can be analyzed using \`snow_analyze_artifact\`
1571
-
1572
- ✅ **Discovery Complete!** All required artifacts have been identified and are ready for flow composition.`,
1573
- },
1574
- ],
1575
- };
1576
- }
1577
- catch (error) {
1578
- throw new Error(`Artifact discovery failed: ${error instanceof Error ? error.message : String(error)}`);
1579
- }
1580
- }
1581
- /**
1582
- * Extract a flow name from instruction text
1583
- */
1584
- extractFlowName(instruction) {
1585
- // Try to extract meaningful name from instruction
1586
- const keywords = ['flow', 'process', 'workflow', 'automation'];
1587
- const words = instruction.toLowerCase().split(/\s+/);
1588
- // Look for keywords and use surrounding context
1589
- for (const keyword of keywords) {
1590
- const keywordIndex = words.indexOf(keyword);
1591
- if (keywordIndex >= 0) {
1592
- // Get 2-3 words before the keyword as the name
1593
- const startIndex = Math.max(0, keywordIndex - 2);
1594
- const nameParts = words.slice(startIndex, keywordIndex + 1);
1595
- return nameParts.join('_').replace(/[^a-z0-9_]/g, '');
1596
- }
1597
- }
1598
- // Fallback: use first few words
1599
- return words.slice(0, 3).join('_').replace(/[^a-z0-9_]/g, '') + '_flow';
1600
- }
1601
- async previewFlowStructure(args) {
1602
- // Check authentication first
1603
- const isAuth = await this.oauth.isAuthenticated();
1604
- if (!isAuth) {
1605
- return {
1606
- content: [
1607
- {
1608
- type: 'text',
1609
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
1610
- },
1611
- ],
1612
- };
1613
- }
1614
- try {
1615
- this.logger.info('Previewing flow structure', { instruction: args.instruction });
1616
- const flowInstruction = await this.composer.createFlowFromInstruction(args.instruction);
1617
- // FIX: Add null safety checks to prevent "Cannot read properties of undefined" errors
1618
- if (!flowInstruction || !flowInstruction.flowStructure) {
1619
- this.logger.error('Flow instruction or flowStructure is undefined', { flowInstruction });
1620
- // Create minimal fallback flow structure
1621
- const fallbackFlow = {
1622
- name: this.extractFlowName(args.instruction),
1623
- description: `Flow for: ${args.instruction}`,
1624
- trigger: { type: 'manual', table: 'task', condition: '' },
1625
- variables: [],
1626
- activities: [],
1627
- error_handling: []
1628
- };
1629
- return {
1630
- content: [{
1631
- type: 'text',
1632
- text: `⚠️ **Flow Structure Creation Issue**
1633
-
1634
- The flow composer returned incomplete data. Creating minimal flow structure:
1635
-
1636
- 📋 **Flow Information:**
1637
- - **Name**: ${fallbackFlow.name}
1638
- - **Description**: ${fallbackFlow.description}
1639
- - **Type**: Manual trigger on task table
1640
-
1641
- 💡 **Suggestion**: Try being more specific with your flow requirements, for example:
1642
- - "Create an approval flow for incident management"
1643
- - "Build a notification flow when priority 1 incidents are created"
1644
- - "Design a flow to update request items when approved"
1645
-
1646
- 🔧 **Debug Info**: flowInstruction=${JSON.stringify(flowInstruction ? Object.keys(flowInstruction) : 'null')}`
1647
- }]
1648
- };
1649
- }
1650
- const flowStructure = flowInstruction.flowStructure;
1651
- // Additional safety checks for flowStructure properties
1652
- const safeGet = (obj, path, defaultValue = 'Unknown') => {
1653
- const parts = path.split('.');
1654
- let current = obj;
1655
- for (const part of parts) {
1656
- if (!current || typeof current !== 'object')
1657
- return defaultValue;
1658
- current = current[part];
1659
- }
1660
- return current || defaultValue;
1661
- };
1662
- return {
1663
- content: [
1664
- {
1665
- type: 'text',
1666
- text: `🔍 Flow Structure Preview
1667
-
1668
- 📋 **Flow Information:**
1669
- - **Name**: ${safeGet(flowStructure, 'name', 'Auto-generated')}
1670
- - **Description**: ${safeGet(flowStructure, 'description', 'No description')}
1671
-
1672
- 🔄 **Trigger Configuration:**
1673
- - **Type**: ${safeGet(flowStructure, 'trigger.type', 'manual')}
1674
- - **Table**: ${safeGet(flowStructure, 'trigger.table', 'task')}
1675
- - **Condition**: ${safeGet(flowStructure, 'trigger.condition', 'None')}
1676
-
1677
- 📊 **Flow Variables:**
1678
- ${flowStructure.variables && Array.isArray(flowStructure.variables)
1679
- ? flowStructure.variables.map((variable) => `- **${variable.name}** (${variable.type}): ${variable.description}`).join('\n')
1680
- : '- No variables defined'}
1681
-
1682
- 🏗️ **Flow Activities:**
1683
- ${flowStructure.activities.map((activity, index) => `### ${index + 1}. ${activity.name}
1684
- **Type**: ${activity.type}
1685
- **ID**: ${activity.id}
1686
- ${activity.artifact ? `**Uses Artifact**: ${activity.artifact.name} (${activity.artifact.type})` : ''}
1687
-
1688
- **Inputs:**
1689
- ${Object.entries(activity.inputs).map(([key, value]) => ` - ${key}: ${value}`).join('\n')}
1690
-
1691
- **Outputs:**
1692
- ${Object.entries(activity.outputs).map(([key, value]) => ` - ${key}: ${value}`).join('\n')}
1693
- `).join('\n')}
1694
-
1695
- ⚠️ **Error Handling:**
1696
- ${flowStructure.error_handling.map((handler, index) => `${index + 1}. **Condition**: ${handler.condition}
1697
- **Action**: ${handler.action}
1698
- **Parameters**: ${JSON.stringify(handler.parameters || {})}`).join('\n\n')}
1699
-
1700
- 🔄 **Flow Execution Path:**
1701
- 1. **${flowStructure.trigger.type}** event occurs on **${flowStructure.trigger.table}**
1702
- ${flowStructure.activities.map((activity, index) => `${index + 2}. Execute **${activity.name}** (${activity.type})`).join('\n')}
1703
-
1704
- 📈 **Flow Metrics:**
1705
- - **Total Activities**: ${flowStructure.activities.length}
1706
- - **Variables**: ${flowStructure.variables.length}
1707
- - **Error Handlers**: ${flowStructure.error_handling.length}
1708
- - **Artifact Dependencies**: ${flowStructure.activities.filter((a) => a.artifact).length}
1709
- - **External Integrations**: ${flowStructure.activities.filter((a) => a.type === 'custom_script').length}
1710
-
1711
- 🎯 **Data Flow Analysis:**
1712
- ${this.analyzeDataFlow(flowStructure.activities)}
1713
-
1714
- ✅ **Preview Complete!** The flow structure is optimized and ready for deployment.
1715
-
1716
- 🚀 **To Deploy**: Use \`snow_deploy_composed_flow\` or \`snow_create_complex_flow\` with \`deploy_immediately: true\``,
1717
- },
1718
- ],
1719
- };
1720
- }
1721
- catch (error) {
1722
- throw new Error(`Flow structure preview failed: ${error instanceof Error ? error.message : String(error)}`);
1723
- }
1724
- }
1725
- async deployComposedFlow(args) {
1726
- // Check authentication first
1727
- const isAuth = await this.oauth.isAuthenticated();
1728
- if (!isAuth) {
1729
- return {
1730
- content: [
1731
- {
1732
- type: 'text',
1733
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
1734
- },
1735
- ],
1736
- };
1737
- }
1738
- try {
1739
- this.logger.info('Deploying composed flow', { flow: args.flow_instruction });
1740
- const deploymentResult = await this.composer.deployFlow(args.flow_instruction);
1741
- const credentials = await this.oauth.loadCredentials();
1742
- return {
1743
- content: [
1744
- {
1745
- type: 'text',
1746
- text: `🚀 Flow Deployment Complete!
1747
-
1748
- ✅ **Deployment Status**: ${deploymentResult.success ? 'Successful' : 'Failed'}
1749
- 📋 **Message**: ${deploymentResult.message}
1750
-
1751
- 🎯 **Deployed Flow Details:**
1752
- - **Name**: ${args.flow_instruction.flowStructure.name}
1753
- - **Activities**: ${args.flow_instruction.flowStructure.activities.length}
1754
- - **Artifacts**: ${args.flow_instruction.requiredArtifacts?.length || 0}
1755
-
1756
- 🔗 **ServiceNow Links:**
1757
- - Flow Designer: https://${credentials?.instance}/flow-designer/flow/${args.flow_instruction.flowStructure.name}
1758
- - Flow Designer Home: https://${credentials?.instance}/flow-designer
1759
-
1760
- 📊 **Deployment Summary:**
1761
- ${args.flow_instruction.requiredArtifacts?.map((artifact, index) => `${index + 1}. **${artifact.type}**: ${artifact.purpose} - ${artifact.required ? 'Required' : 'Optional'}`)?.join('\n') || 'No artifacts'}
1762
-
1763
- ✅ **Deployment Complete!** Your complex ServiceNow flow with multi-artifact orchestration is now active.`,
1764
- },
1765
- ],
1766
- };
1767
- }
1768
- catch (error) {
1769
- throw new Error(`Flow deployment failed: ${error instanceof Error ? error.message : String(error)}`);
1770
- }
1771
- }
1772
- getTableForArtifactType(type) {
1773
- const tableMapping = {
1774
- 'script_include': 'sys_script_include',
1775
- 'business_rule': 'sys_script',
1776
- 'table': 'sys_db_object',
1777
- 'widget': 'sp_widget',
1778
- 'ui_script': 'sys_ui_script'
1779
- };
1780
- return tableMapping[type] || 'sys_metadata';
1781
- }
1782
- getFlowStepForArtifact(artifact, flowInstruction) {
1783
- const step = flowInstruction.flowStructure?.activities?.find((a) => a.artifact_reference && a.artifact_reference.type === artifact.type);
1784
- return step ? step.name : 'Not used in flow';
1785
- }
1786
- getArtifactInputs(artifact) {
1787
- switch (artifact.type) {
1788
- case 'script_include':
1789
- return 'message, target_language, configuration';
1790
- case 'business_rule':
1791
- return 'record data, trigger conditions';
1792
- case 'table':
1793
- return 'record data, field values';
1794
- default:
1795
- return 'context-dependent';
1796
- }
1797
- }
1798
- getArtifactOutputs(artifact) {
1799
- switch (artifact.type) {
1800
- case 'script_include':
1801
- return 'processed_data, success_flag, error_message';
1802
- case 'business_rule':
1803
- return 'validation_result, side_effects';
1804
- case 'table':
1805
- return 'record_id, created_timestamp';
1806
- default:
1807
- return 'context-dependent';
1808
- }
1809
- }
1810
- analyzeDataFlow(activities) {
1811
- let dataFlow = "Data flows through the following path:\n";
1812
- activities.forEach((activity, index) => {
1813
- const inputs = Object.keys(activity.inputs).join(', ');
1814
- const outputs = Object.keys(activity.outputs).join(', ');
1815
- dataFlow += `${index + 1}. **${activity.name}**: ${inputs} → ${outputs}\n`;
1816
- });
1817
- return dataFlow;
1818
- }
1819
- /**
1820
- * Enhanced error handling for ServiceNow API operations
1821
- */
1822
- handleServiceNowError(error, operation) {
1823
- this.logger.error(`ServiceNow API error during ${operation}`, error);
1824
- let errorMessage = 'Unknown error occurred';
1825
- let troubleshooting = [];
1826
- if (error.response) {
1827
- const status = error.response.status;
1828
- const data = error.response.data;
1829
- switch (status) {
1830
- case 401:
1831
- errorMessage = `🚨 Authentication Error (401) - Token Expired or Invalid
1832
-
1833
- 📍 Possible Causes:
1834
- • OAuth token expired or invalid
1835
- • ServiceNow instance URL incorrect
1836
- • Credentials not properly configured
1837
-
1838
- 🔧 Troubleshooting Steps:
1839
- 1. Run diagnostics: snow_auth_diagnostics()
1840
- 2. Re-authenticate: snow-flow auth login
1841
- 3. Check credentials: Verify SNOW_INSTANCE, CLIENT_ID, CLIENT_SECRET
1842
- 4. Verify instance URL format: https://dev123456.service-now.com
1843
-
1844
- 💡 Quick Fix: Run snow_auth_diagnostics() for detailed analysis`;
1845
- troubleshooting = [
1846
- 'Run snow_auth_diagnostics() for detailed analysis',
1847
- 'Re-authenticate with snow-flow auth login',
1848
- 'Verify .env file OAuth credentials',
1849
- 'Check ServiceNow instance URL format'
1850
- ];
1851
- break;
1852
- case 403:
1853
- errorMessage = `🚨 Permission Error (403) - Insufficient Access Rights
1854
-
1855
- 📍 Possible Causes:
1856
- • Insufficient permissions for flow operations
1857
- • Missing required ServiceNow roles
1858
- • Application scope restrictions
1859
-
1860
- 🔧 Troubleshooting Steps:
1861
- 1. Run diagnostics: snow_auth_diagnostics()
1862
- 2. Check required roles: flow_designer, admin, itil
1863
- 3. Contact ServiceNow administrator for role assignment
1864
- 4. Verify application scope permissions
1865
-
1866
- 💡 Required Roles:
1867
- • flow_designer: For flow operations
1868
- • admin: For Update Set management
1869
- • itil: For incident/request operations`;
1870
- troubleshooting = [
1871
- 'Run snow_auth_diagnostics() to check permissions',
1872
- 'Verify user has flow_designer, admin, itil roles',
1873
- 'Contact ServiceNow administrator for role assignment',
1874
- 'Check application scope permissions'
1875
- ];
1876
- break;
1877
- case 404:
1878
- errorMessage = `🚨 Flow Testing failed: Endpoint not found (404)
1879
-
1880
- 📍 Possible Causes:
1881
- • Flow sys_id format incorrect or invalid
1882
- • API endpoint not available on this ServiceNow instance
1883
- • Insufficient permissions for this operation
1884
- • Flow not properly created or activated
1885
-
1886
- 🔧 Troubleshooting Steps:
1887
- 1. Verify artifact exists: snow_get_by_sysid("your-sys-id")
1888
- 2. Check Update Set tracking: snow_update_set_current()
1889
- 3. Try alternative: snow_test_flow_with_mock()
1890
- 4. Verify permissions: snow_auth_diagnostics()
1891
-
1892
- 💡 Alternative Tools:
1893
- • For flow testing: Use snow_test_flow_with_mock (always works)
1894
- • For verification: Use snow_get_by_sysid first
1895
- • For comprehensive testing: Only after basic tests pass`;
1896
- troubleshooting = [
1897
- 'Use snow_test_flow_with_mock() for reliable testing',
1898
- 'Verify flow exists with snow_get_by_sysid()',
1899
- 'Check Update Set status with snow_update_set_current()',
1900
- 'Run snow_auth_diagnostics() to check permissions'
1901
- ];
1902
- break;
1903
- case 429:
1904
- errorMessage = 'Rate limit exceeded';
1905
- troubleshooting = [
1906
- 'Wait a few minutes before retrying',
1907
- 'Reduce the frequency of API calls',
1908
- 'Contact ServiceNow administrator about rate limits'
1909
- ];
1910
- break;
1911
- case 500:
1912
- errorMessage = 'ServiceNow server error';
1913
- troubleshooting = [
1914
- 'Wait a few minutes and try again',
1915
- 'Check ServiceNow instance status',
1916
- 'Contact ServiceNow administrator if issue persists'
1917
- ];
1918
- break;
1919
- default:
1920
- errorMessage = data?.error?.message || `HTTP ${status} error`;
1921
- troubleshooting = [
1922
- 'Check ServiceNow instance connectivity',
1923
- 'Verify API permissions',
1924
- 'Review ServiceNow logs for details'
1925
- ];
1926
- }
1927
- }
1928
- else if (error.request) {
1929
- errorMessage = 'Network connection error';
1930
- troubleshooting = [
1931
- 'Check internet connectivity',
1932
- 'Verify ServiceNow instance URL',
1933
- 'Check if ServiceNow instance is accessible'
1934
- ];
1935
- }
1936
- else {
1937
- errorMessage = error.message || 'Unknown error';
1938
- troubleshooting = [
1939
- 'Check the instruction syntax',
1940
- 'Verify all required parameters are provided',
1941
- 'Try a simpler instruction to isolate the issue'
1942
- ];
1943
- }
1944
- return {
1945
- content: [
1946
- {
1947
- type: 'text',
1948
- text: `❌ ${operation} Failed
1949
-
1950
- **Error Details:**
1951
- ${errorMessage}
1952
-
1953
- **Troubleshooting Steps:**
1954
- ${troubleshooting.map((step, index) => `${index + 1}. ${step}`).join('\n')}
1955
-
1956
- **Additional Help:**
1957
- - Check ServiceNow instance health: https://status.servicenow.com/
1958
- - Review ServiceNow API documentation
1959
- - Contact your ServiceNow administrator for permissions
1960
- - Try using basic functionality first before advanced features
1961
-
1962
- **Alternative Approaches:**
1963
- - Use simpler instructions with fewer components
1964
- - Try analysis tools first (e.g., \`snow_analyze_flow_instruction\`)
1965
- - Use template matching for common patterns
1966
- - Break complex flows into smaller parts`,
1967
- },
1968
- ],
1969
- };
1970
- }
1971
- /**
1972
- * Retry operation with exponential backoff
1973
- */
1974
- async retryOperation(operation, operationName, maxRetries = 3, baseDelay = 1000) {
1975
- let lastError;
1976
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
1977
- try {
1978
- this.logger.info(`Attempting ${operationName} (attempt ${attempt}/${maxRetries})`);
1979
- return await operation();
1980
- }
1981
- catch (error) {
1982
- lastError = error;
1983
- if (attempt === maxRetries) {
1984
- break;
1985
- }
1986
- // Don't retry on authentication or permission errors
1987
- if (error.response?.status === 401 || error.response?.status === 403) {
1988
- break;
1989
- }
1990
- // Don't retry on client errors (except rate limiting)
1991
- if (error.response?.status >= 400 && error.response?.status < 500 && error.response?.status !== 429) {
1992
- break;
1993
- }
1994
- const delay = baseDelay * Math.pow(2, attempt - 1);
1995
- this.logger.warn(`${operationName} failed (attempt ${attempt}), retrying in ${delay}ms`, error);
1996
- await new Promise(resolve => setTimeout(resolve, delay));
1997
- }
1998
- }
1999
- throw lastError;
2000
- }
2001
- /**
2002
- * Format intelligent analysis results for display
2003
- */
2004
- formatIntelligentAnalysis(flowInstruction) {
2005
- // Backward compatibility - handle cases where intelligent analysis is not available
2006
- if (!flowInstruction.decisionAnalysis && !flowInstruction.validation &&
2007
- !flowInstruction.templateMatching && !flowInstruction.subflowCreation) {
2008
- return `📊 **Flow Analysis:**
2009
- - **Type**: Standard flow creation
2010
- - **Processing**: Basic natural language processing applied
2011
- - **Deployment**: Ready for ServiceNow deployment`;
2012
- }
2013
- const analysis = flowInstruction.decisionAnalysis;
2014
- const validation = flowInstruction.validation;
2015
- const templateMatching = flowInstruction.templateMatching;
2016
- const subflowCreation = flowInstruction.subflowCreation;
2017
- let analysisText = '🧠 **Intelligent Analysis Results:**\n\n';
2018
- // Decision analysis (if available)
2019
- if (analysis) {
2020
- analysisText += `📊 **Decision Analysis:**
2021
- - **Recommended Type**: ${analysis.recommendedType} (${Math.round(analysis.confidence * 100)}% confidence)
2022
- - **Rationale**: ${analysis.rationale}
2023
- - **Complexity**: ${analysis.complexity}
2024
- - **Reusability**: ${analysis.reusability}
2025
- - **Context**: ${analysis.context}
2026
-
2027
- `;
2028
- }
2029
- // Validation results (if available)
2030
- if (validation) {
2031
- analysisText += `✅ **Validation Results:**
2032
- - **Valid**: ${validation.isValid ? 'Yes' : 'No'}
2033
- - **Score**: ${validation.score}/${validation.maxScore}
2034
- - **Severity**: ${validation.severity}
2035
- - **Issues**: ${validation.issues?.length || 0} identified
2036
- - **Recommendations**: ${validation.recommendations?.length || 0} provided
2037
-
2038
- `;
2039
- }
2040
- // Template matching (if available)
2041
- if (templateMatching) {
2042
- analysisText += `🎯 **Template Matching:**
2043
- - **Matches Found**: ${templateMatching.matches}
2044
- - **Best Match**: ${templateMatching.bestMatch || 'None'}
2045
- - **Match Confidence**: ${Math.round(templateMatching.confidence * 100)}%
2046
-
2047
- `;
2048
- }
2049
- // Subflow creation (if available)
2050
- if (subflowCreation) {
2051
- analysisText += `🔄 **Subflow Creation:**
2052
- - **Candidates Identified**: ${subflowCreation.candidatesIdentified}
2053
- - **Subflows Created**: ${subflowCreation.subflowsCreated}
2054
- - **Success Rate**: ${subflowCreation.candidatesIdentified > 0 ? Math.round((subflowCreation.subflowsCreated / subflowCreation.candidatesIdentified) * 100) : 0}%
2055
-
2056
- `;
2057
- }
2058
- // Recommendations
2059
- analysisText += `💡 **Recommendations:**
2060
- ${flowInstruction.recommendations?.map((rec, index) => `${index + 1}. ${rec}`).join('\n') || 'No specific recommendations'}`;
2061
- return analysisText;
2062
- }
2063
- /**
2064
- * Safe method to access composer features with fallback
2065
- */
2066
- async safeComposerOperation(operation, fallbackOperation, operationName) {
2067
- try {
2068
- return await operation();
2069
- }
2070
- catch (error) {
2071
- this.logger.warn(`${operationName} failed, falling back to basic operation`, error);
2072
- return await fallbackOperation();
2073
- }
2074
- }
2075
- /**
2076
- * Intelligent flow analysis tool
2077
- */
2078
- async intelligentFlowAnalysis(args) {
2079
- const isAuth = await this.oauth.isAuthenticated();
2080
- if (!isAuth) {
2081
- return {
2082
- content: [
2083
- {
2084
- type: 'text',
2085
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
2086
- },
2087
- ],
2088
- };
2089
- }
2090
- try {
2091
- this.logger.info('Performing intelligent flow analysis', { instruction: args.instruction });
2092
- const analysisResult = await this.composer.getFlowAnalysisSummary(args.instruction);
2093
- return {
2094
- content: [
2095
- {
2096
- type: 'text',
2097
- text: `🧠 Intelligent Flow Analysis Results
2098
-
2099
- 📝 **Original Instruction:**
2100
- "${args.instruction}"
2101
-
2102
- 🎯 **Decision Analysis:**
2103
- - **Recommended Type**: ${analysisResult.decision?.recommendedType || 'Unknown'}
2104
- - **Confidence**: ${analysisResult.decision?.confidence ? Math.round(analysisResult.decision.confidence * 100) + '%' : 'Unknown'}
2105
- - **Rationale**: ${analysisResult.decision?.rationale || 'No rationale provided'}
2106
-
2107
- 📊 **Complexity Assessment:**
2108
- - **Level**: ${analysisResult.complexity || 'Unknown'}
2109
- - **Reusability**: ${analysisResult.reusability || 'Unknown'}
2110
- - **Context**: ${analysisResult.context || 'Unknown'}
2111
-
2112
- ✅ **Validation Results:**
2113
- - **Valid**: ${analysisResult.validation?.isValid ? 'Yes' : 'No'}
2114
- - **Score**: ${analysisResult.validation?.score || 0}/${analysisResult.validation?.maxScore || 0}
2115
-
2116
- 🎯 **Template Matching:**
2117
- - **Matches Found**: ${analysisResult.templates?.matchCount || 0}
2118
- - **Best Match**: ${analysisResult.templates?.bestMatch || 'None'}
2119
- - **Confidence**: ${analysisResult.templates?.confidence ? Math.round(analysisResult.templates.confidence * 100) + '%' : 'N/A'}
2120
-
2121
- 🔄 **Subflow Opportunities:**
2122
- - **Candidates Identified**: ${analysisResult.subflowCandidates || 0}
2123
- - **Alternatives Available**: ${analysisResult.alternatives?.length || 0}
2124
-
2125
- 💡 **Key Insights:**
2126
- - Flow complexity suggests ${analysisResult.complexity === 'high' ? 'breaking into smaller components' : 'keeping as single flow'}
2127
- - ${analysisResult.reusability === 'high' ? 'High reusability indicates subflow opportunities' : 'Low reusability suggests single-use flow'}
2128
- - ${analysisResult.templates?.matchCount > 0 ? 'Template matching available for consistency' : 'Custom implementation required'}
2129
-
2130
- 🚀 **Next Steps:**
2131
- 1. Use \`snow_template_matching\` to explore template options
2132
- 2. Run \`snow_create_flow\` with deploy_immediately: true to implement the recommended approach
2133
- 3. Consider \`snow_scope_optimization\` for deployment strategy
2134
-
2135
- ✅ **Analysis Complete!** The instruction has been comprehensively analyzed with intelligent insights.`,
2136
- },
2137
- ],
2138
- };
2139
- }
2140
- catch (error) {
2141
- throw new Error(`Intelligent flow analysis failed: ${error instanceof Error ? error.message : String(error)}`);
2142
- }
2143
- }
2144
- /**
2145
- * Scope optimization tool
2146
- */
2147
- async scopeOptimization(args) {
2148
- const isAuth = await this.oauth.isAuthenticated();
2149
- if (!isAuth) {
2150
- return {
2151
- content: [
2152
- {
2153
- type: 'text',
2154
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
2155
- },
2156
- ],
2157
- };
2158
- }
2159
- try {
2160
- this.logger.info('Performing scope optimization analysis', {
2161
- artifactType: args.artifact_type,
2162
- environmentType: args.environment_type
2163
- });
2164
- // Create a deployment context for analysis
2165
- const deploymentContext = {
2166
- artifactType: args.artifact_type,
2167
- artifactData: args.artifact_data,
2168
- environmentType: args.environment_type || 'development'
2169
- };
2170
- // Use the composer's scope manager for analysis
2171
- const scopeAnalysis = await this.composer.scopeManagerInstance.makeScopeDecision(deploymentContext);
2172
- return {
2173
- content: [
2174
- {
2175
- type: 'text',
2176
- text: `🎯 Scope Optimization Analysis
2177
-
2178
- 📋 **Artifact Information:**
2179
- - **Type**: ${args.artifact_type}
2180
- - **Environment**: ${args.environment_type || 'development'}
2181
- - **Name**: ${args.artifact_data?.name || 'Unknown'}
2182
-
2183
- 🎯 **Scope Recommendation:**
2184
- - **Recommended Scope**: ${scopeAnalysis?.selectedScope || 'global'}
2185
- - **Confidence**: ${scopeAnalysis?.confidence ? Math.round(scopeAnalysis.confidence * 100) + '%' : 'Unknown'}
2186
- - **Rationale**: ${scopeAnalysis?.rationale || 'Global scope provides maximum flexibility and reusability'}
2187
-
2188
- 🔄 **Fallback Strategy:**
2189
- - **Fallback Scope**: ${scopeAnalysis?.fallbackScope || 'application'}
2190
- - **Fallback Triggers**: Permission issues, compliance requirements, environment restrictions
2191
-
2192
- ✅ **Validation Results:**
2193
- - **Permissions**: ${scopeAnalysis?.validationResult?.permissions || 'Valid'}
2194
- - **Compliance**: ${scopeAnalysis?.validationResult?.compliance || 'Compliant'}
2195
- - **Dependencies**: ${scopeAnalysis?.validationResult?.dependencies || 'Resolved'}
2196
-
2197
- 💡 **Recommendations:**
2198
- ${scopeAnalysis?.recommendations?.map((rec, index) => `${index + 1}. ${rec}`).join('\n') || '1. Deploy to global scope for maximum reusability\n2. Ensure proper naming conventions\n3. Document scope decision for future reference'}
2199
-
2200
- 🚀 **Deployment Strategy:**
2201
- 1. **Primary**: Deploy to ${scopeAnalysis?.selectedScope || 'global'} scope
2202
- 2. **Fallback**: Use ${scopeAnalysis?.fallbackScope || 'application'} scope if primary fails
2203
- 3. **Validation**: Comprehensive pre-deployment checks
2204
- 4. **Monitoring**: Post-deployment validation and rollback capability
2205
-
2206
- ⚠️ **Important Considerations:**
2207
- - Global scope artifacts are shared across all applications
2208
- - Application scope provides isolation but limits reusability
2209
- - Environment-specific considerations may override recommendations
2210
- - Compliance requirements may dictate scope selection
2211
-
2212
- ✅ **Analysis Complete!** Scope optimization strategy is ready for implementation.`,
2213
- },
2214
- ],
2215
- };
2216
- }
2217
- catch (error) {
2218
- throw new Error(`Scope optimization failed: ${error instanceof Error ? error.message : String(error)}`);
2219
- }
2220
- }
2221
- /**
2222
- * Template matching tool
2223
- */
2224
- async templateMatching(args) {
2225
- const isAuth = await this.oauth.isAuthenticated();
2226
- if (!isAuth) {
2227
- return {
2228
- content: [
2229
- {
2230
- type: 'text',
2231
- text: '❌ Not authenticated with ServiceNow.\n\nPlease run: snow-flow auth login\n\nOr configure your .env file with ServiceNow OAuth credentials.',
2232
- },
2233
- ],
2234
- };
2235
- }
2236
- try {
2237
- this.logger.info('Performing template matching', {
2238
- instruction: args.instruction,
2239
- minimumConfidence: args.minimum_confidence || 0.6
2240
- });
2241
- const matchingResults = await this.composer.patternTemplatesInstance.findMatchingTemplates(args.instruction);
2242
- // Filter by minimum confidence if specified
2243
- const filteredResults = matchingResults?.filter((result) => result.confidence >= (args.minimum_confidence || 0.6)) || [];
2244
- // Filter by categories if specified
2245
- const categoryFilteredResults = args.template_categories ?
2246
- filteredResults.filter((result) => args.template_categories.includes(result.template.category)) : filteredResults;
2247
- return {
2248
- content: [
2249
- {
2250
- type: 'text',
2251
- text: `🎯 Template Matching Results
2252
-
2253
- 📝 **Search Criteria:**
2254
- - **Instruction**: "${args.instruction}"
2255
- - **Minimum Confidence**: ${Math.round((args.minimum_confidence || 0.6) * 100)}%
2256
- - **Categories**: ${args.template_categories?.join(', ') || 'All categories'}
2257
-
2258
- 🎯 **Matching Templates (${categoryFilteredResults.length} found):**
2259
-
2260
- ${categoryFilteredResults.map((result, index) => `### ${index + 1}. ${result.template.name}
2261
- **Category**: ${result.template.category}
2262
- **Confidence**: ${Math.round(result.confidence * 100)}%
2263
- **Description**: ${result.template.description}
2264
-
2265
- **Template Features:**
2266
- - **Triggers**: ${result.template.triggers?.join(', ') || 'Generic'}
2267
- - **Activities**: ${result.template.activities?.length || 0} predefined activities
2268
- - **Variables**: ${result.template.variables?.length || 0} template variables
2269
- - **Customizable**: ${result.template.customizable ? 'Yes' : 'No'}
2270
-
2271
- **Why this matches:**
2272
- ${result.matchingReasons?.map((reason) => `- ${reason}`).join('\n') || '- Pattern similarity with instruction'}
2273
-
2274
- **Confidence Breakdown:**
2275
- - **Keyword Match**: ${Math.round(result.scores?.keywords * 100)}%
2276
- - **Intent Match**: ${Math.round(result.scores?.intent * 100)}%
2277
- - **Structure Match**: ${Math.round(result.scores?.structure * 100)}%
2278
- - **Context Match**: ${Math.round(result.scores?.context * 100)}%`).join('\n\n')}
2279
-
2280
- ${categoryFilteredResults.length === 0 ? `🔍 **No templates found matching your criteria.**
2281
-
2282
- **Suggestions:**
2283
- 1. Lower the minimum confidence threshold (currently ${Math.round((args.minimum_confidence || 0.6) * 100)}%)
2284
- 2. Remove category filters to see all available templates
2285
- 3. Try different keywords or phrases in your instruction
2286
- 4. Consider creating a custom flow without templates` : ''}
2287
-
2288
- 💡 **Template Usage:**
2289
- - **Best Match**: ${categoryFilteredResults[0]?.template.name || 'None'}
2290
- - **Confidence**: ${categoryFilteredResults[0]?.confidence ? Math.round(categoryFilteredResults[0].confidence * 100) + '%' : 'N/A'}
2291
- - **Recommended**: ${categoryFilteredResults[0]?.confidence >= 0.8 ? 'Yes - High confidence match' : 'Consider manual review'}
2292
-
2293
- 🚀 **Next Steps:**
2294
- 1. Use \`snow_create_flow\` with deploy_immediately: true to implement the best matching template
2295
- 2. Review template customization options
2296
- 3. Consider \`snow_intelligent_flow_analysis\` for detailed analysis
2297
- 4. Modify instruction if no suitable templates found
2298
-
2299
- ✅ **Template matching complete!** ${categoryFilteredResults.length > 0 ? 'Templates ready for implementation.' : 'Consider custom flow creation.'}`,
2300
- },
2301
- ],
2302
- };
2303
- }
2304
- catch (error) {
2305
- throw new Error(`Template matching failed: ${error instanceof Error ? error.message : String(error)}`);
2306
- }
2307
- }
2308
- async start() {
2309
- const transport = new stdio_js_1.StdioServerTransport();
2310
- await this.server.connect(transport);
2311
- this.logger.info('ServiceNow Flow Composer MCP Server started');
2312
- }
2313
- /**
2314
- * Map trigger type to XML format
2315
- */
2316
- mapTriggerTypeToXML(triggerType) {
2317
- const mapping = {
2318
- 'record_created': 'record_created',
2319
- 'record_updated': 'record_updated',
2320
- 'manual': 'manual',
2321
- 'scheduled': 'scheduled',
2322
- 'create': 'record_created',
2323
- 'update': 'record_updated',
2324
- 'on_create': 'record_created',
2325
- 'on_update': 'record_updated'
2326
- };
2327
- return mapping[triggerType.toLowerCase()] || 'manual';
2328
- }
2329
- /**
2330
- * Convert activities to XML format
2331
- */
2332
- convertActivitiesToXML(activities) {
2333
- return activities.map((activity, index) => ({
2334
- type: this.mapActivityTypeToXML(activity.type),
2335
- name: activity.name || `Activity ${index + 1}`,
2336
- inputs: activity.inputs || {},
2337
- order: (index + 1) * 100,
2338
- description: activity.description || activity.name
2339
- }));
2340
- }
2341
- /**
2342
- * Convert activities to CompleteFlowXMLGenerator format
2343
- */
2344
- convertActivitiesToCompleteFormat(activities) {
2345
- return activities.map((activity, index) => ({
2346
- name: activity.name || `Activity ${index + 1}`,
2347
- type: this.mapActivityTypeToXML(activity.type),
2348
- order: (index + 1) * 100,
2349
- description: activity.description || activity.name || '',
2350
- inputs: activity.inputs || {},
2351
- outputs: activity.outputs || {},
2352
- condition: activity.condition || '',
2353
- artifact_reference: activity.artifact_reference,
2354
- subflow_reference: activity.subflow_reference
2355
- }));
2356
- }
2357
- /**
2358
- * Map activity type to XML format
2359
- */
2360
- mapActivityTypeToXML(activityType) {
2361
- const mapping = {
2362
- 'approval': 'approval',
2363
- 'notification': 'notification',
2364
- 'email': 'notification',
2365
- 'script': 'script',
2366
- 'create_record': 'create_record',
2367
- 'update_record': 'update_record',
2368
- 'rest_call': 'rest_step',
2369
- 'condition': 'condition',
2370
- 'subflow': 'assign_subflow'
2371
- };
2372
- return mapping[activityType.toLowerCase()] || 'script';
2373
- }
2374
- /**
2375
- * Comprehensive flow verification with retry logic
2376
- */
2377
- async verifyFlowInServiceNow(flowName) {
2378
- const maxRetries = 5;
2379
- const baseDelay = 2000; // Start with 2 seconds
2380
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
2381
- try {
2382
- // Progressive delay - ServiceNow needs time to process
2383
- if (attempt > 1) {
2384
- const delay = baseDelay * attempt; // 2s, 4s, 6s, 8s, 10s
2385
- this.logger.info(`Waiting ${delay}ms before verification attempt ${attempt}/${maxRetries}`);
2386
- await this.sleep(delay);
2387
- }
2388
- const ServiceNowClient = (await Promise.resolve().then(() => __importStar(require('../utils/servicenow-client.js')))).ServiceNowClient;
2389
- const client = new ServiceNowClient();
2390
- // Multi-table verification for comprehensive check
2391
- const verificationPromises = [
2392
- // Check main flow table
2393
- client.makeRequest({
2394
- method: 'GET',
2395
- url: '/api/now/table/sys_hub_flow',
2396
- params: {
2397
- sysparm_query: `name=${flowName}^ORsys_name=${flowName}`,
2398
- sysparm_fields: 'sys_id,name,sys_name,active,table,description',
2399
- sysparm_limit: 5
2400
- }
2401
- }),
2402
- // Check flow snapshots
2403
- client.makeRequest({
2404
- method: 'GET',
2405
- url: '/api/now/table/sys_hub_flow_snapshot',
2406
- params: {
2407
- sysparm_query: `flow.name=${flowName}^ORflow.sys_name=${flowName}`,
2408
- sysparm_fields: 'sys_id,flow,name,active',
2409
- sysparm_limit: 5
2410
- }
2411
- }),
2412
- // Check trigger instances
2413
- client.makeRequest({
2414
- method: 'GET',
2415
- url: '/api/now/table/sys_hub_trigger_instance',
2416
- params: {
2417
- sysparm_query: `flow.name=${flowName}^ORflow.sys_name=${flowName}`,
2418
- sysparm_fields: 'sys_id,flow,trigger_type',
2419
- sysparm_limit: 5
2420
- }
2421
- })
2422
- ];
2423
- const [flowCheck, snapshotCheck, triggerCheck] = await Promise.allSettled(verificationPromises);
2424
- // Analyze results
2425
- const flowExists = flowCheck.status === 'fulfilled' &&
2426
- flowCheck.value.result &&
2427
- flowCheck.value.result.length > 0;
2428
- const snapshotExists = snapshotCheck.status === 'fulfilled' &&
2429
- snapshotCheck.value.result &&
2430
- snapshotCheck.value.result.length > 0;
2431
- const triggerExists = triggerCheck.status === 'fulfilled' &&
2432
- triggerCheck.value.result &&
2433
- triggerCheck.value.result.length > 0;
2434
- // Comprehensive verification result
2435
- if (flowExists) {
2436
- const flowData = flowCheck.value.result[0];
2437
- return {
2438
- verified: true,
2439
- sys_id: flowData.sys_id,
2440
- name: flowData.name || flowData.sys_name,
2441
- active: flowData.active,
2442
- table: flowData.table,
2443
- has_snapshot: snapshotExists,
2444
- has_trigger: triggerExists,
2445
- verification_attempt: attempt,
2446
- verification_method: 'multi_table_comprehensive',
2447
- completeness_score: (flowExists ? 1 : 0) + (snapshotExists ? 1 : 0) + (triggerExists ? 1 : 0),
2448
- url: `https://${await this.getInstanceUrl()}/flow-designer/flow/${flowData.sys_id}`
2449
- };
2450
- }
2451
- // Log partial results for debugging
2452
- this.logger.warn(`Verification attempt ${attempt}: Flow=${flowExists}, Snapshot=${snapshotExists}, Trigger=${triggerExists}`);
2453
- // If this is the last attempt, return detailed failure info
2454
- if (attempt === maxRetries) {
2455
- return {
2456
- verified: false,
2457
- reason: 'Flow not found after comprehensive verification',
2458
- attempts: maxRetries,
2459
- partial_results: {
2460
- flow_found: flowExists,
2461
- snapshot_found: snapshotExists,
2462
- trigger_found: triggerExists
2463
- },
2464
- search_query: `name=${flowName}`,
2465
- recommendation: 'Check ServiceNow Flow Designer manually or verify deployment was successful'
2466
- };
2467
- }
2468
- }
2469
- catch (error) {
2470
- this.logger.warn(`Verification attempt ${attempt} failed:`, error);
2471
- // If this is the last attempt, include error details
2472
- if (attempt === maxRetries) {
2473
- return {
2474
- verified: false,
2475
- reason: 'Verification failed due to error',
2476
- error: error instanceof Error ? error.message : String(error),
2477
- attempts: maxRetries
2478
- };
2479
- }
2480
- }
2481
- }
2482
- return {
2483
- verified: false,
2484
- reason: 'Max verification attempts exceeded',
2485
- attempts: maxRetries
2486
- };
2487
- }
2488
- /**
2489
- * Helper to get instance URL for flow links
2490
- */
2491
- async getInstanceUrl() {
2492
- try {
2493
- const credentials = await this.oauth.loadCredentials();
2494
- return credentials?.instance || 'your-instance.service-now.com';
2495
- }
2496
- catch {
2497
- return 'your-instance.service-now.com';
2498
- }
2499
- }
2500
- /**
2501
- * Sleep utility
2502
- */
2503
- sleep(ms) {
2504
- return new Promise(resolve => setTimeout(resolve, ms));
2505
- }
2506
- /**
2507
- * Generate manual import guide for failed deployments
2508
- */
2509
- generateManualImportGuide(xmlFilePath) {
2510
- // BUG-004 FIX: Handle undefined or empty file paths properly
2511
- if (!xmlFilePath || xmlFilePath.trim() === '') {
2512
- return `
2513
- **⚠️ No XML file was generated**
2514
-
2515
- Since the flow XML generation failed, you'll need to:
2516
-
2517
- 1. **Create the flow manually in ServiceNow**:
2518
- - Navigate to Flow Designer
2519
- - Click "New" > "Flow"
2520
- - Build the flow based on your requirements
2521
-
2522
- 2. **Alternative: Use the deployment tool**:
2523
- - Run: snow-flow deploy --retry
2524
- - This will attempt to regenerate and deploy the flow
2525
-
2526
- 3. **Check error logs**:
2527
- - Review the error details above to understand why XML generation failed
2528
- - Common causes: missing artifacts, permission issues, or invalid flow structure`;
2529
- }
2530
- return `
2531
- 1. **Navigate to ServiceNow**:
2532
- - System Update Sets > Retrieved Update Sets
2533
-
2534
- 2. **Import XML**:
2535
- - Click "Import Update Set from XML"
2536
- - Select file: ${xmlFilePath}
2537
- - Click "Upload"
2538
-
2539
- 3. **Preview**:
2540
- - Find your imported update set
2541
- - Click "Preview Update Set"
2542
- - Review any conflicts or issues
2543
-
2544
- 4. **Commit**:
2545
- - If preview is clean, click "Commit Update Set"
2546
- - Your flow will be available in Flow Designer
2547
-
2548
- 5. **Verify**:
2549
- - Navigate to Flow Designer
2550
- - Check "My Flows" for your new flow`;
2551
- }
2552
- /**
2553
- * Deploy with fallback strategies + MANDATORY VERIFICATION
2554
- * 🔴 CRITICAL FIX: SNOW-001 Silent Deployment Failures
2555
- * Each strategy now MUST verify that the flow actually exists before claiming success
2556
- */
2557
- async deployWithFallback(xmlFilePath, flowDefinition) {
2558
- // 🚀 ENHANCED: Use our complete solution components
2559
- const toolRegistry = (0, mcp_tool_registry_js_1.getToolRegistry)();
2560
- try {
2561
- // Use our enhanced deployment system
2562
- this.logger.info('🚀 Using enhanced deployment system with complete solution');
2563
- // Deploy using UpdateSetImporter
2564
- const importResult = await (0, update_set_importer_js_1.deployFlowXML)(xmlFilePath, true);
2565
- if (importResult.success) {
2566
- // Extract complete metadata using DeploymentMetadataHandler
2567
- const metadataResult = await (0, deployment_metadata_handler_js_1.ensureDeploymentMetadata)('flow', { success: true, flow: { sys_id: importResult.flowSysId } }, {
2568
- flowSysId: importResult.flowSysId,
2569
- name: flowDefinition.name,
2570
- update_set_id: importResult.localUpdateSetId
2571
- });
2572
- if (metadataResult.success && metadataResult.metadata) {
2573
- return {
2574
- success: true,
2575
- strategy: 'Enhanced XML Update Set',
2576
- result: importResult,
2577
- verification: {
2578
- verified: true,
2579
- sys_id: metadataResult.metadata.sys_id,
2580
- url: metadataResult.metadata.ui_url,
2581
- api_endpoint: metadataResult.metadata.api_endpoint,
2582
- has_flow: true,
2583
- has_snapshot: true,
2584
- has_trigger: true,
2585
- completeness_score: 100,
2586
- verification_attempt: 1,
2587
- reason: 'Complete deployment with metadata verification'
2588
- },
2589
- deployment_verified: true,
2590
- metadata: metadataResult.metadata
2591
- };
2592
- }
2593
- }
2594
- // If enhanced deployment fails, try legacy methods
2595
- this.logger.warn('Enhanced deployment failed, trying fallback strategies');
2596
- }
2597
- catch (error) {
2598
- this.logger.warn('Enhanced deployment error:', error);
2599
- }
2600
- // Fallback to legacy strategies
2601
- const strategies = [
2602
- {
2603
- name: 'XML Remote Update Set',
2604
- fn: async () => await this.deployXMLToServiceNowWithVerification(xmlFilePath, flowDefinition.name)
2605
- },
2606
- {
2607
- name: 'Direct Table API',
2608
- fn: async () => await this.deployViaTableAPIWithVerification(flowDefinition)
2609
- }
2610
- ];
2611
- let lastError;
2612
- for (const strategy of strategies) {
2613
- try {
2614
- this.logger.info(`Trying deployment strategy: ${strategy.name}`);
2615
- const result = await strategy.fn();
2616
- // 🔴 CRITICAL: Strategy can only return if it includes verification proof
2617
- if (!result.verification || !result.verification.verified) {
2618
- throw new Error(`${strategy.name} completed but verification failed: ${result.verification?.reason || 'Unknown verification failure'}`);
2619
- }
2620
- return {
2621
- success: true,
2622
- strategy: strategy.name,
2623
- result,
2624
- verification: result.verification,
2625
- deployment_verified: true
2626
- };
2627
- }
2628
- catch (error) {
2629
- this.logger.warn(`Strategy ${strategy.name} failed:`, error);
2630
- lastError = error;
2631
- }
2632
- }
2633
- throw lastError || new Error('All deployment strategies failed');
2634
- }
2635
- /**
2636
- * 🔴 CRITICAL FIX: Deploy XML with MANDATORY verification
2637
- * SNOW-001: Prevents false positive where XML import succeeds but flow doesn't exist
2638
- */
2639
- async deployXMLToServiceNowWithVerification(xmlFilePath, flowName) {
2640
- this.logger.info(`🔴 CRITICAL FIX: XML deployment with mandatory verification for: ${flowName}`);
2641
- // Step 1: Deploy the XML (existing logic)
2642
- await this.deployXMLToServiceNow(xmlFilePath);
2643
- // Step 2: MANDATORY verification - wait for ServiceNow to process
2644
- this.logger.info('🔍 Starting mandatory post-deployment verification...');
2645
- const verification = await this.verifyFlowInServiceNow(flowName);
2646
- if (!verification.verified) {
2647
- // 🔴 CRITICAL: XML deployment succeeded but flow doesn't exist
2648
- const errorMsg = `🔴 CRITICAL: XML deployment appeared to succeed but flow verification failed: ${verification.reason}`;
2649
- this.logger.error('SNOW-001 detected: Silent deployment failure', {
2650
- xmlFilePath,
2651
- flowName,
2652
- verificationResult: verification,
2653
- issue: 'XML import/commit succeeded but no flow created'
2654
- });
2655
- throw new Error(errorMsg);
2656
- }
2657
- this.logger.info(`✅ XML deployment verified successfully: ${flowName} found with sys_id ${verification.sys_id}`);
2658
- return {
2659
- deployment_method: 'XML Remote Update Set',
2660
- xml_file: xmlFilePath,
2661
- verification: verification,
2662
- success_message: `XML deployment completed and verified: Flow ${flowName} is live in ServiceNow`
2663
- };
2664
- }
2665
- /**
2666
- * 🔴 CRITICAL FIX: Deploy via Table API with MANDATORY verification
2667
- * SNOW-001: Prevents false positive where API call succeeds but flow doesn't exist
2668
- */
2669
- async deployViaTableAPIWithVerification(flowDefinition) {
2670
- this.logger.info(`🔴 CRITICAL FIX: Table API deployment with mandatory verification for: ${flowDefinition.name}`);
2671
- // Step 1: Deploy via Table API (existing logic)
2672
- await this.deployViaTableAPI(flowDefinition);
2673
- // Step 2: MANDATORY verification
2674
- this.logger.info('🔍 Starting mandatory post-deployment verification...');
2675
- const verification = await this.verifyFlowInServiceNow(flowDefinition.name);
2676
- if (!verification.verified) {
2677
- // 🔴 CRITICAL: Table API deployment succeeded but flow doesn't exist
2678
- const errorMsg = `🔴 CRITICAL: Table API deployment appeared to succeed but flow verification failed: ${verification.reason}`;
2679
- this.logger.error('SNOW-001 detected: Silent deployment failure', {
2680
- flowName: flowDefinition.name,
2681
- verificationResult: verification,
2682
- issue: 'Table API call succeeded but no flow created'
2683
- });
2684
- throw new Error(errorMsg);
2685
- }
2686
- this.logger.info(`✅ Table API deployment verified successfully: ${flowDefinition.name} found with sys_id ${verification.sys_id}`);
2687
- return {
2688
- deployment_method: 'Direct Table API',
2689
- verification: verification,
2690
- success_message: `Table API deployment completed and verified: Flow ${flowDefinition.name} is live in ServiceNow`
2691
- };
2692
- }
2693
- /**
2694
- * Deploy via direct table API (LEGACY METHOD - used by new verified method)
2695
- */
2696
- async deployViaTableAPI(flowDefinition) {
2697
- const ServiceNowClient = (await Promise.resolve().then(() => __importStar(require('../utils/servicenow-client.js')))).ServiceNowClient;
2698
- const client = new ServiceNowClient();
2699
- // Try to create flow directly in sys_hub_flow
2700
- const flowResponse = await client.makeRequest({
2701
- method: 'POST',
2702
- url: '/api/now/table/sys_hub_flow',
2703
- data: {
2704
- name: flowDefinition.name,
2705
- description: flowDefinition.description,
2706
- active: true,
2707
- // Additional flow properties
2708
- table: flowDefinition.table
2709
- }
2710
- });
2711
- if (!flowResponse.result || !flowResponse.result.sys_id) {
2712
- throw new Error('Failed to create flow via Table API');
2713
- }
2714
- this.logger.info(`Flow created via Table API: ${flowResponse.result.sys_id}`);
2715
- }
2716
- /**
2717
- * Deploy XML file to ServiceNow automatically
2718
- */
2719
- async deployXMLToServiceNow(xmlFilePath) {
2720
- // Check authentication
2721
- const isAuth = await this.oauth.isAuthenticated();
2722
- if (!isAuth) {
2723
- throw new Error('Not authenticated with ServiceNow. Please run: snow-flow auth login');
2724
- }
2725
- // Initialize ServiceNow client
2726
- const ServiceNowClient = (await Promise.resolve().then(() => __importStar(require('../utils/servicenow-client.js')))).ServiceNowClient;
2727
- const client = new ServiceNowClient();
2728
- // Check for active Update Set first
2729
- let currentUpdateSet;
2730
- try {
2731
- const updateSetResponse = await client.makeRequest({
2732
- method: 'GET',
2733
- url: '/api/now/table/sys_update_set',
2734
- params: {
2735
- sysparm_query: 'state=in progress^nameNOT LIKEDefault',
2736
- sysparm_limit: 1
2737
- }
2738
- });
2739
- if (!updateSetResponse.result || updateSetResponse.result.length === 0) {
2740
- this.logger.warn('No active Update Set found. Flow will be imported but not tracked properly.');
2741
- // Continue anyway - let ServiceNow handle it
2742
- }
2743
- else {
2744
- currentUpdateSet = updateSetResponse.result[0];
2745
- this.logger.info(`Active Update Set found: ${currentUpdateSet.name}`);
2746
- }
2747
- }
2748
- catch (error) {
2749
- this.logger.warn('Could not check for active Update Set:', error);
2750
- // Continue anyway
2751
- }
2752
- // Read the XML file
2753
- const fs = require('fs').promises;
2754
- const xmlContent = await fs.readFile(xmlFilePath, 'utf-8');
2755
- // Import XML as remote update set
2756
- let importResponse;
2757
- try {
2758
- importResponse = await client.makeRequest({
2759
- method: 'POST',
2760
- url: '/api/now/table/sys_remote_update_set',
2761
- headers: {
2762
- 'Content-Type': 'application/xml',
2763
- 'Accept': 'application/json'
2764
- },
2765
- data: xmlContent
2766
- });
2767
- }
2768
- catch (error) {
2769
- // Enhanced error handling with detailed messages
2770
- if (error.response?.status === 400) {
2771
- const errorDetail = error.response.data?.error?.detail ||
2772
- error.response.data?.error?.message ||
2773
- 'Unknown error';
2774
- this.logger.error('ServiceNow 400 Error:', {
2775
- status: error.response.status,
2776
- statusText: error.response.statusText,
2777
- data: error.response.data,
2778
- headers: error.response.headers
2779
- });
2780
- throw new Error(`ServiceNow rejected the XML: ${errorDetail}. Check if you have an active Update Set.`);
2781
- }
2782
- else if (error.response?.status === 401 || error.response?.status === 403) {
2783
- throw new Error('Authentication failed. Your session may have expired. Run: snow-flow auth login');
2784
- }
2785
- else {
2786
- throw new Error(`Failed to import XML: ${error.message}`);
2787
- }
2788
- }
2789
- if (!importResponse.result || !importResponse.result.sys_id) {
2790
- throw new Error('Failed to import XML update set');
2791
- }
2792
- const remoteUpdateSetId = importResponse.result.sys_id;
2793
- this.logger.info(`✅ XML imported successfully (sys_id: ${remoteUpdateSetId})`);
2794
- // Load the update set
2795
- try {
2796
- await client.makeRequest({
2797
- method: 'PUT',
2798
- url: `/api/now/table/sys_remote_update_set/${remoteUpdateSetId}`,
2799
- data: {
2800
- state: 'loaded'
2801
- }
2802
- });
2803
- }
2804
- catch (error) {
2805
- this.logger.error('Failed to load update set:', error);
2806
- throw new Error(`Failed to load update set: ${error.message}. You may need to load it manually.`);
2807
- }
2808
- // Find the loaded update set
2809
- const loadedResponse = await client.makeRequest({
2810
- method: 'GET',
2811
- url: '/api/now/table/sys_update_set',
2812
- params: {
2813
- sysparm_query: `remote_sys_id=${remoteUpdateSetId}`,
2814
- sysparm_limit: 1
2815
- }
2816
- });
2817
- if (!loadedResponse.result || loadedResponse.result.length === 0) {
2818
- throw new Error('Failed to find loaded update set');
2819
- }
2820
- const updateSetId = loadedResponse.result[0].sys_id;
2821
- const updateSetName = loadedResponse.result[0].name;
2822
- // Preview the update set
2823
- try {
2824
- await client.makeRequest({
2825
- method: 'POST',
2826
- url: `/api/now/table/sys_update_set/${updateSetId}/preview`
2827
- });
2828
- }
2829
- catch (error) {
2830
- this.logger.error('Failed to preview update set:', error);
2831
- // Continue anyway, as preview might fail but commit could still work
2832
- }
2833
- // Check for preview problems
2834
- const previewProblems = await client.makeRequest({
2835
- method: 'GET',
2836
- url: '/api/now/table/sys_update_preview_problem',
2837
- params: {
2838
- sysparm_query: `update_set=${updateSetId}`,
2839
- sysparm_limit: 100
2840
- }
2841
- });
2842
- if (previewProblems.result && previewProblems.result.length > 0) {
2843
- const problemsList = previewProblems.result.map((p) => `- ${p.type}: ${p.description}`).join('\n');
2844
- throw new Error(`Preview found problems:\n${problemsList}\n\nPlease review and resolve in ServiceNow UI`);
2845
- }
2846
- // Commit the update set
2847
- try {
2848
- await client.makeRequest({
2849
- method: 'POST',
2850
- url: `/api/now/table/sys_update_set/${updateSetId}/commit`
2851
- });
2852
- this.logger.info(`✅ Update set committed successfully: ${updateSetName}`);
2853
- }
2854
- catch (error) {
2855
- this.logger.error('Failed to commit update set:', error);
2856
- throw new Error(`Failed to commit update set. Manual intervention required in ServiceNow UI.`);
2857
- }
2858
- }
2859
- /**
2860
- * 🚀 BUG-007 FIX: Performance Analysis Tool
2861
- * Analyze flows for performance bottlenecks and provide database index recommendations
2862
- */
2863
- async performanceAnalysis(args) {
2864
- try {
2865
- this.logger.info('🔍 Running performance analysis', {
2866
- flowDefinition: !!args.flow_definition,
2867
- tableName: args.table_name,
2868
- includeIndexes: args.include_database_indexes,
2869
- includeCode: args.include_code_analysis
2870
- });
2871
- // Import the performance engine
2872
- const { PerformanceRecommendationsEngine } = await Promise.resolve().then(() => __importStar(require('../intelligence/performance-recommendations-engine.js')));
2873
- const performanceEngine = new PerformanceRecommendationsEngine();
2874
- // Run performance analysis
2875
- const analysisResult = await performanceEngine.analyzeFlowPerformance(args.flow_definition);
2876
- let responseText = `🚀 **Performance Analysis Results**
2877
-
2878
- 📊 **SUMMARY:**
2879
- • Critical Issues: ${analysisResult.summary.criticalIssues}
2880
- • Estimated Performance Improvement: ${analysisResult.summary.estimatedImprovementPercent}%
2881
- • Total Recommendations: ${analysisResult.databaseIndexes.length + analysisResult.performanceRecommendations.length}
2882
-
2883
- `;
2884
- // Add database index recommendations if requested
2885
- if (args.include_database_indexes !== false && analysisResult.databaseIndexes.length > 0) {
2886
- responseText += `🗄️ **DATABASE INDEX RECOMMENDATIONS:**
2887
-
2888
- ${analysisResult.databaseIndexes.map((idx, i) => `**${i + 1}. ${idx.table} - ${idx.fields.join(', ')} [${idx.priority.toUpperCase()}]**
2889
- 💡 **Reason**: ${idx.reason}
2890
- 📈 **Expected Improvement**: ${idx.estimatedImprovement}%
2891
- 💻 **SQL**: \`${idx.createStatement}\`
2892
- 📊 **Impact**: ${idx.impactAnalysis.queryImpact.join(', ')}
2893
- 💾 **Storage**: ${idx.impactAnalysis.storageImpact}
2894
- 🔧 **Maintenance**: ${idx.impactAnalysis.maintenanceImpact}
2895
- `).join('\n')}
2896
-
2897
- `;
2898
- }
2899
- // Add performance recommendations if requested
2900
- if (args.include_code_analysis !== false && analysisResult.performanceRecommendations.length > 0) {
2901
- responseText += `⚡ **PERFORMANCE RECOMMENDATIONS:**
2902
-
2903
- ${analysisResult.performanceRecommendations.map((rec, i) => `**${i + 1}. ${rec.type.replace(/_/g, ' ').toUpperCase()} [${rec.impact.toUpperCase()} IMPACT]**
2904
- 📋 **Issue**: ${rec.description}
2905
- 💡 **Recommendation**: ${rec.recommendation}
2906
- ⏱️ **Time Savings**: ${rec.estimated_time_savings}
2907
- ${rec.code_example ? `\n💻 **Example Code**:\n\`\`\`javascript\n${rec.code_example}\n\`\`\`` : ''}
2908
- `).join('\n')}
2909
-
2910
- `;
2911
- }
2912
- // Add top priority actions
2913
- if (analysisResult.summary.recommendedActions.length > 0) {
2914
- responseText += `🎯 **TOP PRIORITY ACTIONS:**
2915
- ${analysisResult.summary.recommendedActions.map((action, i) => `${i + 1}. ${action}`).join('\n')}
2916
-
2917
- `;
2918
- }
2919
- // Add detailed report if requested
2920
- if (args.detailed_report) {
2921
- responseText += `📋 **DETAILED PERFORMANCE REPORT:**
2922
-
2923
- ${performanceEngine.generatePerformanceReport(analysisResult)}`;
2924
- }
2925
- responseText += `
2926
- 🔍 **NEXT STEPS:**
2927
- 1. Implement critical database indexes first (highest ROI)
2928
- 2. Review and optimize flow scripts for performance issues
2929
- 3. Consider implementing caching for frequently accessed data
2930
- 4. Monitor performance metrics after implementing changes
2931
- 5. Schedule regular performance reviews for optimal results
2932
-
2933
- ⚠️ **IMPORTANT**: Test all database changes in a development environment first!
2934
-
2935
- ✅ **Performance analysis complete!** Review recommendations and implement changes for optimal performance.`;
2936
- return {
2937
- content: [
2938
- {
2939
- type: 'text',
2940
- text: responseText,
2941
- },
2942
- ],
2943
- };
2944
- }
2945
- catch (error) {
2946
- this.logger.error('Performance analysis failed:', error);
2947
- throw new Error(`Performance analysis failed: ${error instanceof Error ? error.message : String(error)}`);
2948
- }
2949
- }
2950
- /**
2951
- * 🚀 BUG-006 FIX: Comprehensive Requirements Analysis Tool
2952
- * Multi-pass analysis to ensure comprehensive requirements coverage
2953
- */
2954
- async comprehensiveRequirementsAnalysis(args) {
2955
- try {
2956
- this.logger.info('🔍 Running comprehensive multi-pass requirements analysis', {
2957
- objective: args.objective,
2958
- includeDependencies: args.include_dependencies,
2959
- includeContext: args.include_context_analysis,
2960
- includeValidation: args.include_validation
2961
- });
2962
- // Import the multi-pass analyzer
2963
- const { MultiPassRequirementsAnalyzer } = await Promise.resolve().then(() => __importStar(require('../intelligence/multi-pass-requirements-analyzer.js')));
2964
- const analyzer = new MultiPassRequirementsAnalyzer();
2965
- // Run comprehensive multi-pass analysis
2966
- const analysisResult = await analyzer.analyzeRequirements(args.objective);
2967
- let responseText = `🚀 **Comprehensive Requirements Analysis Results**
2968
-
2969
- 📝 **OBJECTIVE**: ${args.objective}
2970
-
2971
- 📊 **ANALYSIS SUMMARY:**
2972
- • Total Requirements Identified: ${analysisResult.totalRequirements}
2973
- • MCP Coverage: ${analysisResult.mcpCoveredCount}/${analysisResult.totalRequirements} (${analysisResult.mcpCoveragePercentage}%)
2974
- • Gap Requirements: ${analysisResult.gapCount}
2975
- • Estimated Complexity: ${analysisResult.estimatedComplexity.toUpperCase()}
2976
- • Risk Assessment: ${analysisResult.riskAssessment.toUpperCase()}
2977
- • Completeness Score: ${analysisResult.completenessScore}/100
2978
- • Confidence Level: ${analysisResult.confidenceLevel.toUpperCase()}
2979
-
2980
- `;
2981
- // Add multi-pass analysis breakdown
2982
- responseText += `🔍 **MULTI-PASS ANALYSIS BREAKDOWN:**
2983
-
2984
- ${Object.entries(analysisResult.analysisPassesData).map(([passKey, passData]) => `**${passData.passName} (Pass ${passData.passNumber})**
2985
- • Requirements Found: ${passData.newRequirementsAdded}
2986
- • Analysis Method: ${passData.analysisMethod}
2987
- • Processing Time: ${passData.processingTime}ms
2988
- • Confidence: ${Math.round(passData.confidence * 100)}%
2989
- • Key Findings: ${passData.keyFindings.length > 0 ? passData.keyFindings.slice(0, 3).join('; ') : 'No specific findings'}
2990
- `).join('\n')}
2991
-
2992
- `;
2993
- // Add requirements by category
2994
- const categorizedRequirements = analysisResult.requirements.reduce((acc, req) => {
2995
- if (!acc[req.category])
2996
- acc[req.category] = [];
2997
- acc[req.category].push(req);
2998
- return acc;
2999
- }, {});
3000
- responseText += `📋 **REQUIREMENTS BY CATEGORY:**
3001
-
3002
- ${Object.entries(categorizedRequirements).map(([category, reqs]) => `**${category.replace(/_/g, ' ').toUpperCase()}** (${reqs.length} items)
3003
- ${reqs.slice(0, 5).map(req => `• ${req.name} [${req.priority.toUpperCase()}] ${req.mcpCoverage ? '✅ MCP' : '⚠️ Manual'} - ${req.description.substring(0, 80)}...`).join('\n')}
3004
- ${reqs.length > 5 ? `... and ${reqs.length - 5} more items` : ''}
3005
- `).join('\n')}
3006
-
3007
- `;
3008
- // Add critical path analysis
3009
- if (analysisResult.criticalPath.length > 0) {
3010
- responseText += `🎯 **CRITICAL PATH REQUIREMENTS:**
3011
- ${analysisResult.criticalPath.map((req, i) => `${i + 1}. ${req}`).join('\n')}
3012
-
3013
- `;
3014
- }
3015
- // Add cross-domain impacts
3016
- if (analysisResult.crossDomainImpacts.length > 0) {
3017
- responseText += `🌐 **CROSS-DOMAIN IMPACTS:**
3018
- ${analysisResult.crossDomainImpacts.map((impact, i) => `${i + 1}. ${impact}`).join('\n')}
3019
-
3020
- `;
3021
- }
3022
- // Add implicit dependencies
3023
- if (analysisResult.implicitDependencies.length > 0) {
3024
- responseText += `🔗 **IMPLICIT DEPENDENCIES:**
3025
- ${analysisResult.implicitDependencies.slice(0, 5).map((dep, i) => `${i + 1}. ${dep}`).join('\n')}
3026
-
3027
- `;
3028
- }
3029
- // Add missing requirements detected
3030
- if (analysisResult.missingRequirementsDetected.length > 0) {
3031
- responseText += `⚠️ **MISSING REQUIREMENTS DETECTED:**
3032
- ${analysisResult.missingRequirementsDetected.slice(0, 3).map((req, i) => `${i + 1}. **${req.name}** [${req.priority.toUpperCase()}]
3033
- ${req.description}
3034
- Effort: ${req.estimatedEffort} | Risk: ${req.riskLevel} | MCP: ${req.mcpCoverage ? 'Yes' : 'No'}`).join('\n\n')}
3035
-
3036
- `;
3037
- }
3038
- // Add detailed report if requested
3039
- if (args.detailed_report) {
3040
- responseText += `📋 **DETAILED ANALYSIS REPORT:**
3041
-
3042
- **COMPLETENESS ANALYSIS:**
3043
- The analysis achieved a completeness score of ${analysisResult.completenessScore}/100 with ${analysisResult.confidenceLevel} confidence.
3044
-
3045
- **PASS-BY-PASS BREAKDOWN:**
3046
- ${Object.entries(analysisResult.analysisPassesData).map(([passKey, passData]) => `
3047
- **${passData.passName}:**
3048
- - New requirements identified: ${passData.newRequirementsAdded}
3049
- - Key insights: ${passData.keyFindings.join('; ')}
3050
- - Analysis approach: ${passData.analysisMethod}
3051
- - Processing efficiency: ${passData.processingTime}ms
3052
- `).join('')}
3053
-
3054
- **RISK ASSESSMENT:**
3055
- ${analysisResult.riskAssessment === 'high' ? '⚠️ HIGH RISK: This objective involves complex integrations and significant system changes.' :
3056
- analysisResult.riskAssessment === 'medium' ? '🔶 MEDIUM RISK: Standard complexity with some integration challenges.' :
3057
- '✅ LOW RISK: Straightforward implementation with minimal system impact.'}
3058
-
3059
- **COMPLEXITY BREAKDOWN:**
3060
- The ${analysisResult.estimatedComplexity} complexity rating is based on:
3061
- - Number of components: ${analysisResult.totalRequirements}
3062
- - Integration points: ${analysisResult.categories.length} different categories
3063
- - Estimated duration: ${analysisResult.estimatedDuration}
3064
- - Cross-domain impacts: ${analysisResult.crossDomainImpacts.length} identified
3065
-
3066
- `;
3067
- }
3068
- responseText += `
3069
- 🔍 **NEXT STEPS:**
3070
- 1. **Immediate Actions**: Focus on ${analysisResult.criticalPath.length > 0 ? 'critical path requirements' : 'high-priority items'}
3071
- 2. **MCP Coverage**: ${analysisResult.mcpCoveragePercentage}% can be automated, ${100 - analysisResult.mcpCoveragePercentage}% requires manual work
3072
- 3. **Resource Planning**: Estimated ${analysisResult.estimatedDuration} development time
3073
- 4. **Risk Mitigation**: Address ${analysisResult.riskAssessment} risk items first
3074
- 5. **Quality Assurance**: Validate completeness score of ${analysisResult.completenessScore}/100
3075
-
3076
- 💡 **RECOMMENDATIONS:**
3077
- • Start with MCP-covered requirements for quick wins
3078
- • Address security and compliance requirements early
3079
- • Plan for cross-domain impact testing
3080
- • Consider phased implementation for complex scenarios
3081
-
3082
- ✅ **Comprehensive analysis complete!** This ${analysisResult.analysisPassesData.pass1_initial.requirementsFound + analysisResult.analysisPassesData.pass2_dependencies.newRequirementsAdded + analysisResult.analysisPassesData.pass3_context.newRequirementsAdded + analysisResult.analysisPassesData.pass4_validation.newRequirementsAdded}-requirement analysis ensures nothing is missed.`;
3083
- return {
3084
- content: [
3085
- {
3086
- type: 'text',
3087
- text: responseText,
3088
- },
3089
- ],
3090
- };
3091
- }
3092
- catch (error) {
3093
- this.logger.error('Comprehensive requirements analysis failed:', error);
3094
- throw new Error(`Comprehensive requirements analysis failed: ${error instanceof Error ? error.message : String(error)}`);
3095
- }
3096
- }
3097
- }
3098
- // Start the server
3099
- const server = new ServiceNowFlowComposerMCP();
3100
- server.start().catch((error) => {
3101
- console.error('Failed to start ServiceNow Flow Composer MCP:', error);
3102
- process.exit(1);
3103
- });