snow-flow 10.0.1-dev.445 → 10.0.1-dev.446

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.445",
3
+ "version": "10.0.1-dev.446",
4
4
  "name": "snow-flow",
5
5
  "description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
6
6
  "license": "Elastic-2.0",
@@ -521,6 +521,61 @@ async function addSubflowCallViaGraphQL(
521
521
  }
522
522
  }
523
523
 
524
+ // ── GENERIC UPDATE/DELETE for any flow element ───────────────────────
525
+
526
+ const elementGraphQLMap: Record<string, { key: string; type: string; responseFields: string }> = {
527
+ action: { key: 'actions', type: 'action', responseFields: 'actions { inserts { sysId uiUniqueIdentifier __typename } updates deletes __typename }' },
528
+ trigger: { key: 'triggerInstances', type: 'trigger', responseFields: 'triggerInstances { inserts { sysId uiUniqueIdentifier __typename } updates deletes __typename }' },
529
+ flowlogic: { key: 'flowLogics', type: 'flowlogic', responseFields: 'flowLogics { inserts { sysId uiUniqueIdentifier __typename } updates deletes __typename }' },
530
+ subflow: { key: 'subflows', type: 'subflow', responseFields: 'subflows { inserts { sysId uiUniqueIdentifier __typename } updates deletes __typename }' },
531
+ };
532
+
533
+ async function updateElementViaGraphQL(
534
+ client: any,
535
+ flowId: string,
536
+ elementType: string,
537
+ elementId: string,
538
+ inputs: Record<string, string>
539
+ ): Promise<{ success: boolean; steps?: any; error?: string }> {
540
+ const config = elementGraphQLMap[elementType];
541
+ if (!config) return { success: false, error: 'Unknown element type: ' + elementType };
542
+
543
+ const updateInputs = Object.entries(inputs).map(([name, value]) => ({
544
+ name,
545
+ value: { schemaless: false, schemalessValue: '', value: String(value) }
546
+ }));
547
+
548
+ try {
549
+ await executeFlowPatchMutation(client, {
550
+ flowId,
551
+ [config.key]: { update: [{ uiUniqueIdentifier: elementId, type: config.type, inputs: updateInputs }] }
552
+ }, config.responseFields);
553
+ return { success: true, steps: { element: elementId, type: elementType, inputs: updateInputs.map(i => i.name) } };
554
+ } catch (e: any) {
555
+ return { success: false, error: e.message, steps: { element: elementId, type: elementType } };
556
+ }
557
+ }
558
+
559
+ async function deleteElementViaGraphQL(
560
+ client: any,
561
+ flowId: string,
562
+ elementType: string,
563
+ elementIds: string[]
564
+ ): Promise<{ success: boolean; steps?: any; error?: string }> {
565
+ const config = elementGraphQLMap[elementType];
566
+ if (!config) return { success: false, error: 'Unknown element type: ' + elementType };
567
+
568
+ try {
569
+ await executeFlowPatchMutation(client, {
570
+ flowId,
571
+ [config.key]: { delete: elementIds }
572
+ }, config.responseFields);
573
+ return { success: true, steps: { deleted: elementIds, type: elementType } };
574
+ } catch (e: any) {
575
+ return { success: false, error: e.message, steps: { elementIds, type: elementType } };
576
+ }
577
+ }
578
+
524
579
  async function createFlowViaProcessFlowAPI(
525
580
  client: any,
526
581
  params: {
@@ -629,8 +684,14 @@ export const toolDefinition: MCPToolDefinition = {
629
684
  properties: {
630
685
  action: {
631
686
  type: 'string',
632
- enum: ['create', 'create_subflow', 'list', 'get', 'update', 'activate', 'deactivate', 'delete', 'publish', 'add_trigger', 'update_trigger', 'add_action', 'add_flow_logic', 'add_subflow'],
633
- description: 'Action to perform. Use add_trigger/add_action/add_flow_logic/add_subflow to add elements, update_trigger to change an existing trigger. Flow logic types: IF, FOR_EACH, DO_UNTIL, SWITCH. add_subflow calls an existing subflow as a step.'
687
+ enum: [
688
+ 'create', 'create_subflow', 'list', 'get', 'update', 'activate', 'deactivate', 'delete', 'publish',
689
+ 'add_trigger', 'update_trigger', 'delete_trigger',
690
+ 'add_action', 'update_action', 'delete_action',
691
+ 'add_flow_logic', 'update_flow_logic', 'delete_flow_logic',
692
+ 'add_subflow', 'update_subflow', 'delete_subflow'
693
+ ],
694
+ description: 'Action to perform. add_*/update_*/delete_* for triggers, actions, flow_logic, subflows. update_trigger replaces the trigger type. update_action/update_flow_logic/update_subflow change input values. delete_* removes elements by element_id.'
634
695
  },
635
696
 
636
697
  flow_id: {
@@ -732,6 +793,10 @@ export const toolDefinition: MCPToolDefinition = {
732
793
  type: 'string',
733
794
  description: 'Subflow sys_id or name to call as a step (for add_subflow action). Looked up in sys_hub_flow where type=subflow.'
734
795
  },
796
+ element_id: {
797
+ type: 'string',
798
+ description: 'Element sys_id or uiUniqueIdentifier for update_*/delete_* actions. For delete_* this can also be a comma-separated list of IDs.'
799
+ },
735
800
  type: {
736
801
  type: 'string',
737
802
  enum: ['flow', 'subflow', 'all'],
@@ -1738,6 +1803,62 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
1738
1803
  : createErrorResult(addSubResult.error || 'Failed to add subflow call');
1739
1804
  }
1740
1805
 
1806
+ // ────────────────────────────────────────────────────────────────
1807
+ // UPDATE_ACTION / UPDATE_FLOW_LOGIC / UPDATE_SUBFLOW
1808
+ // ────────────────────────────────────────────────────────────────
1809
+ case 'update_action':
1810
+ case 'update_flow_logic':
1811
+ case 'update_subflow': {
1812
+ if (!args.flow_id) throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'flow_id is required');
1813
+ if (!args.element_id) throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'element_id is required (sys_id or uiUniqueIdentifier of the element)');
1814
+ var updElemFlowId = await resolveFlowId(client, args.flow_id);
1815
+ var updElemType = action === 'update_action' ? 'action' : action === 'update_flow_logic' ? 'flowlogic' : 'subflow';
1816
+ var updElemInputs = args.action_inputs || args.logic_inputs || args.inputs || {};
1817
+
1818
+ var updElemResult = await updateElementViaGraphQL(client, updElemFlowId, updElemType, args.element_id, updElemInputs);
1819
+
1820
+ var updElemSummary = summary();
1821
+ if (updElemResult.success) {
1822
+ updElemSummary.success('Element updated').field('Type', updElemType).field('Element', args.element_id);
1823
+ } else {
1824
+ updElemSummary.error('Failed to update element: ' + (updElemResult.error || 'unknown'));
1825
+ }
1826
+ return updElemResult.success
1827
+ ? createSuccessResult({ action, ...updElemResult }, {}, updElemSummary.build())
1828
+ : createErrorResult(updElemResult.error || 'Failed to update element');
1829
+ }
1830
+
1831
+ // ────────────────────────────────────────────────────────────────
1832
+ // DELETE_ACTION / DELETE_FLOW_LOGIC / DELETE_SUBFLOW / DELETE_TRIGGER
1833
+ // ────────────────────────────────────────────────────────────────
1834
+ case 'delete_action':
1835
+ case 'delete_flow_logic':
1836
+ case 'delete_subflow':
1837
+ case 'delete_trigger': {
1838
+ if (!args.flow_id) throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'flow_id is required');
1839
+ if (!args.element_id) throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'element_id is required (sys_id(s) to delete, comma-separated for multiple)');
1840
+ var delElemFlowId = await resolveFlowId(client, args.flow_id);
1841
+ var delElemType = action === 'delete_action' ? 'action'
1842
+ : action === 'delete_flow_logic' ? 'flowlogic'
1843
+ : action === 'delete_subflow' ? 'subflow'
1844
+ : 'trigger';
1845
+ var delElemIds = String(args.element_id).split(',').map((id: string) => id.trim());
1846
+
1847
+ // Map 'trigger' to the correct GraphQL key
1848
+ var delGraphQLType = delElemType === 'trigger' ? 'trigger' : delElemType;
1849
+ var delResult = await deleteElementViaGraphQL(client, delElemFlowId, delGraphQLType, delElemIds);
1850
+
1851
+ var delSummary = summary();
1852
+ if (delResult.success) {
1853
+ delSummary.success('Element(s) deleted').field('Type', delElemType).field('Deleted', delElemIds.join(', '));
1854
+ } else {
1855
+ delSummary.error('Failed to delete element: ' + (delResult.error || 'unknown'));
1856
+ }
1857
+ return delResult.success
1858
+ ? createSuccessResult({ action, ...delResult }, {}, delSummary.build())
1859
+ : createErrorResult(delResult.error || 'Failed to delete element');
1860
+ }
1861
+
1741
1862
  default:
1742
1863
  throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'Unknown action: ' + action);
1743
1864
  }