@arbium/enterprise-agent-connect 0.2.0 → 0.2.1-dev.7b4e802

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.
Files changed (68) hide show
  1. package/README.md +10 -3
  2. package/dist/connectors/adestra/connector.json +336 -0
  3. package/dist/connectors/adobe-admin-console/connector.json +212 -0
  4. package/dist/connectors/argo-cd/connector.json +210 -0
  5. package/dist/connectors/automox/connector.json +376 -0
  6. package/dist/connectors/churnzero/connector.json +238 -0
  7. package/dist/connectors/confluence/connector.json +168 -0
  8. package/dist/connectors/cvent/connector.json +287 -0
  9. package/dist/connectors/datadog/connector.json +188 -0
  10. package/dist/connectors/drata/connector.json +447 -0
  11. package/dist/connectors/druva/connector.json +258 -0
  12. package/dist/connectors/forsta-decipher/connector.json +164 -0
  13. package/dist/connectors/gitlab/connector.json +263 -0
  14. package/dist/connectors/grafana/connector.json +162 -0
  15. package/dist/connectors/http/index.d.ts +5 -1
  16. package/dist/connectors/http/index.js +62 -8
  17. package/dist/connectors/http/index.js.map +1 -1
  18. package/dist/connectors/http/openapi.d.ts +62 -0
  19. package/dist/connectors/http/openapi.js +342 -0
  20. package/dist/connectors/http/openapi.js.map +1 -0
  21. package/dist/connectors/intercom/connector.json +249 -0
  22. package/dist/connectors/lusha/connector.json +59 -0
  23. package/dist/connectors/lusha/index.d.ts +8 -0
  24. package/dist/connectors/lusha/index.js +7 -0
  25. package/dist/connectors/lusha/index.js.map +1 -0
  26. package/dist/connectors/lusha/tools.d.ts +2 -0
  27. package/dist/connectors/lusha/tools.js +113 -0
  28. package/dist/connectors/lusha/tools.js.map +1 -0
  29. package/dist/connectors/lusha/vendor.d.ts +4 -0
  30. package/dist/connectors/lusha/vendor.js +72 -0
  31. package/dist/connectors/lusha/vendor.js.map +1 -0
  32. package/dist/connectors/odata/index.js +12 -5
  33. package/dist/connectors/odata/index.js.map +1 -1
  34. package/dist/connectors/pagerduty/connector.json +247 -0
  35. package/dist/connectors/qualys/connector.json +271 -0
  36. package/dist/connectors/safebase/connector.json +221 -0
  37. package/dist/connectors/soap/index.js +4 -3
  38. package/dist/connectors/soap/index.js.map +1 -1
  39. package/dist/connectors/sonarqube/connector.json +165 -0
  40. package/dist/connectors/sprout-social/connector.json +158 -0
  41. package/dist/connectors/synthesia/connector.json +113 -0
  42. package/dist/connectors/wordpress/connector.json +203 -0
  43. package/dist/connectors/zephyr/connector.json +192 -0
  44. package/dist/packages/connector-kit/src/connector.d.ts +45 -7
  45. package/dist/packages/connector-kit/src/connector.js +113 -10
  46. package/dist/packages/connector-kit/src/connector.js.map +1 -1
  47. package/dist/packages/connector-kit/src/oauth.d.ts +2 -0
  48. package/dist/packages/connector-kit/src/oauth.js +12 -4
  49. package/dist/packages/connector-kit/src/oauth.js.map +1 -1
  50. package/dist/packages/server/migrations/0008_internal_apps.sql +16 -0
  51. package/dist/packages/server/migrations/rollback/to-legacy.sql +2 -0
  52. package/dist/packages/server/src/api.d.ts +2490 -277
  53. package/dist/packages/server/src/api.js +82 -1
  54. package/dist/packages/server/src/api.js.map +1 -1
  55. package/dist/packages/server/src/app.js +26 -1
  56. package/dist/packages/server/src/app.js.map +1 -1
  57. package/dist/packages/server/src/builtin.d.ts +3 -0
  58. package/dist/packages/server/src/builtin.js +32 -0
  59. package/dist/packages/server/src/builtin.js.map +1 -1
  60. package/dist/packages/server/src/index.js +27 -18
  61. package/dist/packages/server/src/index.js.map +1 -1
  62. package/dist/packages/server/src/service.d.ts +1113 -0
  63. package/dist/packages/server/src/service.js +257 -19
  64. package/dist/packages/server/src/service.js.map +1 -1
  65. package/dist/packages/server/src/store.d.ts +41 -1
  66. package/dist/packages/server/src/store.js +79 -0
  67. package/dist/packages/server/src/store.js.map +1 -1
  68. package/package.json +1 -1
