snow-flow 10.0.1-dev.476 → 10.0.1-dev.477

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "10.0.1-dev.476",
3
+ "version": "10.0.1-dev.477",
4
4
  "name": "snow-flow",
5
5
  "description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
6
6
  "license": "Elastic-2.0",
@@ -1,3 +1,18 @@
1
+ /**
2
+ * Snow-Flow Flow Designer Tool
3
+ *
4
+ * DISCLAIMER:
5
+ * This tool uses both official and undocumented ServiceNow APIs to interact
6
+ * with Flow Designer. The GraphQL-based operations (snFlowDesigner) use
7
+ * internal ServiceNow APIs that are not officially documented and may change
8
+ * without notice. Use at your own risk.
9
+ *
10
+ * This tool is not affiliated with, endorsed by, or sponsored by ServiceNow, Inc.
11
+ * ServiceNow is a registered trademark of ServiceNow, Inc.
12
+ *
13
+ * A valid ServiceNow subscription and credentials are required to use this tool.
14
+ */
15
+
1
16
  import { MCPToolDefinition, ServiceNowContext, ToolResult } from '../../shared/types.js';
2
17
  import { getAuthenticatedClient } from '../../shared/auth.js';
3
18
  import { createSuccessResult, createErrorResult, SnowFlowError, ErrorType } from '../../shared/error-handler.js';
