snow-flow 10.0.1-dev.405 → 10.0.1-dev.408

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.405",
3
+ "version": "10.0.1-dev.408",
4
4
  "name": "snow-flow",
5
5
  "description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
6
6
  "license": "Elastic-2.0",
@@ -123,7 +123,9 @@ async function createFlowViaScheduledJob(
123
123
  " }",
124
124
  " } catch(t1e) { r.steps.tier1 = { success: false, error: t1e.getMessage ? t1e.getMessage() : t1e + '' }; }",
125
125
  "",
126
- // ── TIER 2: GlideRecord with flow_definition ──
126
+ // ── TIER 2: GlideRecord minimal clean records ──
127
+ // Do NOT set flow_definition/latest_snapshot on flow record (computed/managed).
128
+ // Version: INSERT as draft → UPDATE is_current=true (triggers BRs that set latest_version).
127
129
  " if (!flowSysId) {",
128
130
  " try {",
129
131
  " var f = new GlideRecord('sys_hub_flow');",
@@ -133,29 +135,30 @@ async function createFlowViaScheduledJob(
133
135
  " f.setValue('run_as', runAs); f.setValue('active', false);",
134
136
  " f.setValue('status', 'draft'); f.setValue('validated', true);",
135
137
  " f.setValue('type', isSubflow ? 'subflow' : 'flow');",
136
- " if (flowDefStr) { f.setValue('flow_definition', flowDefStr); f.setValue('latest_snapshot', flowDefStr); }",
137
138
  " flowSysId = f.insert();",
138
139
  " r.steps.flow_insert = { success: !!flowSysId, sys_id: flowSysId + '' };",
139
140
  " if (flowSysId) {",
141
+ // Step 1: INSERT version as minimal draft
140
142
  " var v = new GlideRecord('sys_hub_flow_version');",
141
143
  " v.initialize();",
142
144
  " v.setValue('flow', flowSysId); v.setValue('name', '1.0');",
143
145
  " v.setValue('version', '1.0'); v.setValue('state', 'draft');",
144
- " v.setValue('active', true); v.setValue('compile_state', 'draft');",
145
- " v.setValue('is_current', true);",
146
- " if (flowDefStr) v.setValue('flow_definition', flowDefStr);",
146
+ " v.setValue('active', false); v.setValue('compile_state', 'draft');",
147
+ " v.setValue('is_current', false);",
147
148
  " verSysId = v.insert();",
148
149
  " r.steps.version_insert = { success: !!verSysId, sys_id: verSysId + '' };",
150
+ // Step 2: UPDATE version → is_current=true, active=true (triggers BRs)
149
151
  " if (verSysId) {",
150
- " var lk = new GlideRecord('sys_hub_flow');",
151
- " if (lk.get(flowSysId)) { lk.setValue('latest_version', verSysId); lk.update(); }",
152
- " }",
153
- " if (activate) {",
154
- " var fp = new GlideRecord('sys_hub_flow');",
155
- " if (fp.get(flowSysId)) { fp.setValue('status', 'published'); fp.setValue('active', true); fp.update(); }",
156
- " if (verSysId) {",
157
- " var vp = new GlideRecord('sys_hub_flow_version');",
158
- " if (vp.get(verSysId)) { vp.setValue('state', 'published'); vp.setValue('compile_state', 'compiled'); vp.setValue('published_flow', flowSysId); vp.update(); }",
152
+ " var vu = new GlideRecord('sys_hub_flow_version');",
153
+ " if (vu.get(verSysId)) {",
154
+ " vu.setValue('is_current', true); vu.setValue('active', true);",
155
+ " vu.update();",
156
+ " r.steps.version_update = { success: true };",
157
+ " }",
158
+ // Check if BR set latest_version
159
+ " var lvCheck = new GlideRecord('sys_hub_flow');",
160
+ " if (lvCheck.get(flowSysId)) {",
161
+ " r.steps.latest_version_after_update = lvCheck.getValue('latest_version') + '';",
159
162
  " }",
160
163
  " }",
161
164
  " r.tier_used = 'gliderecord_scheduled'; r.success = true;",
@@ -165,80 +168,68 @@ async function createFlowViaScheduledJob(
165
168
  "",
166
169
  // ── Trigger, action, variable creation (runs for any tier) ──
167
170
  " if (flowSysId) {",
168
- // Trigger — search broadly (no type filter, internal_name varies per instance)
171
+ // Trigger — precise search with prefix matching + fallback without action_type
169
172
  " if (!isSubflow && trigType !== 'manual') {",
170
173
  " 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
174
  " var trigDefId = null;",
175
+ " var trigDefName = '';",
179
176
  " var trigSearchLog = [];",
180
- // Search 1: CONTAINS on internal_name (NO type filter — 'type' column values vary)
181
- " for (var ts = 0; ts < terms.length; ts++) {",
182
- " var tg = new GlideRecord('sys_hub_action_type_definition');",
183
- " tg.addQuery('internal_name', 'CONTAINS', terms[ts]);",
184
- " tg.setLimit(5); tg.query();",
185
- " while (tg.next()) {",
186
- " var tgType = tg.getValue('type') + '';",
187
- " var tgName = tg.getValue('internal_name') + '';",
188
- " trigSearchLog.push(terms[ts] + ':' + tgName + '(type=' + tgType + ')');",
189
- " if (!trigDefId) { trigDef = tg; trigDefId = tg.getUniqueValue(); }",
177
+ "",
178
+ // Search 1: exact prefix 'sn_fd.trigger.' (standard Flow Designer naming)
179
+ " var exactNames = {",
180
+ " 'record_created': ['sn_fd.trigger.record_created', 'global.sn_fd.trigger.record_created'],",
181
+ " 'record_updated': ['sn_fd.trigger.record_updated', 'global.sn_fd.trigger.record_updated'],",
182
+ " 'scheduled': ['sn_fd.trigger.scheduled', 'global.sn_fd.trigger.scheduled']",
183
+ " };",
184
+ " var exactCandidates = exactNames[trigType] || [];",
185
+ " for (var ec = 0; ec < exactCandidates.length; ec++) {",
186
+ " var tgE = new GlideRecord('sys_hub_action_type_definition');",
187
+ " tgE.addQuery('internal_name', exactCandidates[ec]);",
188
+ " tgE.setLimit(1); tgE.query();",
189
+ " if (tgE.next()) {",
190
+ " trigDefId = tgE.getUniqueValue(); trigDefName = tgE.getValue('name');",
191
+ " trigSearchLog.push('exact:' + exactCandidates[ec] + ':found');",
192
+ " break;",
190
193
  " }",
191
- " if (trigDefId) break;",
194
+ " trigSearchLog.push('exact:' + exactCandidates[ec] + ':not_found');",
192
195
  " }",
193
- // Search 2: by display name (no type filter)
196
+ "",
197
+ // Search 2: prefix STARTSWITH 'sn_fd.trigger' (catches variations)
194
198
  " if (!trigDefId) {",
195
- " var tg2 = new GlideRecord('sys_hub_action_type_definition');",
196
- " tg2.addQuery('name', 'CONTAINS', trigType.replace('_', ' '));",
197
- " tg2.setLimit(5); tg2.query();",
198
- " while (tg2.next()) {",
199
- " var tg2Type = tg2.getValue('type') + '';",
200
- " var tg2Name = tg2.getValue('internal_name') + '';",
201
- " trigSearchLog.push('name:' + tg2Name + '(type=' + tg2Type + ')');",
202
- " if (!trigDefId) { trigDef = tg2; trigDefId = tg2.getUniqueValue(); }",
199
+ " var tgP = new GlideRecord('sys_hub_action_type_definition');",
200
+ " tgP.addQuery('internal_name', 'STARTSWITH', 'sn_fd.trigger');",
201
+ " tgP.setLimit(10); tgP.query();",
202
+ " var prefixMatches = [];",
203
+ " while (tgP.next()) {",
204
+ " prefixMatches.push(tgP.getValue('internal_name'));",
205
+ " if (!trigDefId && (tgP.getValue('internal_name') + '').indexOf(trigType.replace('record_', '')) > -1) {",
206
+ " trigDefId = tgP.getUniqueValue(); trigDefName = tgP.getValue('name');",
207
+ " }",
203
208
  " }",
209
+ " trigSearchLog.push('prefix_sn_fd.trigger:[' + prefixMatches.join(',') + ']');",
204
210
  " }",
205
- // Search 3: sys_hub_trigger_definition table (alternative on some instances)
206
- " if (!trigDefId) {",
207
- " try {",
208
- " var tg3 = new GlideRecord('sys_hub_trigger_definition');",
209
- " if (tg3.isValid()) {",
210
- " tg3.addQuery('internal_name', 'CONTAINS', terms[0]);",
211
- " tg3.setLimit(3); tg3.query();",
212
- " while (tg3.next()) {",
213
- " trigSearchLog.push('trig_def_table:' + tg3.getValue('internal_name'));",
214
- " if (!trigDefId) { trigDef = tg3; trigDefId = tg3.getUniqueValue(); }",
215
- " }",
216
- " } else { trigSearchLog.push('trig_def_table:invalid'); }",
217
- " } catch(e3) { trigSearchLog.push('trig_def_table:error'); }",
218
- " }",
219
- // Discovery: log what type values exist (helps debug trigger issues)
220
- " if (!trigDefId) {",
221
- " try {",
222
- " var disc = new GlideAggregate('sys_hub_action_type_definition');",
223
- " disc.addAggregate('COUNT', 'type');",
224
- " disc.groupBy('type'); disc.query();",
225
- " var typeValues = [];",
226
- " while (disc.next()) { typeValues.push(disc.getValue('type') + ':' + disc.getAggregate('COUNT', 'type')); }",
227
- " trigSearchLog.push('type_values:[' + typeValues.join(',') + ']');",
228
- " } catch(de) { trigSearchLog.push('discovery:error'); }",
229
- " }",
230
- " if (trigDefId) {",
231
- " var trigInst = new GlideRecord('sys_hub_trigger_instance');",
232
- " trigInst.initialize();",
233
- " trigInst.setValue('flow', flowSysId); trigInst.setValue('action_type', trigDefId);",
234
- " trigInst.setValue('name', trigType); trigInst.setValue('order', 0); trigInst.setValue('active', true);",
235
- " if (trigTable) trigInst.setValue('table', trigTable);",
236
- " if (trigCondition) trigInst.setValue('condition', trigCondition);",
237
- " var trigId = trigInst.insert();",
238
- " r.steps.trigger = { success: !!trigId, sys_id: trigId + '', def_name: trigDef.getValue('name'), def_internal: trigDef.getValue('internal_name'), search: trigSearchLog };",
239
- " } else {",
240
- " r.steps.trigger = { success: false, error: 'No trigger def found after broad search', search: trigSearchLog };",
241
- " }",
211
+ "",
212
+ // Search 3 removed — sys_hub_trigger_definition returned wrong defs (Proactive Analytics, DevOps)
213
+ " if (!trigDefId) { trigSearchLog.push('no_exact_trigger_def_found'); }",
214
+ "",
215
+ // Create trigger instance — only set action_type if exact sn_fd.trigger.* match found
216
+ " var trigInst = new GlideRecord('sys_hub_trigger_instance');",
217
+ " trigInst.initialize();",
218
+ " trigInst.setValue('flow', flowSysId);",
219
+ " trigInst.setValue('name', trigType);",
220
+ " trigInst.setValue('order', 0);",
221
+ " trigInst.setValue('active', true);",
222
+ " if (trigDefId) trigInst.setValue('action_type', trigDefId);",
223
+ " if (trigTable) trigInst.setValue('table', trigTable);",
224
+ " if (trigCondition) trigInst.setValue('condition', trigCondition);",
225
+ " var trigId = trigInst.insert();",
226
+ " r.steps.trigger = {",
227
+ " success: !!trigId,",
228
+ " sys_id: trigId + '',",
229
+ " def_found: !!trigDefId,",
230
+ " def_name: trigDefName || 'none (created without action_type)',",
231
+ " search: trigSearchLog",
232
+ " };",
242
233
  " } catch(te) { r.steps.trigger = { success: false, error: te.getMessage ? te.getMessage() : te + '' }; }",
243
234
  " }",
244
235
  // Actions
@@ -279,11 +270,11 @@ async function createFlowViaScheduledJob(
279
270
  " }",
280
271
  " r.steps.variables = { success: true, created: varsCreated };",
281
272
  "",
282
- // ── Engine: probe APIs + try compile (NOT publish that StackOverflowed) ──
283
- // FlowAPI.publish() caused StackOverflowError and corrupted the flow.
284
- // FlowAPI.compile() should be safer it registers the flow with the
285
- // engine and sets latest_version without the publish side effects.
286
- " r.steps.engine = { apis_found: [], mode: 'probe_and_compile' };",
273
+ // ── Engine: PROBE ONLY do NOT call compile or publish ──
274
+ // FlowAPI.publish() StackOverflowError (corrupts flow)
275
+ // FlowAPI.compile() "success" but doesn't set latest_version, may corrupt
276
+ // Just probe what APIs exist for diagnostics.
277
+ " r.steps.engine = { apis_found: [], mode: 'probe_only' };",
287
278
  " try {",
288
279
  " if (typeof sn_fd !== 'undefined') {",
289
280
  " r.steps.engine.sn_fd = 'available';",
@@ -302,24 +293,6 @@ async function createFlowViaScheduledJob(
302
293
  " }",
303
294
  " } catch(e) {}",
304
295
  " }",
305
- // Try compile (safe) — DO NOT try publish (StackOverflowError)
306
- " var compiled = false;",
307
- // Priority 1: FlowDesigner.compileFlow (most specific)
308
- " if (!compiled && sn_fd.FlowDesigner && typeof sn_fd.FlowDesigner.compileFlow === 'function') {",
309
- " try { sn_fd.FlowDesigner.compileFlow(flowSysId); r.steps.engine.compile = 'FlowDesigner.compileFlow:success'; compiled = true; }",
310
- " catch(e) { r.steps.engine.compile = 'FlowDesigner.compileFlow:' + (e.getMessage ? e.getMessage() : e + ''); }",
311
- " }",
312
- // Priority 2: FlowCompiler.compile
313
- " if (!compiled && sn_fd.FlowCompiler && typeof sn_fd.FlowCompiler.compile === 'function') {",
314
- " try { sn_fd.FlowCompiler.compile(flowSysId); r.steps.engine.compile = 'FlowCompiler.compile:success'; compiled = true; }",
315
- " catch(e) { r.steps.engine.compile = 'FlowCompiler.compile:' + (e.getMessage ? e.getMessage() : e + ''); }",
316
- " }",
317
- // Priority 3: FlowAPI.compile (available on this instance per diagnostics)
318
- " if (!compiled && sn_fd.FlowAPI && typeof sn_fd.FlowAPI.compile === 'function') {",
319
- " try { sn_fd.FlowAPI.compile(flowSysId); r.steps.engine.compile = 'FlowAPI.compile:success'; compiled = true; }",
320
- " catch(e) { r.steps.engine.compile = 'FlowAPI.compile:' + (e.getMessage ? e.getMessage() : e + ''); }",
321
- " }",
322
- " r.steps.engine.compiled = compiled;",
323
296
  " } else {",
324
297
  " r.steps.engine.sn_fd = 'unavailable';",
325
298
  " }",
@@ -1528,54 +1501,59 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
1528
1501
  }
1529
1502
 
1530
1503
  // Create trigger instance (non-manual flows only)
1531
- // Search broadly internal_name varies across ServiceNow instances
1504
+ // Use precise prefix search, then fallback to creating without action_type
1532
1505
  if (!isSubflow && triggerType !== 'manual') {
1533
1506
  try {
1534
- var trigSearchTerms: Record<string, string[]> = {
1535
- 'record_created': ['record_created', 'record_insert', 'created'],
1536
- 'record_updated': ['record_updated', 'record_update', 'updated'],
1537
- 'scheduled': ['scheduled', 'timer', 'schedule']
1538
- };
1539
- var searchTerms = trigSearchTerms[triggerType] || [triggerType];
1540
1507
  var triggerDefId: string | null = null;
1541
1508
 
1542
- for (var tsi = 0; tsi < searchTerms.length && !triggerDefId; tsi++) {
1543
- var triggerDefResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1509
+ // Search 1: exact sn_fd.trigger.* prefix
1510
+ var exactTrigNames: Record<string, string[]> = {
1511
+ 'record_created': ['sn_fd.trigger.record_created', 'global.sn_fd.trigger.record_created'],
1512
+ 'record_updated': ['sn_fd.trigger.record_updated', 'global.sn_fd.trigger.record_updated'],
1513
+ 'scheduled': ['sn_fd.trigger.scheduled', 'global.sn_fd.trigger.scheduled']
1514
+ };
1515
+ var exactCands = exactTrigNames[triggerType] || [];
1516
+ for (var eci = 0; eci < exactCands.length && !triggerDefId; eci++) {
1517
+ var exactResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1544
1518
  params: {
1545
- sysparm_query: 'internal_nameLIKE' + searchTerms[tsi] + '^type=trigger',
1519
+ sysparm_query: 'internal_name=' + exactCands[eci],
1546
1520
  sysparm_fields: 'sys_id',
1547
1521
  sysparm_limit: 1
1548
1522
  }
1549
1523
  });
1550
- triggerDefId = triggerDefResp.data.result?.[0]?.sys_id || null;
1524
+ triggerDefId = exactResp.data.result?.[0]?.sys_id || null;
1551
1525
  }
1552
1526
 
1553
- // Fallback: search by display name
1527
+ // Search 2: STARTSWITH sn_fd.trigger
1554
1528
  if (!triggerDefId) {
1555
- var trigNameResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1529
+ var prefixResp = await client.get('/api/now/table/sys_hub_action_type_definition', {
1556
1530
  params: {
1557
- sysparm_query: 'nameLIKE' + triggerType.replace(/_/g, ' ') + '^type=trigger',
1558
- sysparm_fields: 'sys_id',
1559
- sysparm_limit: 1
1531
+ sysparm_query: 'internal_nameSTARTSWITHsn_fd.trigger',
1532
+ sysparm_fields: 'sys_id,internal_name',
1533
+ sysparm_limit: 10
1560
1534
  }
1561
1535
  });
1562
- triggerDefId = trigNameResp.data.result?.[0]?.sys_id || null;
1536
+ var prefixResults = prefixResp.data.result || [];
1537
+ for (var pri = 0; pri < prefixResults.length && !triggerDefId; pri++) {
1538
+ if ((prefixResults[pri].internal_name || '').indexOf(triggerType.replace('record_', '')) > -1) {
1539
+ triggerDefId = prefixResults[pri].sys_id;
1540
+ }
1541
+ }
1563
1542
  }
1564
1543
 
1565
- if (triggerDefId) {
1566
- var triggerData: any = {
1567
- flow: flowSysId,
1568
- action_type: triggerDefId,
1569
- name: triggerType,
1570
- order: 0,
1571
- active: true
1572
- };
1573
- if (flowTable) triggerData.table = flowTable;
1574
- if (triggerCondition) triggerData.condition = triggerCondition;
1575
-
1576
- await client.post('/api/now/table/sys_hub_trigger_instance', triggerData);
1577
- triggerCreated = true;
1578
- }
1544
+ // Create trigger instance (with or without action_type)
1545
+ var triggerData: any = {
1546
+ flow: flowSysId,
1547
+ name: triggerType,
1548
+ order: 0,
1549
+ active: true
1550
+ };
1551
+ if (triggerDefId) triggerData.action_type = triggerDefId;
1552
+ if (flowTable) triggerData.table = flowTable;
1553
+ if (triggerCondition) triggerData.condition = triggerCondition;
1554
+
1555
+ await client.post('/api/now/table/sys_hub_trigger_instance', triggerData);
1556
+ triggerCreated = true;
1579
1557
  } catch (triggerError) {
1580
1558
  // Best-effort
1581
1559
  }