@@ -0,0 +1,238 @@
1
+ {
2
+ "id": "churnzero",
3
+ "name": "ChurnZero",
4
+ "description": "Let agents read your customer accounts in ChurnZero: contract value, renewal dates, licenses and products, health scores, contacts, product usage events, meetings and notes. For renewal decks, usage reviews and meeting prep.",
5
+ "logo": "/brand/registry/churnzero.svg",
6
+ "identity": "A ChurnZero user's API key. Agents read what that user's permission group may read in bulk, and change nothing.",
7
+ "accountKey": "instance",
8
+ "connectionKind": "guided",
9
+ "setup": [
10
+ {
11
+ "title": "Turn on the REST API",
12
+ "body": "The ChurnZero REST API is an add-on. If your ChurnZero admin pages have no API Keys page, ask your ChurnZero Customer Success Manager to turn it on.",
13
+ "link": {
14
+ "label": "ChurnZero: REST API reference",
15
+ "href": "https://app.churnzero.net/developers"
16
+ }
17
+ },
18
+ {
19
+ "title": "Give a user only the access agents need",
20
+ "body": "Use a ChurnZero user for agents, in a permission group with the Developer Tools permission and only these bulk read permissions: Accounts, Contacts, Events, Meetings and Notes. Leave the other bulk read permissions off. The group's permissions apply to everyone in it, so a group of its own is safest.",
21
+ "click": [
22
+ "In ChurnZero, go to Admin, then User Permission Groups, and create or open the agents' group.",
23
+ "Turn on Developer Tools.",
24
+ "Turn on Bulk Read - Accounts, Bulk Read - Contacts, Bulk Read - Events, Bulk Read - Meetings and Bulk Read - Notes. Leave every other bulk read permission off.",
25
+ "Add the agents' user to the group."
26
+ ]
27
+ },
28
+ {
29
+ "title": "Create an API key",
30
+ "body": "Signed in as that user, create an API key and copy it for the form below. Your ChurnZero address is the one you sign in at, such as acme.us1app.churnzero.net: enter the part before .us1app.",
31
+ "click": ["In ChurnZero, go to Admin, then API Keys, and create a new API key."],
32
+ "copy": [
33
+ "curl -s -u \"$CHURNZERO_USERNAME:$CHURNZERO_API_KEY\" \"https://acme.us1app.churnzero.net/public/v1/Account?\\$top=1&\\$select=Name\""
34
+ ],
35
+ "shell": "bash"
36
+ }
37
+ ],
38
+ "afterConnect": [],
39
+ "fields": [
40
+ {
41
+ "id": "instance",
42
+ "label": "ChurnZero instance",
43
+ "help": "The part before .us1app.churnzero.net in your ChurnZero address.",
44
+ "placeholder": "acme",
45
+ "secret": false
46
+ },
47
+ { "id": "username", "label": "Username", "secret": false },
48
+ { "id": "api_key", "label": "API key", "secret": true }
49
+ ],
50
+ "capabilities": [
51
+ {
52
+ "id": "accounts",
53
+ "label": "Read accounts",
54
+ "description": "Find customer accounts by name, id, CRM id or renewal date, and read one: contract value, renewal and end dates, licenses, products, health and relationship scores, NPS and owner.",
55
+ "required": true,
56
+ "note": "Reaches every account unless you keep an agent to chosen accounts. Read-only.",
57
+ "scopes": [],
58
+ "permissions": [],
59
+ "tools": ["churnzero_list_accounts", "churnzero_get_account"]
60
+ },
61
+ {
62
+ "id": "contacts",
63
+ "label": "Read contacts",
64
+ "description": "List an account's contacts: names, emails and products.",
65
+ "scopes": [],
66
+ "permissions": [],
67
+ "tools": ["churnzero_list_contacts"]
68
+ },
69
+ {
70
+ "id": "usage",
71
+ "label": "Read usage",
72
+ "description": "List product usage events by account, contact, event type and date, and the event types.",
73
+ "scopes": [],
74
+ "permissions": [],
75
+ "tools": ["churnzero_list_events", "churnzero_list_event_types"]
76
+ },
77
+ {
78
+ "id": "activity",
79
+ "label": "Read meetings and notes",
80
+ "description": "List an account's meetings and notes: subject, date, attendees, summary and sentiment.",
81
+ "note": "Notes and meeting summaries hold what your team wrote about the customer.",
82
+ "scopes": [],
83
+ "permissions": [],
84
+ "tools": ["churnzero_list_meetings", "churnzero_list_notes"]
85
+ }
86
+ ],
87
+ "limits": [
88
+ {
89
+ "id": "accounts",
90
+ "label": "Accounts",
91
+ "help": "Optional: only these ChurnZero accounts, by their ChurnZero id (the number in the account's address). Leave empty for every account.",
92
+ "kind": "list",
93
+ "required": false,
94
+ "pattern": "^\\d{1,18}$"
95
+ }
96
+ ],
97
+ "verify": {
98
+ "method": "GET",
99
+ "path": "/Account?$top=5&$select=Name",
100
+ "label": "ChurnZero accounts",
101
+ "show": "value[].Name"
102
+ },
103
+ "revoke": "In ChurnZero, go to Admin, then API Keys, and delete the key. Agents lose access to ChurnZero at once.",
104
+ "odata": {
105
+ "serviceRoot": "https://{instance}.us1app.churnzero.net/public/v1",
106
+ "version": "4",
107
+ "auth": { "type": "basic", "username": "username", "password": "api_key" },
108
+ "tools": [
109
+ {
110
+ "name": "churnzero_list_accounts",
111
+ "description": "List customer accounts, soonest renewal first. Filter by part of the name, ChurnZero id, CRM id, external id, renewal date or active. Answers {items, next}; pass next as cursor for more.",
112
+ "kind": "list",
113
+ "entitySet": "Account",
114
+ "filters": {
115
+ "name": { "type": "string", "property": "Name", "op": "contains", "description": "Part of the account name (at least 2 letters)" },
116
+ "id": { "type": "integer", "property": "Id", "description": "The ChurnZero account id", "limit": "accounts" },
117
+ "crm_id": { "type": "string", "property": "CrmId", "description": "The account's id in your CRM" },
118
+ "external_id": { "type": "string", "property": "ExternalId", "description": "The account's external id" },
119
+ "renewal_from": { "type": "datetime", "property": "NextRenewalDate", "op": "ge", "description": "Next renewal on or after this date" },
120
+ "renewal_to": { "type": "datetime", "property": "NextRenewalDate", "op": "le", "description": "Next renewal on or before this date" },
121
+ "active": { "type": "boolean", "property": "IsActive", "description": "Only active (true) or inactive (false) accounts" }
122
+ },
123
+ "select": [
124
+ "Id",
125
+ "Name",
126
+ "CrmId",
127
+ "ExternalId",
128
+ "IsActive",
129
+ "TotalContractAmount",
130
+ "NextRenewalDate",
131
+ "EndDate",
132
+ "LicenseCount",
133
+ "PrimaryChurnScoreValue",
134
+ "UserAccountId"
135
+ ],
136
+ "orderBy": "NextRenewalDate",
137
+ "top": 100
138
+ },
139
+ {
140
+ "name": "churnzero_get_account",
141
+ "description": "Read one account by its external id (the id your systems send ChurnZero): contract value, renewal and end dates, licenses, product subscriptions, scores, NPS, parent accounts and owner.",
142
+ "kind": "get",
143
+ "entitySet": "Account",
144
+ "key": {
145
+ "external_id": { "type": "string", "property": "AccountExternalId", "description": "The account's external id" }
146
+ },
147
+ "select": [
148
+ "Id",
149
+ "Name",
150
+ "CrmId",
151
+ "ExternalId",
152
+ "IsActive",
153
+ "StartDate",
154
+ "EndDate",
155
+ "NextRenewalDate",
156
+ "TenureInDays",
157
+ "TotalContractAmount",
158
+ "LicenseCount",
159
+ "ProductSubscriptions",
160
+ "PrimaryChurnScoreValue",
161
+ "RelationshipScore",
162
+ "NpsScore",
163
+ "CsatScore",
164
+ "UsageFrequency",
165
+ "Tags",
166
+ "ParentAccountId",
167
+ "UltimateParentAccountId",
168
+ "UserAccountId",
169
+ "BillingAddressCity",
170
+ "BillingAddressState",
171
+ "BillingAddressCountry"
172
+ ],
173
+ "answerLimits": [{ "field": "Id", "limit": "accounts" }]
174
+ },
175
+ {
176
+ "name": "churnzero_list_contacts",
177
+ "description": "List an account's contacts, or find a contact by email. Answers {items, next}; pass next as cursor for more.",
178
+ "kind": "list",
179
+ "entitySet": "Contact",
180
+ "filters": {
181
+ "account_id": { "type": "integer", "property": "AccountId", "description": "The ChurnZero account id", "limit": "accounts" },
182
+ "email": { "type": "string", "property": "Email", "description": "The contact's email address" }
183
+ },
184
+ "select": ["Id", "AccountId", "FullName", "Email", "ExternalId", "Products", "Tags"],
185
+ "top": 100
186
+ },
187
+ {
188
+ "name": "churnzero_list_events",
189
+ "description": "List product usage events, newest first, by account, contact, event type and date. Each has a date, type, quantity and description. Answers {items, next}; pass next as cursor for more.",
190
+ "kind": "list",
191
+ "entitySet": "Event",
192
+ "filters": {
193
+ "account_id": { "type": "integer", "property": "AccountId", "description": "The ChurnZero account id", "limit": "accounts" },
194
+ "contact_id": { "type": "integer", "property": "ContactId", "description": "The ChurnZero contact id" },
195
+ "event_type_id": { "type": "integer", "property": "EventTypeId", "description": "The event type id, from churnzero_list_event_types" },
196
+ "from": { "type": "datetime", "property": "EventDate", "op": "ge", "description": "Events on or after this date" },
197
+ "to": { "type": "datetime", "property": "EventDate", "op": "lt", "description": "Events before this date" }
198
+ },
199
+ "select": ["Id", "AccountId", "ContactId", "EventTypeId", "EventDate", "Quantity", "Description"],
200
+ "orderBy": "EventDate desc",
201
+ "top": 200
202
+ },
203
+ {
204
+ "name": "churnzero_list_event_types",
205
+ "description": "List the usage event types, to name the event type ids of events.",
206
+ "kind": "list",
207
+ "entitySet": "EventType",
208
+ "top": 200
209
+ },
210
+ {
211
+ "name": "churnzero_list_meetings",
212
+ "description": "List an account's meetings, newest first: subject, start and end, organizer, attendees, summary and sentiment. Answers {items, next}; pass next as cursor for more.",
213
+ "kind": "list",
214
+ "entitySet": "Meeting",
215
+ "filters": {
216
+ "account_id": { "type": "integer", "property": "AccountId", "description": "The ChurnZero account id", "limit": "accounts" },
217
+ "from": { "type": "datetime", "property": "StartDate", "op": "ge", "description": "Meetings starting on or after this date" }
218
+ },
219
+ "select": ["Id", "AccountId", "Subject", "StartDate", "EndDate", "Organizer", "Attendees", "Summary", "Sentiment", "Topics"],
220
+ "orderBy": "StartDate desc",
221
+ "top": 50
222
+ },
223
+ {
224
+ "name": "churnzero_list_notes",
225
+ "description": "List an account's notes, newest first: title, date, text, contacts, topics and sentiment. Answers {items, next}; pass next as cursor for more.",
226
+ "kind": "list",
227
+ "entitySet": "Note",
228
+ "filters": {
229
+ "account_id": { "type": "integer", "property": "AccountId", "description": "The ChurnZero account id", "limit": "accounts" },
230
+ "from": { "type": "datetime", "property": "NoteDate", "op": "ge", "description": "Notes on or after this date" }
231
+ },
232
+ "select": ["Id", "AccountId", "Name", "NoteDate", "Content", "Contacts", "Topics", "Sentiment"],
233
+ "orderBy": "NoteDate desc",
234
+ "top": 50
235
+ }
236
+ ]
237
+ }
238
+ }
@@ -0,0 +1,168 @@
1
+ {
2
+ "id": "confluence",
3
+ "name": "Confluence",
4
+ "description": "Let agents find and read Confluence pages in the spaces you choose, such as release checklists, runbooks and sign-off pages. For release readiness checks and go/no-go summaries.",
5
+ "logo": "/brand/registry/confluence.svg",
6
+ "identity": "An Atlassian service account named \"{brand.microsoft.appName}\" with OAuth 2.0 credentials. It uses no Confluence seat and reads only the spaces it is given.",
7
+ "accountKey": "cloud",
8
+ "connectionKind": "guided",
9
+ "setup": [
10
+ {
11
+ "title": "Create a service account with Confluence access",
12
+ "body": "In Atlassian Administration, create a service account named \"{brand.microsoft.appName}\". When it asks you to select an app role, set Confluence to User and leave every other app on None. If you already made one for Jira, you can use it and add the Confluence role.",
13
+ "link": {
14
+ "label": "Atlassian: create OAuth 2.0 credentials for service accounts",
15
+ "href": "https://support.atlassian.com/user-management/docs/create-oauth-2-0-credential-for-service-accounts/"
16
+ },
17
+ "click": [
18
+ "Atlassian Administration > Directory > Service accounts > Create service account",
19
+ "Name: {brand.microsoft.appName}",
20
+ "Select app role: Confluence > User (every other app: None) > Create"
21
+ ]
22
+ },
23
+ {
24
+ "title": "Let it view the spaces agents should read",
25
+ "body": "Give the service account the View permission in each space agents should read, and nothing more. You can narrow each agent to some of those spaces here later.",
26
+ "click": [
27
+ "In each space: Space settings > Users > Add people > {brand.microsoft.appName} > View only"
28
+ ]
29
+ },
30
+ {
31
+ "title": "Create OAuth 2.0 credentials",
32
+ "body": "On the service account, select Create credentials, then OAuth 2.0, and select exactly these scopes. Copy the client ID and secret: Atlassian shows the secret only once.",
33
+ "click": [
34
+ "Atlassian Administration > Directory > Service accounts > {brand.microsoft.appName} > Create credentials > OAuth 2.0 > Next",
35
+ "Scopes: read:page:confluence and read:space:confluence > Next > Create"
36
+ ],
37
+ "copy": ["{scopes}"]
38
+ },
39
+ {
40
+ "title": "Find your site's cloud ID",
41
+ "body": "Atlassian calls your site by an ID. Open the address below with your site's name in place of your-company: the cloudId it shows goes in the form.",
42
+ "click": ["Open https://your-company.atlassian.net/_edge/tenant_info in your browser and copy cloudId."],
43
+ "copy": ["curl -s https://your-company.atlassian.net/_edge/tenant_info"],
44
+ "shell": "bash"
45
+ }
46
+ ],
47
+ "afterConnect": [],
48
+ "fields": [
49
+ {
50
+ "id": "cloud",
51
+ "label": "Cloud ID",
52
+ "help": "Shown at https://<your site>.atlassian.net/_edge/tenant_info.",
53
+ "placeholder": "1a2b3c4d-1234-5678-9abc-def012345678",
54
+ "secret": false
55
+ },
56
+ { "id": "client_id", "label": "Client ID", "secret": false },
57
+ { "id": "client_secret", "label": "Client secret", "secret": true }
58
+ ],
59
+ "capabilities": [
60
+ {
61
+ "id": "read",
62
+ "label": "Read pages",
63
+ "description": "List spaces, list a space's pages by title, and read a page with its content.",
64
+ "required": true,
65
+ "note": "Read-only. Reaches the spaces the service account may view unless you keep a key to chosen spaces.",
66
+ "scopes": ["read:page:confluence", "read:space:confluence"],
67
+ "permissions": [],
68
+ "tools": ["confluence_list_spaces", "confluence_list_pages", "confluence_get_page"]
69
+ }
70
+ ],
71
+ "limits": [
72
+ {
73
+ "id": "spaces",
74
+ "label": "Spaces",
75
+ "help": "Optional: only pages in these spaces, by space id (listed under Spaces after connecting). Leave empty for every space the service account may view.",
76
+ "kind": "list",
77
+ "required": false,
78
+ "pattern": "^\\d{1,20}$"
79
+ }
80
+ ],
81
+ "verify": {
82
+ "method": "GET",
83
+ "path": "/api/v2/spaces?limit=25",
84
+ "label": "Confluence spaces",
85
+ "show": "results[].name",
86
+ "ifEmpty": "The service account cannot view any space yet: give it View in the spaces agents should read."
87
+ },
88
+ "discover": {
89
+ "method": "GET",
90
+ "path": "/api/v2/spaces?limit=250",
91
+ "label": "Spaces",
92
+ "show": "results[].id",
93
+ "name": "results[].name"
94
+ },
95
+ "revoke": "In Atlassian Administration, go to Directory > Service accounts, select {brand.microsoft.appName} and delete its OAuth 2.0 credentials, or remove its Confluence role. Agents lose access to Confluence within the hour, when their last token expires.",
96
+ "http": {
97
+ "baseUrl": "https://api.atlassian.com/ex/confluence/{cloud}/wiki",
98
+ "auth": {
99
+ "type": "oauth2",
100
+ "tokenUrl": "https://auth.atlassian.com/oauth/token",
101
+ "clientId": "client_id",
102
+ "clientSecret": "client_secret"
103
+ },
104
+ "tools": [
105
+ {
106
+ "name": "confluence_list_spaces",
107
+ "description": "List spaces with their id, key and name, or find some by key. Pass next from the answer as cursor for the next page.",
108
+ "method": "GET",
109
+ "path": "/api/v2/spaces",
110
+ "params": {
111
+ "keys": { "type": "array", "items": "string", "description": "Only these space keys", "in": "query", "join": ",", "required": false },
112
+ "limit": { "type": "integer", "description": "Spaces per page, at most 250", "in": "query", "default": 50 },
113
+ "cursor": { "type": "string", "description": "The next value of the previous answer", "in": "query", "required": false }
114
+ },
115
+ "paging": { "param": "cursor", "link": true },
116
+ "result": { "items": "results", "fields": ["id", "key", "name", "type", "status"] }
117
+ },
118
+ {
119
+ "name": "confluence_list_pages",
120
+ "description": "List pages in some spaces, optionally only those with a given title, newest first. Pass next from the answer as cursor for the next page.",
121
+ "method": "GET",
122
+ "path": "/api/v2/pages",
123
+ "params": {
124
+ "space_ids": {
125
+ "type": "array",
126
+ "items": "string",
127
+ "description": "The space ids",
128
+ "in": "query",
129
+ "name": "space-id",
130
+ "join": ",",
131
+ "limit": "spaces"
132
+ },
133
+ "title": { "type": "string", "description": "Only pages with exactly this title", "in": "query", "required": false },
134
+ "sort": {
135
+ "type": "string",
136
+ "enum": ["-modified-date", "modified-date", "title", "-title", "created-date", "-created-date"],
137
+ "description": "The order",
138
+ "in": "query",
139
+ "default": "-modified-date"
140
+ },
141
+ "limit": { "type": "integer", "description": "Pages per page, at most 250", "in": "query", "default": 50 },
142
+ "cursor": { "type": "string", "description": "The next value of the previous answer", "in": "query", "required": false }
143
+ },
144
+ "paging": { "param": "cursor", "link": true },
145
+ "result": { "items": "results", "fields": ["id", "title", "spaceId", "parentId", "status", "version.number", "version.createdAt", "_links.webui"] }
146
+ },
147
+ {
148
+ "name": "confluence_get_page",
149
+ "description": "Read one page with its content, in Confluence's storage format (XHTML) by default.",
150
+ "method": "GET",
151
+ "path": "/api/v2/pages/{id}",
152
+ "params": {
153
+ "id": { "type": "string", "description": "The page id", "in": "path" },
154
+ "body_format": {
155
+ "type": "string",
156
+ "enum": ["storage", "atlas_doc_format", "view"],
157
+ "description": "The content's format",
158
+ "in": "query",
159
+ "name": "body-format",
160
+ "default": "storage"
161
+ }
162
+ },
163
+ "answerLimits": [{ "field": "spaceId", "limit": "spaces" }],
164
+ "result": { "fields": ["id", "title", "spaceId", "parentId", "status", "version.number", "version.createdAt", "body", "_links.webui"] }
165
+ }
166
+ ]
167
+ }
168
+ }