snow-flow 10.0.1-dev.404 → 10.0.1-dev.407

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.404",
3
+ "version": "10.0.1-dev.407",
4
4
  "name": "snow-flow",
5
5
  "description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
6
6
  "license": "Elastic-2.0",
@@ -165,46 +165,81 @@ async function createFlowViaScheduledJob(
165
165
  "",
166
166
  // ── Trigger, action, variable creation (runs for any tier) ──
167
167
  " if (flowSysId) {",
168
- // Trigger — search broadly for trigger definition (internal_name varies per instance)
168
+ // Trigger — precise search with prefix matching + fallback without action_type
169
169
  " if (!isSubflow && trigType !== 'manual') {",
170
170
  " try {",
171
- " var trigSearchTerms = {",
172
- " 'record_created': ['record_created', 'record_insert', 'created'],",
173
- " 'record_updated': ['record_updated', 'record_update', 'updated'],",
174
- " 'scheduled': ['scheduled', 'timer', 'schedule']",
175
- " };",
176
- " var terms = trigSearchTerms[trigType] || [trigType];",
177
- " var trigDef = null;",
178
171
  " var trigDefId = null;",
172
+ " var trigDefName = '';",
179
173
  " var trigSearchLog = [];",
180
- " for (var ts = 0; ts < terms.length; ts++) {",
181
- " var tg = new GlideRecord('sys_hub_action_type_definition');",
182
- " tg.addQuery('internal_name', 'CONTAINS', terms[ts]);",
183
- " tg.addQuery('type', 'trigger');",
184
- " tg.setLimit(1); tg.query();",
185
- " if (tg.next()) { trigDef = tg; trigDefId = tg.getUniqueValue(); trigSearchLog.push(terms[ts] + ':found'); break; }",
186
- " trigSearchLog.push(terms[ts] + ':not_found');",
174
+ "",
175
+ // Search 1: exact prefix 'sn_fd.trigger.' (standard Flow Designer naming)
176
+ " var exactNames = {",
177
+ " 'record_created': ['sn_fd.trigger.record_created', 'global.sn_fd.trigger.record_created'],",
178
+ " 'record_updated': ['sn_fd.trigger.record_updated', 'global.sn_fd.trigger.record_updated'],",
179
+ " 'scheduled': ['sn_fd.trigger.scheduled', 'global.sn_fd.trigger.scheduled']",
180
+ " };",
181
+ " var exactCandidates = exactNames[trigType] || [];",
182
+ " for (var ec = 0; ec < exactCandidates.length; ec++) {",
183
+ " var tgE = new GlideRecord('sys_hub_action_type_definition');",
184
+ " tgE.addQuery('internal_name', exactCandidates[ec]);",
185
+ " tgE.setLimit(1); tgE.query();",
186
+ " if (tgE.next()) {",
187
+ " trigDefId = tgE.getUniqueValue(); trigDefName = tgE.getValue('name');",
188
+ " trigSearchLog.push('exact:' + exactCandidates[ec] + ':found');",
189
+ " break;",
190
+ " }",
191
+ " trigSearchLog.push('exact:' + exactCandidates[ec] + ':not_found');",
187
192
  " }",
193
+ "",
194
+ // Search 2: prefix STARTSWITH 'sn_fd.trigger' (catches variations)
188
195
  " if (!trigDefId) {",
189
- " var tg2 = new GlideRecord('sys_hub_action_type_definition');",
190
- " tg2.addQuery('name', 'CONTAINS', trigType.replace('_', ' '));",
191
- " tg2.addQuery('type', 'trigger');",
192
- " tg2.setLimit(1); tg2.query();",
193
- " if (tg2.next()) { trigDef = tg2; trigDefId = tg2.getUniqueValue(); trigSearchLog.push('name_search:found'); }",
194
- " else { trigSearchLog.push('name_search:not_found'); }",
196
+ " var tgP = new GlideRecord('sys_hub_action_type_definition');",
197
+ " tgP.addQuery('internal_name', 'STARTSWITH', 'sn_fd.trigger');",
198
+ " tgP.setLimit(10); tgP.query();",
199
+ " var prefixMatches = [];",
200
+ " while (tgP.next()) {",
201
+ " prefixMatches.push(tgP.getValue('internal_name'));",
202
+ " if (!trigDefId && (tgP.getValue('internal_name') + '').indexOf(trigType.replace('record_', '')) > -1) {",
203
+ " trigDefId = tgP.getUniqueValue(); trigDefName = tgP.getValue('name');",
204
+ " }",
205
+ " }",
206
+ " trigSearchLog.push('prefix_sn_fd.trigger:[' + prefixMatches.join(',') + ']');",
195
207
  " }",
196
- " if (trigDefId) {",
197
- " var trigInst = new GlideRecord('sys_hub_trigger_instance');",
198
- " trigInst.initialize();",
199
- " trigInst.setValue('flow', flowSysId); trigInst.setValue('action_type', trigDefId);",
200
- " trigInst.setValue('name', trigType); trigInst.setValue('order', 0); trigInst.setValue('active', true);",
201
- " if (trigTable) trigInst.setValue('table', trigTable);",
202
- " if (trigCondition) trigInst.setValue('condition', trigCondition);",
203
- " var trigId = trigInst.insert();",
204
- " r.steps.trigger = { success: !!trigId, sys_id: trigId + '', def_name: trigDef.getValue('name'), search: trigSearchLog };",
205
- " } else {",
206
- " r.steps.trigger = { success: false, error: 'No trigger def found', search: trigSearchLog };",
208
+ "",
209
+ // Search 3: sys_hub_trigger_definition table
210
+ " if (!trigDefId) {",
211
+ " try {",
212
+ " var tg3 = new GlideRecord('sys_hub_trigger_definition');",
213
+ " if (tg3.isValid()) {",
214
+ " tg3.addQuery('internal_name', 'CONTAINS', trigType);",
215
+ " tg3.setLimit(5); tg3.query();",
216
+ " while (tg3.next()) {",
217
+ " var t3n = tg3.getValue('internal_name') + '';",
218
+ " trigSearchLog.push('trigger_def:' + t3n);",
219
+ " if (!trigDefId) { trigDefId = tg3.getUniqueValue(); trigDefName = tg3.getValue('name'); }",
220
+ " }",
221
+ " } else { trigSearchLog.push('trigger_def_table:not_valid'); }",
222
+ " } catch(e3) { trigSearchLog.push('trigger_def_table:' + e3); }",
207
223
  " }",
224
+ "",
225
+ // Create trigger instance
226
+ " var trigInst = new GlideRecord('sys_hub_trigger_instance');",
227
+ " trigInst.initialize();",
228
+ " trigInst.setValue('flow', flowSysId);",
229
+ " trigInst.setValue('name', trigType);",
230
+ " trigInst.setValue('order', 0);",
231
+ " trigInst.setValue('active', true);",
232
+ " if (trigDefId) trigInst.setValue('action_type', trigDefId);",
233
+ " if (trigTable) trigInst.setValue('table', trigTable);",
234
+ " if (trigCondition) trigInst.setValue('condition', trigCondition);",
235
+ " var trigId = trigInst.insert();",
236
+ " r.steps.trigger = {",
237
+ " success: !!trigId,",
238
+ " sys_id: trigId + '',",
239
+ " def_found: !!trigDefId,",
240
+ " def_name: trigDefName || 'none (created without action_type)',",
241
+ " search: trigSearchLog",
242
+ " };",
208
243
  " } catch(te) { r.steps.trigger = { success: false, error: te.getMessage ? te.getMessage() : te + '' }; }",
209
244
  " }",
210
245
  // Actions
@@ -245,11 +280,11 @@ async function createFlowViaScheduledJob(
245
280
  " }",
246
281
  " r.steps.variables = { success: true, created: varsCreated };",
247
282
  "",
248
- // ── Engine probe (discovery only do NOT call publish/compile) ──
249
- // Previous versions called FlowAPI.publish() which caused StackOverflowError
250
- // and corrupted the flow. Now we only probe which APIs exist for diagnostics.
251
- // The flow is left as a clean draft; user publishes via Flow Designer UI.
252
- " r.steps.engine = { apis_found: [], mode: 'probe_only' };",
283
+ // ── Engine: probe APIs + try compile (NOT publish — that StackOverflowed) ──
284
+ // FlowAPI.publish() caused StackOverflowError and corrupted the flow.
285
+ // FlowAPI.compile() should be safer it registers the flow with the
286
+ // engine and sets latest_version without the publish side effects.
287
+ " r.steps.engine = { apis_found: [], mode: 'probe_and_compile' };",
253
288
  " try {",
254
289
  " if (typeof sn_fd !== 'undefined') {",
255
290
  " r.steps.engine.sn_fd = 'available';",
@@ -268,6 +303,24 @@ async function createFlowViaScheduledJob(
268
303
  " }",
269
304
  " } catch(e) {}",
270
305
  " }",
306
+ // Try compile (safe) — DO NOT try publish (StackOverflowError)
307
+ " var compiled = false;",
308
+ // Priority 1: FlowDesigner.compileFlow (most specific)
309
+ " if (!compiled && sn_fd.FlowDesigner && typeof sn_fd.FlowDesigner.compileFlow === 'function') {",
310
+ " try { sn_fd.FlowDesigner.compileFlow(flowSysId); r.steps.engine.compile = 'FlowDesigner.compileFlow:success'; compiled = true; }",
311
+ " catch(e) { r.steps.engine.compile = 'FlowDesigner.compileFlow:' + (e.getMessage ? e.getMessage() : e + ''); }",
312
+ " }",
313
+ // Priority 2: FlowCompiler.compile
314
+ " if (!compiled && sn_fd.FlowCompiler && typeof sn_fd.FlowCompiler.compile === 'function') {",
315
+ " try { sn_fd.FlowCompiler.compile(flowSysId); r.steps.engine.compile = 'FlowCompiler.compile:success'; compiled = true; }",
316
+ " catch(e) { r.steps.engine.compile = 'FlowCompiler.compile:' + (e.getMessage ? e.getMessage() : e + ''); }",
317
+ " }",
318
+ // Priority 3: FlowAPI.compile (available on this instance per diagnostics)
319
+ " if (!compiled && sn_fd.FlowAPI && typeof sn_fd.FlowAPI.compile === 'function') {",
320
+ " try { sn_fd.FlowAPI.compile(flowSysId); r.steps.engine.compile = 'FlowAPI.compile:success'; compiled = true; }",
321
+ " catch(e) { r.steps.engine.compile = 'FlowAPI.compile:' + (e.getMessage ? e.getMessage() : e + ''); }",
322
+ " }",
323
+ " r.steps.engine.compiled = compiled;",
271
324
  " } else {",
272
325
  " r.steps.engine.sn_fd = 'unavailable';",
273
326
  " }",
@@ -1476,54 +1529,59 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
1476
1529
  }
1477
1530
 
1478
1531
  // Create trigger instance (non-manual flows only)
1479
- // Search broadly internal_name varies across ServiceNow instances
1532
+ // Use precise prefix search, then fallback to creating without action_type
1480
1533
  if (!isSubflow && triggerType !== 'manual') {
1481
1534
  try {
1482
- var trigSearchTerms: Record<string, string[]> = {
1483
- 'record_created': ['record_created', 'record_insert', 'created'],
1484
- 'record_updated': ['record_updated', 'record_update', 'updated'],
1485
- 'scheduled': ['scheduled', 'timer', 'schedule']
1486
- };
1487
- var searchTerms = trigSearchTerms[triggerType] || [triggerType];
1488
1535
  var triggerDefId: string | null = null;
1489
1536
 
1490
- for (var tsi = 0; tsi < searchTerms.length && !triggerDefId; tsi++) {
1491
- var triggerDefResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1537
+ // Search 1: exact sn_fd.trigger.* prefix
1538
+ var exactTrigNames: Record<string, string[]> = {
1539
+ 'record_created': ['sn_fd.trigger.record_created', 'global.sn_fd.trigger.record_created'],
1540
+ 'record_updated': ['sn_fd.trigger.record_updated', 'global.sn_fd.trigger.record_updated'],
1541
+ 'scheduled': ['sn_fd.trigger.scheduled', 'global.sn_fd.trigger.scheduled']
1542
+ };
1543
+ var exactCands = exactTrigNames[triggerType] || [];
1544
+ for (var eci = 0; eci < exactCands.length && !triggerDefId; eci++) {
1545
+ var exactResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1492
1546
  params: {
1493
- sysparm_query: 'internal_nameLIKE' + searchTerms[tsi] + '^type=trigger',
1547
+ sysparm_query: 'internal_name=' + exactCands[eci],
1494
1548
  sysparm_fields: 'sys_id',
1495
1549
  sysparm_limit: 1
1496
1550
  }
1497
1551
  });
1498
- triggerDefId = triggerDefResp.data.result?.[0]?.sys_id || null;
1552
+ triggerDefId = exactResp.data.result?.[0]?.sys_id || null;
1499
1553
  }
1500
1554
 
1501
- // Fallback: search by display name
1555
+ // Search 2: STARTSWITH sn_fd.trigger
1502
1556
  if (!triggerDefId) {
1503
- var trigNameResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1557
+ var prefixResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1504
1558
  params: {
1505
- sysparm_query: 'nameLIKE' + triggerType.replace(/_/g, ' ') + '^type=trigger',
1506
- sysparm_fields: 'sys_id',
1507
- sysparm_limit: 1
1559
+ sysparm_query: 'internal_nameSTARTSWITHsn_fd.trigger',
1560
+ sysparm_fields: 'sys_id,internal_name',
1561
+ sysparm_limit: 10
1508
1562
  }
1509
1563
  });
1510
- triggerDefId = trigNameResp.data.result?.[0]?.sys_id || null;
1564
+ var prefixResults = prefixResp.data.result || [];
1565
+ for (var pri = 0; pri < prefixResults.length && !triggerDefId; pri++) {
1566
+ if ((prefixResults[pri].internal_name || '').indexOf(triggerType.replace('record_', '')) > -1) {
1567
+ triggerDefId = prefixResults[pri].sys_id;
1568
+ }
1569
+ }
1511
1570
  }
1512
1571
 
1513
- if (triggerDefId) {
1514
- var triggerData: any = {
1515
- flow: flowSysId,
1516
- action_type: triggerDefId,
1517
- name: triggerType,
1518
- order: 0,
1519
- active: true
1520
- };
1521
- if (flowTable) triggerData.table = flowTable;
1522
- if (triggerCondition) triggerData.condition = triggerCondition;
1523
-
1524
- await client.post('/api/now/table/sys_hub_trigger_instance', triggerData);
1525
- triggerCreated = true;
1526
- }
1572
+ // Create trigger instance (with or without action_type)
1573
+ var triggerData: any = {
1574
+ flow: flowSysId,
1575
+ name: triggerType,
1576
+ order: 0,
1577
+ active: true
1578
+ };
1579
+ if (triggerDefId) triggerData.action_type = triggerDefId;
1580
+ if (flowTable) triggerData.table = flowTable;
1581
+ if (triggerCondition) triggerData.condition = triggerCondition;
1582
+
1583
+ await client.post('/api/now/table/sys_hub_trigger_instance', triggerData);
1584
+ triggerCreated = true;
1527
1585
  } catch (triggerError) {
1528
1586
  // Best-effort
1529
1587
  }