snow-flow 1.3.1 ā 1.3.2
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/.claude-flow/queen/queen-memory.db +0 -0
- package/.env.example +249 -14
- package/CLAUDE.md +185 -24
- package/README.md +55 -5
- package/dist/api/error-handling.js +898 -4
- package/dist/api/performance-optimizer.js +3 -2
- package/dist/cli.js +590 -200
- package/dist/config/snow-flow-config.js +320 -8
- package/dist/health/system-health.js +288 -21
- package/dist/mcp/http-transport-wrapper.js +65 -4
- package/dist/mcp/servicenow-automation-mcp-refactored.js +90 -9
- package/dist/mcp/servicenow-deployment-mcp-refactored.js +151 -2
- package/dist/mcp/servicenow-deployment-mcp.js +828 -15
- package/dist/mcp/servicenow-integration-mcp-refactored.js +100 -9
- package/dist/mcp/servicenow-intelligent-mcp.js +198 -7
- package/dist/mcp/servicenow-memory-mcp.js +2 -1
- package/dist/mcp/servicenow-operations-mcp-refactored.js +3 -2
- package/dist/mcp/servicenow-xml-flow-mcp.js +671 -0
- package/dist/mcp/shared/base-mcp-server.js +1356 -8
- package/dist/mcp/shared/mcp-resource-manager.js +304 -0
- package/dist/queen/parallel-agent-engine.js +26 -8
- package/dist/queen/servicenow-queen.js +47 -44
- package/dist/sparc/sparc-help.js +37 -26
- package/dist/sparc/team-sparc.js +60 -16
- package/dist/utils/action-type-cache.js +2 -1
- package/dist/utils/mcp-config-manager.js +7 -3
- package/dist/utils/mcp-server-manager.js +7 -3
- package/dist/utils/servicenow-client.js +134 -107
- package/dist/utils/servicenow-id-generator.js +171 -0
- package/dist/utils/snow-oauth.js +13 -8
- package/dist/utils/widget-template-generator.js +1690 -0
- package/dist/utils/xml-first-flow-generator.js +473 -0
- package/flow-update-sets/flow_build_automated_approval_flow_with_notifications_flow.xml +203 -0
- package/flow-update-sets/flow_create_approval_flow_for_equipment_requests_flow.xml +206 -0
- package/flow-update-sets/flow_create_equipment_approval_flow_with_manager_approv_flow.xml +254 -0
- package/flow-update-sets/iphone_15_pro_approval_flow.xml +203 -0
- package/flow-update-sets/test_iphone_approval_flow_flow.xml +303 -0
- package/package.json +2 -1
- package/test-config.js +55 -0
- package/test-real-monitoring.js +184 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<unload unload_date="2025-07-24T08:12:47.905Z">
|
|
3
|
+
<!-- Remote Update Set for Import -->
|
|
4
|
+
<sys_remote_update_set action="INSERT_OR_UPDATE">
|
|
5
|
+
<sys_id>a68896d8ed8a457e918b406ba00292c2</sys_id>
|
|
6
|
+
<name>Test_iPhone_Approval_Flow_Import</name>
|
|
7
|
+
<description>Flow import: Test iPhone Approval Flow</description>
|
|
8
|
+
<remote_sys_id>a68896d8ed8a457e918b406ba00292c2</remote_sys_id>
|
|
9
|
+
<state>loaded</state>
|
|
10
|
+
<application>global</application>
|
|
11
|
+
<sys_created_by>admin</sys_created_by>
|
|
12
|
+
<sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on>
|
|
13
|
+
</sys_remote_update_set>
|
|
14
|
+
|
|
15
|
+
<!-- Update XML Record for Flow -->
|
|
16
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
17
|
+
<sys_id>a792ea3c54d64e27b96512fd4c83fefb</sys_id>
|
|
18
|
+
<action>INSERT_OR_UPDATE</action>
|
|
19
|
+
<application>global</application>
|
|
20
|
+
<name>sys_hub_flow_a599b09ad5aa4f6c9ae7d12a47e0c0cf</name>
|
|
21
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_flow"><sys_hub_flow action="INSERT_OR_UPDATE"><sys_id>a599b09ad5aa4f6c9ae7d12a47e0c0cf</sys_id><name>Test iPhone Approval Flow</name><internal_name>test_iphone_approval</internal_name><description>Test flow for iPhone 15 Pro approval requests</description><active>true</active><type>flow</type><category>custom</category><sys_scope display_value="Global">global</sys_scope><access>package_private</access><run_as>user</run_as><sys_class_name>sys_hub_flow</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path><sys_updated_by>admin</sys_updated_by><sys_updated_on>2025-07-24T08:12:47.905Z</sys_updated_on><latest_snapshot>e4dbfd3712f64d52b7670d36322f142a</latest_snapshot><master_snapshot>e4dbfd3712f64d52b7670d36322f142a</master_snapshot><natlang/><copied_from/><copied_from_name/><show_draft_actions>false</show_draft_actions><show_row_wfr_actions>false</show_row_wfr_actions><show_wf_actions>false</show_wf_actions></sys_hub_flow></record_update>]]></payload>
|
|
22
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
23
|
+
<source_table>sys_hub_flow</source_table>
|
|
24
|
+
<sys_recorded_at>2025-07-24T08:12:47.905Z</sys_recorded_at>
|
|
25
|
+
<type>Flow Designer Flow</type>
|
|
26
|
+
<update_set/>
|
|
27
|
+
</sys_update_xml>
|
|
28
|
+
|
|
29
|
+
<!-- Flow Snapshot Record -->
|
|
30
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
31
|
+
<sys_id>9ab0f89debcf4a848c16b20209d85a5f</sys_id>
|
|
32
|
+
<action>INSERT_OR_UPDATE</action>
|
|
33
|
+
<application>global</application>
|
|
34
|
+
<name>sys_hub_flow_snapshot_e4dbfd3712f64d52b7670d36322f142a</name>
|
|
35
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_flow_snapshot"><sys_hub_flow_snapshot action="INSERT_OR_UPDATE"><sys_id>e4dbfd3712f64d52b7670d36322f142a</sys_id><name>Test iPhone Approval Flow</name><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><note>Initial version</note><snapshot><![CDATA[{
|
|
36
|
+
"$id": "root",
|
|
37
|
+
"type": "object",
|
|
38
|
+
"properties": {
|
|
39
|
+
"schemaVersion": "1.0",
|
|
40
|
+
"id": "a599b09ad5aa4f6c9ae7d12a47e0c0cf",
|
|
41
|
+
"name": "Test iPhone Approval Flow",
|
|
42
|
+
"description": "Test flow for iPhone 15 Pro approval requests",
|
|
43
|
+
"graph": {
|
|
44
|
+
"graphData": {
|
|
45
|
+
"nodeData": {
|
|
46
|
+
"actions": [
|
|
47
|
+
{
|
|
48
|
+
"id": "a52ab1675fc3454dbb4e475df5d15782",
|
|
49
|
+
"name": "Trigger",
|
|
50
|
+
"type": "trigger",
|
|
51
|
+
"base_type": "trigger",
|
|
52
|
+
"parents": [],
|
|
53
|
+
"children": [
|
|
54
|
+
"ed83b8af7e8747b58c6b4b7bfc7db368"
|
|
55
|
+
],
|
|
56
|
+
"outputs": {
|
|
57
|
+
"condition": "cat_item.nameSTARTSWITHiPhone^active=true",
|
|
58
|
+
"table": "sc_request"
|
|
59
|
+
},
|
|
60
|
+
"x": 100,
|
|
61
|
+
"y": 100
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "ed83b8af7e8747b58c6b4b7bfc7db368",
|
|
65
|
+
"name": "Log Request Details",
|
|
66
|
+
"type": "43c8cf0e0b200300d97d8bf637673ab4",
|
|
67
|
+
"base_type": "action",
|
|
68
|
+
"action_type_id": "43c8cf0e0b200300d97d8bf637673ab4",
|
|
69
|
+
"parents": [
|
|
70
|
+
"a52ab1675fc3454dbb4e475df5d15782"
|
|
71
|
+
],
|
|
72
|
+
"children": [
|
|
73
|
+
"e9f11d9e4cf043d2b06bdb01fa2d22ab"
|
|
74
|
+
],
|
|
75
|
+
"inputs": {
|
|
76
|
+
"script": "// Log request details\ngs.info('iPhone request created: ' + current.number, 'iPhoneFlow');\ngs.info('Requested by: ' + current.requested_for.name, 'iPhoneFlow');\ngs.info('Item: ' + current.cat_item.name, 'iPhoneFlow');\nreturn { logged: true };"
|
|
77
|
+
},
|
|
78
|
+
"outputs": {
|
|
79
|
+
"logged": "boolean"
|
|
80
|
+
},
|
|
81
|
+
"x": 300,
|
|
82
|
+
"y": 100
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "e9f11d9e4cf043d2b06bdb01fa2d22ab",
|
|
86
|
+
"name": "Manager Approval",
|
|
87
|
+
"type": "e3a61c920b200300d97d8bf637673a30",
|
|
88
|
+
"base_type": "action",
|
|
89
|
+
"action_type_id": "e3a61c920b200300d97d8bf637673a30",
|
|
90
|
+
"parents": [
|
|
91
|
+
"ed83b8af7e8747b58c6b4b7bfc7db368"
|
|
92
|
+
],
|
|
93
|
+
"children": [
|
|
94
|
+
"fde49fe1b5244c669bf7aacac2f7c5f8"
|
|
95
|
+
],
|
|
96
|
+
"inputs": {
|
|
97
|
+
"table": "sc_request",
|
|
98
|
+
"record": "{{trigger.current.sys_id}}",
|
|
99
|
+
"approver": "{{trigger.current.requested_for.manager}}",
|
|
100
|
+
"approval_field": "approval",
|
|
101
|
+
"journal_field": "comments",
|
|
102
|
+
"message": "Please approve iPhone request {{trigger.current.number}} for {{trigger.current.requested_for.name}}"
|
|
103
|
+
},
|
|
104
|
+
"outputs": {
|
|
105
|
+
"state": "string",
|
|
106
|
+
"approver_sys_id": "string",
|
|
107
|
+
"comments": "string"
|
|
108
|
+
},
|
|
109
|
+
"x": 500,
|
|
110
|
+
"y": 100
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "fde49fe1b5244c669bf7aacac2f7c5f8",
|
|
114
|
+
"name": "Send Approval Notification",
|
|
115
|
+
"type": "716281160b100300d97d8bf637673ac7",
|
|
116
|
+
"base_type": "action",
|
|
117
|
+
"action_type_id": "716281160b100300d97d8bf637673ac7",
|
|
118
|
+
"parents": [
|
|
119
|
+
"e9f11d9e4cf043d2b06bdb01fa2d22ab"
|
|
120
|
+
],
|
|
121
|
+
"children": [
|
|
122
|
+
"82e0ae1287834690a622bba7149ef4a0"
|
|
123
|
+
],
|
|
124
|
+
"inputs": {
|
|
125
|
+
"notification_id": "3c7d23a4db01030077c9a4d3ca961985",
|
|
126
|
+
"recipients": "{{trigger.current.requested_for}}",
|
|
127
|
+
"values": {
|
|
128
|
+
"request_number": "{{trigger.current.number}}",
|
|
129
|
+
"approval_status": "{{manager_approval.state}}",
|
|
130
|
+
"manager_comments": "{{manager_approval.comments}}"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"outputs": {
|
|
134
|
+
"sent": "boolean"
|
|
135
|
+
},
|
|
136
|
+
"x": 700,
|
|
137
|
+
"y": 100
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"id": "82e0ae1287834690a622bba7149ef4a0",
|
|
141
|
+
"name": "Send Rejection Notification",
|
|
142
|
+
"type": "716281160b100300d97d8bf637673ac7",
|
|
143
|
+
"base_type": "action",
|
|
144
|
+
"action_type_id": "716281160b100300d97d8bf637673ac7",
|
|
145
|
+
"parents": [
|
|
146
|
+
"fde49fe1b5244c669bf7aacac2f7c5f8"
|
|
147
|
+
],
|
|
148
|
+
"children": [],
|
|
149
|
+
"inputs": {
|
|
150
|
+
"notification_id": "3c7d23a4db01030077c9a4d3ca961985",
|
|
151
|
+
"recipients": "{{trigger.current.requested_for}}",
|
|
152
|
+
"values": {
|
|
153
|
+
"request_number": "{{trigger.current.number}}",
|
|
154
|
+
"approval_status": "{{manager_approval.state}}",
|
|
155
|
+
"rejection_reason": "{{manager_approval.comments}}"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"outputs": {
|
|
159
|
+
"sent": "boolean"
|
|
160
|
+
},
|
|
161
|
+
"x": 900,
|
|
162
|
+
"y": 100
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"triggers": [
|
|
169
|
+
{
|
|
170
|
+
"id": "a52ab1675fc3454dbb4e475df5d15782",
|
|
171
|
+
"type": "9b5a67a4db01030077c9a4d3ca961911",
|
|
172
|
+
"table": "sc_request",
|
|
173
|
+
"condition": "cat_item.nameSTARTSWITHiPhone^active=true"
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
}]]]]><![CDATA[></snapshot><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on></sys_hub_flow_snapshot></record_update>]]></payload>
|
|
178
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
179
|
+
<source_table>sys_hub_flow_snapshot</source_table>
|
|
180
|
+
<type>Flow Designer Snapshot</type>
|
|
181
|
+
</sys_update_xml>
|
|
182
|
+
|
|
183
|
+
<!-- Trigger Instance -->
|
|
184
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
185
|
+
<sys_id>8fdb4dfb110744e7a9a394b5b82ca635</sys_id>
|
|
186
|
+
<action>INSERT_OR_UPDATE</action>
|
|
187
|
+
<application>global</application>
|
|
188
|
+
<name>sys_hub_trigger_instance_a52ab1675fc3454dbb4e475df5d15782</name>
|
|
189
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_trigger_instance"><sys_hub_trigger_instance action="INSERT_OR_UPDATE"><sys_id>a52ab1675fc3454dbb4e475df5d15782</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><trigger_type>9b5a67a4db01030077c9a4d3ca961911</trigger_type><table>sc_request</table><condition>cat_item.nameSTARTSWITHiPhone^active=true</condition><order>100</order><active>true</active><sys_class_name>sys_hub_trigger_instance</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_trigger_instance></record_update>]]></payload>
|
|
190
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
191
|
+
<source_table>sys_hub_trigger_instance</source_table>
|
|
192
|
+
<type>Flow Designer Trigger</type>
|
|
193
|
+
</sys_update_xml>
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
<!-- Action Instance: Log Request Details -->
|
|
197
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
198
|
+
<sys_id>bff9b218c0354088bec21822ce8e898c</sys_id>
|
|
199
|
+
<action>INSERT_OR_UPDATE</action>
|
|
200
|
+
<application>global</application>
|
|
201
|
+
<name>sys_hub_action_instance_ed83b8af7e8747b58c6b4b7bfc7db368</name>
|
|
202
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_action_instance"><sys_hub_action_instance action="INSERT_OR_UPDATE"><sys_id>ed83b8af7e8747b58c6b4b7bfc7db368</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><action_type display_value="">43c8cf0e0b200300d97d8bf637673ab4</action_type><name>Log Request Details</name><order>100</order><active>true</active><inputs><![CDATA[{"script":"// Log request details\ngs.info('iPhone request created: ' + current.number, 'iPhoneFlow');\ngs.info('Requested by: ' + current.requested_for.name, 'iPhoneFlow');\ngs.info('Item: ' + current.cat_item.name, 'iPhoneFlow');\nreturn { logged: true };"}]]]]><![CDATA[></inputs><outputs><![CDATA[{"logged":"boolean"}]]]]><![CDATA[></outputs><condition></condition><comment_text/><sys_class_name>sys_hub_action_instance</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_action_instance></record_update>]]></payload>
|
|
203
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
204
|
+
<source_table>sys_hub_action_instance</source_table>
|
|
205
|
+
<type>Flow Designer Action</type>
|
|
206
|
+
</sys_update_xml>
|
|
207
|
+
|
|
208
|
+
<!-- Action Instance: Manager Approval -->
|
|
209
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
210
|
+
<sys_id>8c164a139fc64cf0bdc2883420975576</sys_id>
|
|
211
|
+
<action>INSERT_OR_UPDATE</action>
|
|
212
|
+
<application>global</application>
|
|
213
|
+
<name>sys_hub_action_instance_e9f11d9e4cf043d2b06bdb01fa2d22ab</name>
|
|
214
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_action_instance"><sys_hub_action_instance action="INSERT_OR_UPDATE"><sys_id>e9f11d9e4cf043d2b06bdb01fa2d22ab</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><action_type display_value="">e3a61c920b200300d97d8bf637673a30</action_type><name>Manager Approval</name><order>200</order><active>true</active><inputs><![CDATA[{"table":"sc_request","record":"{{trigger.current.sys_id}}","approver":"{{trigger.current.requested_for.manager}}","approval_field":"approval","journal_field":"comments","message":"Please approve iPhone request {{trigger.current.number}} for {{trigger.current.requested_for.name}}"}]]]]><![CDATA[></inputs><outputs><![CDATA[{"state":"string","approver_sys_id":"string","comments":"string"}]]]]><![CDATA[></outputs><condition></condition><comment_text/><sys_class_name>sys_hub_action_instance</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_action_instance></record_update>]]></payload>
|
|
215
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
216
|
+
<source_table>sys_hub_action_instance</source_table>
|
|
217
|
+
<type>Flow Designer Action</type>
|
|
218
|
+
</sys_update_xml>
|
|
219
|
+
|
|
220
|
+
<!-- Action Instance: Send Approval Notification -->
|
|
221
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
222
|
+
<sys_id>d6b213968e494bcfb1e36b08488d8882</sys_id>
|
|
223
|
+
<action>INSERT_OR_UPDATE</action>
|
|
224
|
+
<application>global</application>
|
|
225
|
+
<name>sys_hub_action_instance_fde49fe1b5244c669bf7aacac2f7c5f8</name>
|
|
226
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_action_instance"><sys_hub_action_instance action="INSERT_OR_UPDATE"><sys_id>fde49fe1b5244c669bf7aacac2f7c5f8</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><action_type display_value="">716281160b100300d97d8bf637673ac7</action_type><name>Send Approval Notification</name><order>300</order><active>true</active><inputs><![CDATA[{"notification_id":"3c7d23a4db01030077c9a4d3ca961985","recipients":"{{trigger.current.requested_for}}","values":{"request_number":"{{trigger.current.number}}","approval_status":"{{manager_approval.state}}","manager_comments":"{{manager_approval.comments}}"}}]]]]><![CDATA[></inputs><outputs><![CDATA[{"sent":"boolean"}]]]]><![CDATA[></outputs><condition>{{manager_approval.state}} == "approved"</condition><comment_text/><sys_class_name>sys_hub_action_instance</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_action_instance></record_update>]]></payload>
|
|
227
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
228
|
+
<source_table>sys_hub_action_instance</source_table>
|
|
229
|
+
<type>Flow Designer Action</type>
|
|
230
|
+
</sys_update_xml>
|
|
231
|
+
|
|
232
|
+
<!-- Action Instance: Send Rejection Notification -->
|
|
233
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
234
|
+
<sys_id>1fd258312e7c478c85a368b13bd26ac3</sys_id>
|
|
235
|
+
<action>INSERT_OR_UPDATE</action>
|
|
236
|
+
<application>global</application>
|
|
237
|
+
<name>sys_hub_action_instance_82e0ae1287834690a622bba7149ef4a0</name>
|
|
238
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_action_instance"><sys_hub_action_instance action="INSERT_OR_UPDATE"><sys_id>82e0ae1287834690a622bba7149ef4a0</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><action_type display_value="">716281160b100300d97d8bf637673ac7</action_type><name>Send Rejection Notification</name><order>400</order><active>true</active><inputs><![CDATA[{"notification_id":"3c7d23a4db01030077c9a4d3ca961985","recipients":"{{trigger.current.requested_for}}","values":{"request_number":"{{trigger.current.number}}","approval_status":"{{manager_approval.state}}","rejection_reason":"{{manager_approval.comments}}"}}]]]]><![CDATA[></inputs><outputs><![CDATA[{"sent":"boolean"}]]]]><![CDATA[></outputs><condition>{{manager_approval.state}} == "rejected"</condition><comment_text/><sys_class_name>sys_hub_action_instance</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_action_instance></record_update>]]></payload>
|
|
239
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
240
|
+
<source_table>sys_hub_action_instance</source_table>
|
|
241
|
+
<type>Flow Designer Action</type>
|
|
242
|
+
</sys_update_xml>
|
|
243
|
+
|
|
244
|
+
<!-- Flow Logic: Trigger -> First Activity -->
|
|
245
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
246
|
+
<sys_id>0975fad6759a4fe7ad4e53bf0c9ed19e</sys_id>
|
|
247
|
+
<action>INSERT_OR_UPDATE</action>
|
|
248
|
+
<application>global</application>
|
|
249
|
+
<name>sys_hub_flow_logic_428a925ed5dd46e7ae5de2b723d53058</name>
|
|
250
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_flow_logic"><sys_hub_flow_logic action="INSERT_OR_UPDATE"><sys_id>428a925ed5dd46e7ae5de2b723d53058</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><from_element>a52ab1675fc3454dbb4e475df5d15782</from_element><from_element_type>trigger</from_element_type><to_element>ed83b8af7e8747b58c6b4b7bfc7db368</to_element><to_element_type>action</to_element_type><connection_type>success</connection_type><order>100</order><sys_class_name>sys_hub_flow_logic</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_flow_logic></record_update>]]></payload>
|
|
251
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
252
|
+
<source_table>sys_hub_flow_logic</source_table>
|
|
253
|
+
<type>Flow Designer Logic</type>
|
|
254
|
+
</sys_update_xml>
|
|
255
|
+
|
|
256
|
+
<!-- Flow Logic: Activity 1 -> Activity 2 -->
|
|
257
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
258
|
+
<sys_id>978012f081b142db84ab1ea4d88e2c03</sys_id>
|
|
259
|
+
<action>INSERT_OR_UPDATE</action>
|
|
260
|
+
<application>global</application>
|
|
261
|
+
<name>sys_hub_flow_logic_9f3e7e86dba54c98b714e835e6d91f49</name>
|
|
262
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_flow_logic"><sys_hub_flow_logic action="INSERT_OR_UPDATE"><sys_id>9f3e7e86dba54c98b714e835e6d91f49</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><from_element>ed83b8af7e8747b58c6b4b7bfc7db368</from_element><from_element_type>action</from_element_type><to_element>e9f11d9e4cf043d2b06bdb01fa2d22ab</to_element><to_element_type>action</to_element_type><connection_type>success</connection_type><order>200</order><sys_class_name>sys_hub_flow_logic</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_flow_logic></record_update>]]></payload>
|
|
263
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
264
|
+
<source_table>sys_hub_flow_logic</source_table>
|
|
265
|
+
<type>Flow Designer Logic</type>
|
|
266
|
+
</sys_update_xml>
|
|
267
|
+
|
|
268
|
+
<!-- Flow Logic: Activity 2 -> Activity 3 -->
|
|
269
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
270
|
+
<sys_id>119c388818c94deb9b1e77bd07a602ab</sys_id>
|
|
271
|
+
<action>INSERT_OR_UPDATE</action>
|
|
272
|
+
<application>global</application>
|
|
273
|
+
<name>sys_hub_flow_logic_54ba277b3376433e8c5cf2bb7d1bdd96</name>
|
|
274
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_flow_logic"><sys_hub_flow_logic action="INSERT_OR_UPDATE"><sys_id>54ba277b3376433e8c5cf2bb7d1bdd96</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><from_element>e9f11d9e4cf043d2b06bdb01fa2d22ab</from_element><from_element_type>action</from_element_type><to_element>fde49fe1b5244c669bf7aacac2f7c5f8</to_element><to_element_type>action</to_element_type><connection_type>success</connection_type><order>300</order><sys_class_name>sys_hub_flow_logic</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_flow_logic></record_update>]]></payload>
|
|
275
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
276
|
+
<source_table>sys_hub_flow_logic</source_table>
|
|
277
|
+
<type>Flow Designer Logic</type>
|
|
278
|
+
</sys_update_xml>
|
|
279
|
+
|
|
280
|
+
<!-- Flow Logic: Activity 3 -> Activity 4 -->
|
|
281
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
282
|
+
<sys_id>c763af3957c7448e9a8aede9e00f12fd</sys_id>
|
|
283
|
+
<action>INSERT_OR_UPDATE</action>
|
|
284
|
+
<application>global</application>
|
|
285
|
+
<name>sys_hub_flow_logic_e63a6348a0d74c59a3920bf04f7c2f5f</name>
|
|
286
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_flow_logic"><sys_hub_flow_logic action="INSERT_OR_UPDATE"><sys_id>e63a6348a0d74c59a3920bf04f7c2f5f</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><from_element>fde49fe1b5244c669bf7aacac2f7c5f8</from_element><from_element_type>action</from_element_type><to_element>82e0ae1287834690a622bba7149ef4a0</to_element><to_element_type>action</to_element_type><connection_type>success</connection_type><order>400</order><sys_class_name>sys_hub_flow_logic</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_flow_logic></record_update>]]></payload>
|
|
287
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
288
|
+
<source_table>sys_hub_flow_logic</source_table>
|
|
289
|
+
<type>Flow Designer Logic</type>
|
|
290
|
+
</sys_update_xml>
|
|
291
|
+
|
|
292
|
+
<!-- Flow Logic: Last Activity -> End -->
|
|
293
|
+
<sys_update_xml action="INSERT_OR_UPDATE">
|
|
294
|
+
<sys_id>4a73086a3a564c43b4bb0adf7ab3d5c9</sys_id>
|
|
295
|
+
<action>INSERT_OR_UPDATE</action>
|
|
296
|
+
<application>global</application>
|
|
297
|
+
<name>sys_hub_flow_logic_3237655d076f459d8b35f38ad04e8b72</name>
|
|
298
|
+
<payload><![CDATA[<?xml version="1.0" encoding="UTF-8"?><record_update table="sys_hub_flow_logic"><sys_hub_flow_logic action="INSERT_OR_UPDATE"><sys_id>3237655d076f459d8b35f38ad04e8b72</sys_id><flow>a599b09ad5aa4f6c9ae7d12a47e0c0cf</flow><from_element>82e0ae1287834690a622bba7149ef4a0</from_element><from_element_type>action</from_element_type><to_element>END</to_element><to_element_type>end</to_element_type><connection_type>success</connection_type><order>600</order><sys_class_name>sys_hub_flow_logic</sys_class_name><sys_created_by>admin</sys_created_by><sys_created_on>2025-07-24T08:12:47.905Z</sys_created_on><sys_domain>global</sys_domain><sys_domain_path>/</sys_domain_path></sys_hub_flow_logic></record_update>]]></payload>
|
|
299
|
+
<remote_update_set>a68896d8ed8a457e918b406ba00292c2</remote_update_set>
|
|
300
|
+
<source_table>sys_hub_flow_logic</source_table>
|
|
301
|
+
<type>Flow Designer Logic</type>
|
|
302
|
+
</sys_update_xml>
|
|
303
|
+
</unload>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snow-flow",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "ServiceNow Queen Agent - Hive-Mind Intelligence for ServiceNow Development inspired by claude-flow. Transform complex workflows into elegant one-command orchestration.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"test": "jest",
|
|
15
15
|
"test:memory": "node dist/memory/memory-test.js",
|
|
16
16
|
"test:mcp-integration": "node dist/memory/mcp-integration-example.js",
|
|
17
|
+
"test:health": "node dist/health/test-system-health.js",
|
|
17
18
|
"lint": "eslint src/**/*.ts",
|
|
18
19
|
"typecheck": "tsc --noEmit",
|
|
19
20
|
"setup-mcp": "node scripts/setup-mcp.js",
|
package/test-config.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration Test Script
|
|
5
|
+
* Validates that environment variables are properly loaded into the configuration system
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Test environment variables
|
|
9
|
+
process.env.SNOW_REQUEST_TIMEOUT = '45000';
|
|
10
|
+
process.env.MCP_DEPLOYMENT_PORT = '3010';
|
|
11
|
+
process.env.SNOW_REDIRECT_PORT = '3020';
|
|
12
|
+
process.env.SNOW_FLOW_MAX_WORKER_AGENTS = '15';
|
|
13
|
+
process.env.SNOW_FLOW_LOG_LEVEL = 'debug';
|
|
14
|
+
|
|
15
|
+
// Import configuration
|
|
16
|
+
const { SnowFlowConfig } = require('./dist/config/snow-flow-config.js');
|
|
17
|
+
|
|
18
|
+
console.log('š§Ŗ Testing Configuration System...\n');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const config = new SnowFlowConfig();
|
|
22
|
+
|
|
23
|
+
console.log('ā
Configuration loaded successfully\n');
|
|
24
|
+
|
|
25
|
+
// Test basic configuration values
|
|
26
|
+
console.log('š Configuration Values:');
|
|
27
|
+
console.log(` ServiceNow timeout: ${config.servicenow.timeout}ms (expected: 45000)`);
|
|
28
|
+
console.log(` MCP Deployment port: ${config.mcp.servers.deployment.port} (expected: 3010)`);
|
|
29
|
+
console.log(` OAuth redirect port: ${config.servicenow.oauth.redirectPort} (expected: 3020)`);
|
|
30
|
+
console.log(` Max worker agents: ${config.agents.queen.maxWorkerAgents} (expected: 15)`);
|
|
31
|
+
console.log(` Log level: ${config.system.logLevel} (expected: debug)`);
|
|
32
|
+
|
|
33
|
+
// Test default values (no env vars set)
|
|
34
|
+
console.log(` MCP Intelligent port: ${config.mcp.servers.intelligent.port} (expected: 3002 - default)`);
|
|
35
|
+
console.log(` OAuth redirect host: ${config.servicenow.oauth.redirectHost} (expected: localhost - default)`);
|
|
36
|
+
|
|
37
|
+
// Test validation
|
|
38
|
+
const isValid = config.servicenow.timeout === 45000 &&
|
|
39
|
+
config.mcp.servers.deployment.port === 3010 &&
|
|
40
|
+
config.servicenow.oauth.redirectPort === 3020 &&
|
|
41
|
+
config.agents.queen.maxWorkerAgents === 15 &&
|
|
42
|
+
config.system.logLevel === 'debug';
|
|
43
|
+
|
|
44
|
+
if (isValid) {
|
|
45
|
+
console.log('\nā
All environment variables correctly loaded!');
|
|
46
|
+
console.log('ā
Configuration system is working properly');
|
|
47
|
+
} else {
|
|
48
|
+
console.log('\nā Some environment variables were not loaded correctly');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('ā Configuration test failed:', error.message);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone test for real system monitoring
|
|
3
|
+
* This demonstrates the actual system metrics being collected
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const { execSync } = require('child_process');
|
|
8
|
+
|
|
9
|
+
// Get real CPU usage
|
|
10
|
+
function getCPUUsage() {
|
|
11
|
+
const cpus = os.cpus();
|
|
12
|
+
let totalIdle = 0;
|
|
13
|
+
let totalTick = 0;
|
|
14
|
+
|
|
15
|
+
cpus.forEach(cpu => {
|
|
16
|
+
for (const type in cpu.times) {
|
|
17
|
+
totalTick += cpu.times[type];
|
|
18
|
+
}
|
|
19
|
+
totalIdle += cpu.times.idle;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const cpuUsage = 100 - ~~(100 * totalIdle / totalTick);
|
|
23
|
+
return cpuUsage;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Get real memory usage
|
|
27
|
+
function getMemoryUsage() {
|
|
28
|
+
const totalMemory = os.totalmem();
|
|
29
|
+
const freeMemory = os.freemem();
|
|
30
|
+
const usedMemory = totalMemory - freeMemory;
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
total: (totalMemory / 1024 / 1024).toFixed(0) + ' MB',
|
|
34
|
+
used: (usedMemory / 1024 / 1024).toFixed(0) + ' MB',
|
|
35
|
+
free: (freeMemory / 1024 / 1024).toFixed(0) + ' MB',
|
|
36
|
+
percentage: ((usedMemory / totalMemory) * 100).toFixed(1) + '%'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Get real disk usage
|
|
41
|
+
function getDiskUsage() {
|
|
42
|
+
try {
|
|
43
|
+
if (process.platform === 'darwin' || process.platform === 'linux') {
|
|
44
|
+
const output = execSync('df -k /', { encoding: 'utf8' });
|
|
45
|
+
const lines = output.trim().split('\n');
|
|
46
|
+
|
|
47
|
+
if (lines.length >= 2) {
|
|
48
|
+
const parts = lines[1].split(/\s+/);
|
|
49
|
+
const totalBlocks = parseInt(parts[1], 10);
|
|
50
|
+
const usedBlocks = parseInt(parts[2], 10);
|
|
51
|
+
|
|
52
|
+
const diskTotal = totalBlocks / 1024 / 1024; // Convert to GB
|
|
53
|
+
const diskUsed = usedBlocks / 1024 / 1024; // Convert to GB
|
|
54
|
+
const diskUsage = (diskUsed / diskTotal) * 100;
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
total: diskTotal.toFixed(1) + ' GB',
|
|
58
|
+
used: diskUsed.toFixed(1) + ' GB',
|
|
59
|
+
percentage: diskUsage.toFixed(1) + '%'
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
} else if (process.platform === 'win32') {
|
|
63
|
+
const output = execSync('wmic logicaldisk where caption="C:" get size,freespace /value', { encoding: 'utf8' });
|
|
64
|
+
const sizeMatch = output.match(/Size=(\d+)/);
|
|
65
|
+
const freeMatch = output.match(/FreeSpace=(\d+)/);
|
|
66
|
+
|
|
67
|
+
if (sizeMatch && freeMatch) {
|
|
68
|
+
const totalBytes = parseInt(sizeMatch[1], 10);
|
|
69
|
+
const freeBytes = parseInt(freeMatch[1], 10);
|
|
70
|
+
const usedBytes = totalBytes - freeBytes;
|
|
71
|
+
|
|
72
|
+
const diskTotal = totalBytes / 1024 / 1024 / 1024;
|
|
73
|
+
const diskUsed = usedBytes / 1024 / 1024 / 1024;
|
|
74
|
+
const diskUsage = (diskUsed / diskTotal) * 100;
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
total: diskTotal.toFixed(1) + ' GB',
|
|
78
|
+
used: diskUsed.toFixed(1) + ' GB',
|
|
79
|
+
percentage: diskUsage.toFixed(1) + '%'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return { error: error.message };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { error: 'Unsupported platform' };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Get process memory usage
|
|
91
|
+
function getProcessMemory() {
|
|
92
|
+
const usage = process.memoryUsage();
|
|
93
|
+
return {
|
|
94
|
+
heapUsed: (usage.heapUsed / 1024 / 1024).toFixed(1) + ' MB',
|
|
95
|
+
heapTotal: (usage.heapTotal / 1024 / 1024).toFixed(1) + ' MB',
|
|
96
|
+
rss: (usage.rss / 1024 / 1024).toFixed(1) + ' MB',
|
|
97
|
+
external: (usage.external / 1024 / 1024).toFixed(1) + ' MB'
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
console.log('š„ Snow-Flow Real System Health Monitoring\n');
|
|
102
|
+
console.log('Platform:', process.platform);
|
|
103
|
+
console.log('Architecture:', process.arch);
|
|
104
|
+
console.log('Node Version:', process.version);
|
|
105
|
+
console.log('CPU Cores:', os.cpus().length);
|
|
106
|
+
console.log('\nš Real-time System Metrics:\n');
|
|
107
|
+
|
|
108
|
+
// Display initial metrics
|
|
109
|
+
console.log('š» CPU Usage:', getCPUUsage() + '%');
|
|
110
|
+
|
|
111
|
+
const memory = getMemoryUsage();
|
|
112
|
+
console.log('\nš§ Memory Usage:');
|
|
113
|
+
console.log(' Total:', memory.total);
|
|
114
|
+
console.log(' Used:', memory.used, `(${memory.percentage})`);
|
|
115
|
+
console.log(' Free:', memory.free);
|
|
116
|
+
|
|
117
|
+
const disk = getDiskUsage();
|
|
118
|
+
console.log('\nš¾ Disk Usage:');
|
|
119
|
+
if (disk.error) {
|
|
120
|
+
console.log(' Error:', disk.error);
|
|
121
|
+
} else {
|
|
122
|
+
console.log(' Total:', disk.total);
|
|
123
|
+
console.log(' Used:', disk.used, `(${disk.percentage})`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const processMemory = getProcessMemory();
|
|
127
|
+
console.log('\nš§ Process Memory:');
|
|
128
|
+
console.log(' Heap Used:', processMemory.heapUsed);
|
|
129
|
+
console.log(' Heap Total:', processMemory.heapTotal);
|
|
130
|
+
console.log(' RSS:', processMemory.rss);
|
|
131
|
+
console.log(' External:', processMemory.external);
|
|
132
|
+
|
|
133
|
+
console.log('\nš Load Average:', os.loadavg().map(l => l.toFixed(2)).join(', '));
|
|
134
|
+
console.log('ā±ļø System Uptime:', (os.uptime() / 3600).toFixed(1), 'hours');
|
|
135
|
+
console.log('ā±ļø Process Uptime:', (process.uptime() / 60).toFixed(1), 'minutes');
|
|
136
|
+
|
|
137
|
+
// Monitor for 5 seconds
|
|
138
|
+
console.log('\nš Monitoring CPU usage for 5 seconds...\n');
|
|
139
|
+
|
|
140
|
+
let previousCPU = getCPUInfo();
|
|
141
|
+
const interval = setInterval(() => {
|
|
142
|
+
const currentCPU = getCPUInfo();
|
|
143
|
+
const usage = calculateCPUUsage(previousCPU, currentCPU);
|
|
144
|
+
|
|
145
|
+
process.stdout.write(`\rCPU: ${usage.toFixed(1)}% | Memory: ${getMemoryUsage().percentage} | Time: ${new Date().toLocaleTimeString()}`);
|
|
146
|
+
|
|
147
|
+
previousCPU = currentCPU;
|
|
148
|
+
}, 1000);
|
|
149
|
+
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
clearInterval(interval);
|
|
152
|
+
console.log('\n\nā
Real system monitoring complete!');
|
|
153
|
+
console.log('\nThis demonstrates that Snow-Flow is now collecting REAL system metrics, not placeholders.');
|
|
154
|
+
}, 5000);
|
|
155
|
+
|
|
156
|
+
// Helper functions for accurate CPU measurement
|
|
157
|
+
function getCPUInfo() {
|
|
158
|
+
const cpus = os.cpus();
|
|
159
|
+
return cpus.map(cpu => {
|
|
160
|
+
const total = Object.values(cpu.times).reduce((acc, time) => acc + time, 0);
|
|
161
|
+
return {
|
|
162
|
+
idle: cpu.times.idle,
|
|
163
|
+
total: total
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function calculateCPUUsage(previous, current) {
|
|
169
|
+
let totalIdleDiff = 0;
|
|
170
|
+
let totalDiff = 0;
|
|
171
|
+
|
|
172
|
+
for (let i = 0; i < current.length; i++) {
|
|
173
|
+
const idleDiff = current[i].idle - previous[i].idle;
|
|
174
|
+
const totalCPUDiff = current[i].total - previous[i].total;
|
|
175
|
+
|
|
176
|
+
totalIdleDiff += idleDiff;
|
|
177
|
+
totalDiff += totalCPUDiff;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (totalDiff === 0) return 0;
|
|
181
|
+
|
|
182
|
+
const idlePercentage = (totalIdleDiff / totalDiff) * 100;
|
|
183
|
+
return 100 - idlePercentage;
|
|
184
|
+
}
|