@@ -1149,67 +1164,66 @@ async function getFlowTriggerInfo(
1149
1164
  var debug: any = {};
1150
1165
 
1151
1166
  // PRIMARY: Read flow via ProcessFlow REST API (same endpoint as Flow Designer UI)
1152
- // This is how the UI loads the flow returns JSON/XML with full trigger data
1167
+ // This API returns XML (not JSON). We parse trigger info from the XML string.
1153
1168
  try {
1154
1169
  debug.processflow_api = 'attempting';
1155
- var pfResp = await client.get('/api/now/processflow/flow/' + flowId);
1156
- var pfData = pfResp.data?.result || pfResp.data;
1170
+ var pfResp = await client.get('/api/now/processflow/flow/' + flowId, {
1171
+ headers: { 'Accept': 'application/xml, application/json' }
1172
+ });
1173
+ var pfRaw = pfResp.data;
1157
1174
  debug.processflow_api = 'success';
1158
- debug.processflow_type = typeof pfData;
1159
- debug.processflow_keys = pfData && typeof pfData === 'object' ? Object.keys(pfData).slice(0, 20) : null;
1160
-
1161
- // The ProcessFlow API returns the flow with trigger instances
1162
- // Try multiple possible structures for trigger data
1163
- var pfTriggers = pfData?.triggerInstances || pfData?.trigger_instances || pfData?.triggers || [];
1164
- if (!Array.isArray(pfTriggers) && pfData?.model?.triggerInstances) {
1165
- pfTriggers = pfData.model.triggerInstances;
1166
- }
1167
- if (!Array.isArray(pfTriggers) && pfData?.definition?.triggerInstances) {
1168
- pfTriggers = pfData.definition.triggerInstances;
1169
- }
1170
- debug.processflow_triggers = Array.isArray(pfTriggers) ? pfTriggers.length : typeof pfTriggers;
1171
-
1172
- if (Array.isArray(pfTriggers) && pfTriggers.length > 0) {
1173
- var pfTrig = pfTriggers[0];
1174
- debug.processflow_trigger_keys = Object.keys(pfTrig);
1175
- debug.processflow_trigger_name = pfTrig.name;
1176
- triggerName = pfTrig.name || pfTrig.triggerName || '';
1177
- if (pfTrig.inputs && Array.isArray(pfTrig.inputs)) {
1178
- for (var pfi = 0; pfi < pfTrig.inputs.length; pfi++) {
1179
- if (pfTrig.inputs[pfi].name === 'table') {
1180
- table = pfTrig.inputs[pfi].value?.value || str(pfTrig.inputs[pfi].value) || '';
1181
- break;
1182
- }
1175
+ debug.processflow_type = typeof pfRaw;
1176
+
1177
+ if (typeof pfRaw === 'string' && pfRaw.indexOf('<triggerInstances>') >= 0) {
1178
+ // Response is XML parse trigger info with regex
1179
+ debug.processflow_format = 'xml';
1180
+
1181
+ // Extract the triggerInstances block
1182
+ var trigBlockMatch = pfRaw.match(/<triggerInstances>([\s\S]*?)<\/triggerInstances>/);
1183
+ if (trigBlockMatch) {
1184
+ var trigBlock = trigBlockMatch[1];
1185
+
1186
+ // Trigger name: <name>X</name> that appears near <triggerType> at end of block
1187
+ // Structure: ...<name>Created or Updated</name><comment/>...<triggerType>Record</triggerType>
1188
+ var trigNameMatch = trigBlock.match(/<name>([^<]+)<\/name>[\s\S]{0,300}<triggerType>/);
1189
+ if (trigNameMatch) {
1190
+ triggerName = trigNameMatch[1];
1191
+ debug.processflow_trigger_name = triggerName;
1192
+ }
1193
+
1194
+ // Table: find <name>table</name> ... <value>X</value> inside trigger inputs
1195
+ var tableMatch = trigBlock.match(/<name>table<\/name>[\s\S]*?<value>([^<]+)<\/value>/);
1196
+ if (tableMatch) {
1197
+ table = tableMatch[1];
1198
+ debug.processflow_table = table;
1183
1199
  }
1184
1200
  }
1185
- }
1201
+ } else if (pfRaw && typeof pfRaw === 'object') {
1202
+ // Response is JSON — traverse object structure
1203
+ debug.processflow_format = 'json';
1204
+ var pfData = pfRaw.result || pfRaw;
1205
+ debug.processflow_keys = pfData && typeof pfData === 'object' ? Object.keys(pfData).slice(0, 20) : null;
1206
+
1207
+ var pfTriggers = pfData?.triggerInstances || pfData?.trigger_instances || pfData?.triggers || [];
1208
+ if (!Array.isArray(pfTriggers) && pfData?.model?.triggerInstances) {
1209
+ pfTriggers = pfData.model.triggerInstances;
1210
+ }
1211
+ if (!Array.isArray(pfTriggers) && pfData?.definition?.triggerInstances) {
1212
+ pfTriggers = pfData.definition.triggerInstances;
1213
+ }
1186
1214
 
1187
- // If trigger not found in expected structure, search recursively in the response
1188
- if (!triggerName && pfData) {
1189
- var searchForTrigger = function (obj: any, depth: number): void {
1190
- if (depth > 4 || triggerName) return;
1191
- if (!obj || typeof obj !== 'object') return;
1192
- // Look for objects that have triggerDefinitionId or triggerType + name
1193
- if (obj.triggerDefinitionId && obj.name) {
1194
- triggerName = obj.name;
1195
- debug.processflow_trigger_found_at = 'recursive_search';
1196
- if (obj.inputs && Array.isArray(obj.inputs)) {
1197
- for (var ri = 0; ri < obj.inputs.length; ri++) {
1198
- if (obj.inputs[ri].name === 'table') {
1199
- table = obj.inputs[ri].value?.value || str(obj.inputs[ri].value) || '';
1200
- break;
1201
- }
1215
+ if (Array.isArray(pfTriggers) && pfTriggers.length > 0) {
1216
+ var pfTrig = pfTriggers[0];
1217
+ triggerName = pfTrig.name || pfTrig.triggerName || '';
1218
+ if (pfTrig.inputs && Array.isArray(pfTrig.inputs)) {
1219
+ for (var pfi = 0; pfi < pfTrig.inputs.length; pfi++) {
1220
+ if (pfTrig.inputs[pfi].name === 'table') {
1221
+ table = pfTrig.inputs[pfi].value?.value || str(pfTrig.inputs[pfi].value) || '';
1222
+ break;
1202
1223
  }
1203
1224
  }
1204
- return;
1205
- }
1206
- if (Array.isArray(obj)) {
1207
- for (var ai = 0; ai < obj.length; ai++) searchForTrigger(obj[ai], depth + 1);
1208
- } else {
1209
- for (var key of Object.keys(obj)) searchForTrigger(obj[key], depth + 1);
1210
1225
  }
1211
- };
1212
- searchForTrigger(pfData, 0);
1226
+ }
1213
1227
  }
1214
1228
  } catch (pfErr: any) {
1215
1229
  debug.processflow_api = 'error: ' + pfErr.message;