@pixlcore/xycli 1.0.0

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 (63) hide show
  1. package/README.md +543 -0
  2. package/docs/help.md +2587 -0
  3. package/docs/screenshots.md +219 -0
  4. package/docs/sync.md +920 -0
  5. package/docs/tutorial.md +204 -0
  6. package/index.js +444 -0
  7. package/lib/alerts.js +735 -0
  8. package/lib/apikey.js +425 -0
  9. package/lib/buckets.js +607 -0
  10. package/lib/categories.js +323 -0
  11. package/lib/channels.js +290 -0
  12. package/lib/config.js +86 -0
  13. package/lib/dashboard.js +237 -0
  14. package/lib/doc.js +131 -0
  15. package/lib/events.js +1314 -0
  16. package/lib/groups.js +1038 -0
  17. package/lib/jobs.js +1254 -0
  18. package/lib/log.js +125 -0
  19. package/lib/marketplace.js +386 -0
  20. package/lib/monitors.js +412 -0
  21. package/lib/plugins.js +491 -0
  22. package/lib/secrets.js +441 -0
  23. package/lib/servers.js +1502 -0
  24. package/lib/snapshots.js +498 -0
  25. package/lib/sync.js +963 -0
  26. package/lib/system.js +612 -0
  27. package/lib/tags.js +250 -0
  28. package/lib/tickets.js +681 -0
  29. package/lib/transfer.js +447 -0
  30. package/lib/utils.js +2745 -0
  31. package/lib/webhook.js +414 -0
  32. package/logo.webp +0 -0
  33. package/package.json +38 -0
  34. package/test/README.md +97 -0
  35. package/test/api-validation.test.js +170 -0
  36. package/test/categories.test.js +246 -0
  37. package/test/channels.test.js +209 -0
  38. package/test/config.test.js +96 -0
  39. package/test/doc.test.js +84 -0
  40. package/test/groups.test.js +211 -0
  41. package/test/help.test.js +26 -0
  42. package/test/helpers/common.js +127 -0
  43. package/test/helpers/pagination-preload.cjs +18 -0
  44. package/test/log.test.js +103 -0
  45. package/test/markdown.test.js +61 -0
  46. package/test/marketplace.test.js +229 -0
  47. package/test/monitors.test.js +227 -0
  48. package/test/pagination.test.js +138 -0
  49. package/test/plugins.test.js +351 -0
  50. package/test/secrets.test.js +271 -0
  51. package/test/servers.test.js +303 -0
  52. package/test/snapshots.test.js +167 -0
  53. package/test/sync-unit.test.js +446 -0
  54. package/test/sync.test.js +542 -0
  55. package/test/system.test.js +94 -0
  56. package/test/tags.test.js +230 -0
  57. package/test/tickets.test.js +261 -0
  58. package/test/toast.test.js +73 -0
  59. package/test/transfer-apikey.test.js +96 -0
  60. package/test/transfer-workflow.test.js +122 -0
  61. package/test/transfer.test.js +314 -0
  62. package/test/webhook.test.js +332 -0
  63. package/test.js +49 -0
package/docs/help.md ADDED
@@ -0,0 +1,2587 @@
1
+ # help
2
+
3
+ Welcome to the xyOps command-line interface. Use `xy` to check your system at a glance, then explore events and jobs with friendly commands designed for both people and scripts.
4
+
5
+ ```sh
6
+ xy
7
+ xy system
8
+ xy events
9
+ xy jobs
10
+ xy keys
11
+ xy alerts
12
+ xy buckets
13
+ xy categories
14
+ xy channels
15
+ xy doc
16
+ xy log xyOps --rows 100
17
+ xy monitors
18
+ xy plugins
19
+ xy servers
20
+ xy snapshots
21
+ xy groups
22
+ xy secrets
23
+ xy tags
24
+ xy tickets
25
+ xy hooks
26
+ xy marketplace
27
+ xy event EVENT_ID --export event.json
28
+ xy import event.json
29
+ xy sync ./ --up events,plugins --dry
30
+ ```
31
+
32
+ Use plural commands such as `events`, `jobs`, and `tickets` to browse collections, and singular commands such as `event`, `job`, and `ticket` to work with one item. Names and titles are matched fuzzily wherever `ID_OR_TITLE` is shown. You can use the `help` system to get details for each command:
33
+
34
+ ```sh
35
+ xy help events
36
+ xy help system
37
+ xy help system export
38
+ xy help system diagnostic
39
+ xy help system restart
40
+ xy help system shutdown
41
+ xy help doc
42
+ xy help event
43
+ xy help event create
44
+ xy help jobs
45
+ xy help job get
46
+ xy help keys
47
+ xy help key create
48
+ xy help alerts
49
+ xy help alerts search
50
+ xy help alert
51
+ xy help alert create
52
+ xy help buckets
53
+ xy help bucket
54
+ xy help bucket write
55
+ xy help categories
56
+ xy help category
57
+ xy help category create
58
+ xy help channels
59
+ xy help channel
60
+ xy help channel create
61
+ xy help log
62
+ xy help monitors
63
+ xy help monitor
64
+ xy help monitor create
65
+ xy help monitor test
66
+ xy help plugins
67
+ xy help plugin
68
+ xy help plugin create
69
+ xy help servers
70
+ xy help server
71
+ xy help server add
72
+ xy help server search
73
+ xy help snapshots
74
+ xy help snapshot
75
+ xy help groups
76
+ xy help group
77
+ xy help group history
78
+ xy help group create
79
+ xy help secrets
80
+ xy help secret
81
+ xy help secret create
82
+ xy help secret decrypt
83
+ xy help tags
84
+ xy help tag
85
+ xy help tag create
86
+ xy help tickets
87
+ xy help ticket
88
+ xy help ticket create
89
+ xy help ticket comment
90
+ xy help hooks
91
+ xy help hook
92
+ xy help hook create
93
+ xy help hook test
94
+ xy help marketplace
95
+ xy help marketplace search
96
+ xy help marketplace get
97
+ xy help marketplace install
98
+ xy help export
99
+ xy help import
100
+ xy help sync
101
+ xy help sync setup
102
+ ```
103
+
104
+ # Command Reference
105
+
106
+ ## export
107
+
108
+ Export an object to an xyOps Portable Data Format (XYPDF) file by adding `--export FILE` to its detail command. The file can be imported by the CLI or the xyOps web interface. Exact IDs take precedence over fuzzy titles.
109
+
110
+ ```sh
111
+ xy event EVENT_ID_OR_TITLE --export event.json
112
+ xy event get --id EVENT_ID --export event.json
113
+ xy category CATEGORY_ID --export category.json
114
+ xy bucket BUCKET_ID --export bucket.json
115
+ xy monitor MONITOR_ID --export monitor.json.gz
116
+ xy event EVENT_ID --export event.json --overwrite
117
+ xy event EVENT_ID --export event.json --dry
118
+ ```
119
+
120
+ Export supports all XYPDF object types:
121
+
122
+ | Object | Command |
123
+ |--------|---------|
124
+ | Alert definition | `xy alert ALERT_ID --export alert.json` |
125
+ | API key | `xy key KEY_ID --export key.json` |
126
+ | Bucket metadata | `xy bucket BUCKET_ID --export bucket.json` |
127
+ | Category | `xy category CATEGORY_ID --export category.json` |
128
+ | Notification channel | `xy channel CHANNEL_ID --export channel.json` |
129
+ | Event or workflow | `xy event EVENT_ID --export event.json` |
130
+ | Server group | `xy group GROUP_ID --export group.json` |
131
+ | Monitor | `xy monitor MONITOR_ID --export monitor.json` |
132
+ | Plugin | `xy plugin PLUGIN_ID --export plugin.json` |
133
+ | Role | `xy role ROLE_ID --export role.json` |
134
+ | Tag | `xy tag TAG_ID --export tag.json` |
135
+ | Web hook | `xy hook WEB_HOOK_ID --export hook.json` |
136
+
137
+ Use `--export` with a single object's detail command rather than a list, search, or mutation command. `--id` and `--title` selectors are also supported.
138
+
139
+ Files are pretty-printed JSON. A `.gz` suffix enables gzip compression; use `.json.gz` for compatibility with the web interface. The destination directory must exist. Existing files are preserved unless you pass `--overwrite`. `--dry` shows what would be written without creating a file. `--format json` prints the output path, item count, and any dependency warnings.
140
+
141
+ Exports contain reusable definitions rather than history and audit details. Buckets do not include stored JSON data or uploaded files, API Key exports never reveal the plaintext secret, and Alert exports contain definitions rather than active alert invocations.
142
+
143
+ **Event and workflow dependencies**
144
+
145
+ Events and workflows export by themselves unless you select dependency types with `--deps`. Use a comma-separated list, repeated options, or `all`:
146
+
147
+ ```sh
148
+ xy event EVENT_ID --export event.json --deps plugins,categories
149
+ xy event WORKFLOW_ID --export workflow.json.gz --deps events,plugins,buckets
150
+ xy event WORKFLOW_ID --export workflow.json --deps events --deps plugins
151
+ xy event WORKFLOW_ID --export workflow.json --deps all
152
+ ```
153
+
154
+ | Dependency | Included objects |
155
+ |------------|------------------|
156
+ | `events` | Events referenced by workflow event nodes, recursively. |
157
+ | `plugins` | Event and workflow job plugins, plus plugins referenced by triggers and actions. |
158
+ | `categories` | Event categories, excluding the built-in General category. |
159
+ | `groups` | Server groups in event targets. Individual servers are not portable. |
160
+ | `buckets` | Bucket metadata referenced by store and fetch actions. |
161
+ | `tags` | Event tags and tags referenced by actions. |
162
+ | `web_hooks` | Web hooks referenced by actions, excluding the built-in example hook. |
163
+
164
+ These choices match the web interface. Stock event and job Plugins are omitted. Only the selected dependency types are included, shared dependencies appear once, and linked workflows are followed safely. Missing dependencies are reported as warnings and omitted from the file.
165
+
166
+ ## import
167
+
168
+ Read a plain JSON or gzip-compressed XYPDF file and preview its contents and planned changes. **No changes are made until you add `--confirm`.** Review the complete data, including Plugin scripts and event triggers, before importing files from another source.
169
+
170
+ ```sh
171
+ xy import event.json
172
+ xy import workflow.json.gz
173
+ xy import workflow.json.gz --format json
174
+ xy import workflow.json.gz --dry
175
+ ```
176
+
177
+ The file determines the object types and may contain any combination of the 12 types supported by `xy help export`. Before making changes, the preview checks the file format, required xyOps version, object types, titles, IDs, and duplicate IDs.
178
+
179
+ An exact matching ID updates the existing object; otherwise a new object is created. Missing or empty IDs are generated by xyOps. Titles are not used to select updates. Omitted fields remain unchanged, while included arrays replace their existing values.
180
+
181
+ Dependencies are imported before the objects that use them. Circular dependencies among new objects are rejected during preview, while references to existing definitions are allowed. Importing a Bucket never writes or clears its stored data or files. Restoring an API Key requires a compatible xyOps version and never reveals its plaintext secret.
182
+
183
+ The preview identifies updates and events with active triggers. Confirmed imports preserve the settings in the file, so enabled schedules or other triggers can run automatically afterward. `--dry` always previews, even with `--confirm`.
184
+
185
+ Your configured permissions still apply during import. If an item fails, import stops and reports each item as `created`, `updated`, `failed`, or `pending`. Earlier successful changes remain in place; there is no automatic rollback. JSON output includes these results, and failed imports exit with a nonzero status.
186
+
187
+ ## sync
188
+
189
+ For setup, configuration, file layouts, and automation examples, see the dedicated [Filesystem Sync Guide](sync.md).
190
+
191
+ Sync existing xyOps definitions with a directory of XYPDF files. Each run scans the directory and its subdirectories, shows any differences, and applies changes in the directions you select. **Changes are applied immediately unless you add `--dry`; there is no `--confirm` step.**
192
+
193
+ ```sh
194
+ xy sync ./ --up events,plugins --dry
195
+ xy sync ./ --up events,plugins
196
+ xy sync ./ --down events,plugins --dry
197
+ xy sync ./ --down events,plugins
198
+ xy sync ./ --up categories,plugins --down events --dry
199
+ xy sync ./ --up events --down events --dry
200
+ xy sync ./ --up all --dry
201
+ xy sync --up events,plugins --verbose
202
+ ```
203
+
204
+ Pass one or more base directories, or omit them to scan the current directory. Folder layout and filenames are up to you. Use `xy help sync setup` to export a starter tree.
205
+
206
+ **Directions and resource types**
207
+
208
+ - `--up TYPES` updates xyOps from local files.
209
+ - `--down TYPES` updates local files from xyOps.
210
+ - `--dry` previews changes without applying them.
211
+ - `--verbose` shows full diffs and API requests and responses.
212
+
213
+ You must enable at least one direction. `TYPES` is a comma-separated list of `alerts`, `api_keys`, `categories`, `channels`, `events`, `groups`, `monitors`, `plugins`, `tags`, or `web_hooks`. Use `all` to select every supported type. Workflows are included under `events`. Buckets, Secrets, Users, and Roles are not supported.
214
+
215
+ Enable both directions for the same type to use experimental two-way sync. The newest modification time wins, including external property files. Git checkouts can reset filesystem timestamps, so prefer one-way sync when reliable conflict handling matters. Dry runs never update xyOps, write files, run completion commands, or send notifications.
216
+
217
+ Sources must be plain `.json` XYPDF files containing exactly one item each. Objects are matched by type and exact ID, not by title. Sync does not create new xyOps objects or local files for newly added objects. Use setup or individual exports to add local sources, and keep their original IDs.
218
+
219
+ Repeated sources with the same type and ID generate warnings, even if their contents are identical. Later duplicates are skipped during scanning, and the warnings stop the run before any definition, file, tracking, or deletion changes. Keep one source per object and avoid overlapping base directories. Warning notifications can still run; warnings produce exit status `1`.
220
+
221
+ External string properties are loaded automatically from adjacent files named `BASENAME-PROPERTY.EXT`, such as `My-Plugin-script.js` beside `My-Plugin.json`, or `My-Event-params.script.sh` beside `My-Event.json`. The extension is your choice. Keep only one external file per property, and rename its basename along with the JSON file.
222
+
223
+ **Delete mode**
224
+
225
+ Add `--delete TYPES` to delete xyOps objects that have no matching source in the scanned directories. Deletion requires up-only sync and a complete local inventory. The CLI rejects deletion if upsync is disabled or any downsync direction is enabled, including saved defaults and dry runs. Use `--down false` to disable inherited downsync. See [Delete mode](sync.md#delete-mode) before using it.
226
+
227
+ ```sh
228
+ xy sync ./ --up events,plugins --delete events --dry
229
+ xy sync ./ --up events,plugins --delete events
230
+ ```
231
+
232
+ **Objects with a `stock` or `marketplace` property are always ignored by deletion**, including during dry runs. They do not need local source files, and setup inclusion flags cannot override this protection.
233
+
234
+ **The scanned directories must contain a complete inventory of the other objects you intend to keep for every type selected for deletion.** Delete mode is not limited to previously synced objects. A missing file, incomplete export, or unavailable mount can cause unintended deletions of your own definitions. Verify that all source directories are available and inspect a dry run before removing `--dry`. Source warnings or scan errors stop the run before any updates or deletions begin.
235
+
236
+ **Completion commands and notifications**
237
+
238
+ ```sh
239
+ xy sync ./ --down events,plugins \
240
+ --down_cmd "git add . && git commit -m 'Sync from xyOps'"
241
+ xy sync ./ --up events,plugins \
242
+ --error_email ops@example.com --error_event EVENT_ID
243
+ ```
244
+
245
+ - `--up_cmd COMMAND` runs after successful updates to xyOps.
246
+ - `--down_cmd COMMAND` runs after successful updates to local files.
247
+ - `--cmd_timeout SECONDS` limits each command, defaulting to 30 seconds.
248
+ - `--error_email ADDRESS` sends warnings and errors by email through xyOps.
249
+ - `--error_event EVENT_ID` runs an Event on warnings or errors.
250
+
251
+ Completion commands run in a local shell in the first base directory. Deletions alone do not trigger them. Event notifications receive `input.data.errors` and `input.data.warnings`.
252
+
253
+ The configured API Key needs the appropriate resource permissions and `update_state` for sync tracking updates. Notification actions also need their usual permissions. Earlier successful changes are not rolled back if a later operation fails.
254
+
255
+ Sync warnings and errors exit with status `1`, including warnings or errors during dry runs and completion-command errors. Completion commands and notifications can finish before the process exits. Runs with no warnings or errors exit with status `0`. Scan warnings stop the run before updates and can trigger notifications.
256
+
257
+ Every sync and setup command uses a built-in host-local PID lock keyed by `base_url`. An overlapping invocation exits nonzero before doing work, while a dead process's stale lock is replaced automatically. Use `sync.lock_file` or `--lock_file PATH` to set an explicit path, particularly for a service account. The parent directory must already exist and be writable. Use one common path for local accounts targeting the same instance; PID locks do not coordinate separate hosts.
258
+
259
+ **Saved defaults**
260
+
261
+ Put sync defaults under a `sync` object in `/etc/xyops/cli.json` or `~/.config/xyops/cli.json`:
262
+
263
+ ```json
264
+ {
265
+ "sync": {
266
+ "up": ["events", "plugins"],
267
+ "down": false,
268
+ "delete": false,
269
+ "lock_file": "/run/xyops/xycli-sync.pid",
270
+ "error_email": "ops@example.com"
271
+ }
272
+ }
273
+ ```
274
+
275
+ Command-line options override saved sync settings. Use `--up false`, `--down false`, or `--delete false` to disable a saved mode. Positional directories take precedence over `base_dirs`. Without positional directories, sync uses the configured `base_dirs` JSON array, or the current directory if it is not configured. Use `--base_dirs '["./"]'` to override the saved array for one run; positional directories still take precedence. These defaults apply to sync runs, not setup.
276
+
277
+ ## sync setup
278
+
279
+ Export existing xyOps definitions into a starter sync tree in the current directory. Use a fresh directory so the generated files are easy to review before your first sync.
280
+
281
+ ```sh
282
+ xy sync setup events plugins categories --dry
283
+ xy sync setup events plugins categories --file_props script,params.script
284
+ xy sync setup all
285
+ xy sync setup all --stock --marketplace
286
+ xy sync setup events plugins --force
287
+ xy sync --setup events,plugins --file_props script,params.script
288
+ ```
289
+
290
+ Choose one or more resource types separated by spaces, or use `all`. Supported types are the same as for `xy sync`. The `--setup TYPES` form also accepts a comma-separated list.
291
+
292
+ Setup creates one folder per resource type and one XYPDF JSON file per object, using its title as a filename slug. Selecting `events` exports both Events and workflows, with workflows placed in a separate `workflows` folder. Both are synced with `--up events` or `--down events`.
293
+
294
+ - `--file_props PATHS` extracts string properties into adjacent files.
295
+ - `--stock` includes stock objects, which are omitted by default.
296
+ - `--marketplace` includes Marketplace objects, which are omitted by default.
297
+ - `--force` allows generated files to overwrite existing destinations.
298
+ - `--dry` previews the layout without creating directories or writing files.
299
+
300
+ For `--file_props`, use comma-separated property names or dot paths, such as `script,params.script`. Only nonempty string values are extracted. The JSON value becomes `(External)`, and sync loads the external file automatically.
301
+
302
+ Without `--force`, setup stops when an output file already exists. Files written before an error are not rolled back. Ensure object titles produce distinct filename slugs, especially when using `--force`, and back up any local edits before rerunning setup. For a delete-mode inventory, verify that every object eligible for deletion that you intend to keep has a source file. Stock and Marketplace objects are protected from deletion and may be omitted.
303
+
304
+ ## api
305
+
306
+ Call any API method exposed by the xyOps SDK and print its JSON request and response. Named options become request properties, and dotted names provide a convenient way to build nested objects.
307
+
308
+ ```sh
309
+ xy api getEvents
310
+ xy api getJob --id JOB_ID
311
+ xy api runEvent --id EVENT_ID --params.example VALUE
312
+ xy api updateEvent --json @request.json
313
+ cat request.json | xy api runEvent --json @-
314
+ xy api runEvent --id EVENT_ID --dry
315
+ ```
316
+
317
+ Use the SDK's camel-case method names, such as `getEvents`, `getJob`, and `runEvent`. Add `--dry` to print a request without calling the API.
318
+
319
+ ## repl
320
+
321
+ Open an interactive Node.js prompt with the current xyOps client state already loaded. This is primarily a development and debugging tool for exploring objects and trying utility methods.
322
+
323
+ ```sh
324
+ xy repl
325
+ ```
326
+
327
+ The REPL exposes `app`, `xy`, `config`, `cli`, and `Tools` in its context.
328
+
329
+ Type `.exit` or hit `Ctrl-C` to exit.
330
+
331
+ ## config
332
+
333
+ View the effective CLI configuration or save one or more user settings. API keys are masked when displayed, and updated values are written to `~/.config/xyops/cli.json`.
334
+
335
+ ```sh
336
+ xy config
337
+ xy config --suggest false
338
+ xy config --color false
339
+ xy config --items_per_page 25
340
+ xy config --base_url http://localhost:5522 --api_key YOUR_API_KEY
341
+ ```
342
+
343
+ Updates load the user file separately and apply only the settings specified on the command line, preserving other user settings. System settings and environment overrides are not copied into the file. If the user file does not exist, it is created with only the supplied settings.
344
+
345
+ Configuration loads `/etc/xyops/cli.json` first, then `~/.config/xyops/cli.json`, then `XYOPS_`-prefixed environment variables. Later sources override matching top-level settings. Environment overrides still take precedence over saved user settings. Common keys include `api_key`, `base_url`, `temp_dir`, `color`, `suggest`, `items_per_page`, `cache_ttl`, `raw`, and `invisible`.
346
+
347
+ ## doc
348
+
349
+ Fetch and display xyOps documentation in the terminal. Run the command without a document name to browse the documentation index. Specify a document to read it in full, or add a chapter slug to focus on one section and all of its sub-sections.
350
+
351
+ ```sh
352
+ xy doc
353
+ xy doc plugins
354
+ xy doc plugins/output-data
355
+ xy doc plugins output-data
356
+ ```
357
+
358
+ Chapter slugs are lowercase heading names with punctuation and spaces replaced by hyphens. The slash and space forms are equivalent. Internal documentation links are displayed as copyable `xy doc` commands.
359
+
360
+ ## dashboard
361
+
362
+ Show the main xyOps dashboard, including server health, active alerts and jobs, queued work, and active rate limits. Add the upcoming view when you also want to see jobs expected to run soon.
363
+
364
+ ```sh
365
+ xy
366
+ xy dashboard
367
+ xy dashboard --upcoming
368
+ xy dashboard upcoming
369
+ xy upcoming
370
+ ```
371
+
372
+ ## system
373
+
374
+ Show the administrator System dashboard. It includes process and database statistics, internal jobs, conductor status, and all connected users.
375
+
376
+ System commands require a full administrator API Key.
377
+
378
+ ```sh
379
+ xy system
380
+ xy system dashboard
381
+ xy system export xyops-export.json.gz
382
+ xy system import xyops-export.json.gz
383
+ xy system delete events,categories,buckets
384
+ xy system maintenance
385
+ xy system optimize
386
+ xy system reset rates
387
+ xy system reset sync
388
+ xy system restart conductor xyops02.example.com
389
+ xy system shutdown conductor xyops02.example.com
390
+ xy system upgrade workers server1,server2
391
+ xy system email test@example.com
392
+ xy system diagnostic
393
+ xy system broadcast "System maintenance begins soon"
394
+ ```
395
+
396
+ Several System operations can interrupt jobs or permanently change data. Commands that import, delete, restart, shut down, upgrade, or reset sync state require `--confirm` before they proceed.
397
+
398
+ ## system export
399
+
400
+ Download a gzip-compressed xyOps data archive. By default, all configuration lists are included, while database history and optional file data are omitted.
401
+
402
+ ```sh
403
+ xy system export xyops-export.json.gz
404
+ xy system export config.json.gz --lists events,categories,plugins
405
+ xy system export history.json.gz --lists none --indexes jobs,activity
406
+ xy system export complete.json.gz --lists all --indexes all --extras all
407
+ xy system export xyops-export.json.gz --overwrite
408
+ xy system export xyops-export.json.gz --dry
409
+ ```
410
+
411
+ Use `--lists`, `--indexes` (or `--tables`), and `--extras` with comma-separated names. Each option also accepts `all` or `none`.
412
+
413
+ Configuration lists include `alerts`, `api_keys`, `buckets`, `categories`, `channels`, `events`, `groups`, `monitors`, `plugins`, `secrets`, `tags`, `users`, `roles`, and `web_hooks`. Database indexes include `alerts`, `jobs`, `servers`, `snapshots`, `activity`, and `tickets`. Extras include job files and logs, Bucket files, Ticket files, Monitor history, statistics history, and user avatars.
414
+
415
+ The destination directory must already exist. Existing files are preserved unless you add `--overwrite`. The completed archive is written with permissions limited to your user account.
416
+
417
+ ## system import
418
+
419
+ Import an xyOps or Cronicle bulk data archive. The command shows the selected file and its format first. **No data is imported until you add `--confirm`.**
420
+
421
+ ```sh
422
+ xy system import xyops-export.json.gz
423
+ xy system import cronicle-export.txt.gz --source cronicle
424
+ xy system import xyops-export.json.gz --dry
425
+ ```
426
+
427
+ Bulk imports can replace existing data, stop running jobs, clear queued jobs, and pause the scheduler. Back up your system and review the selected file before confirming.
428
+
429
+ ## system delete
430
+
431
+ Permanently delete selected categories of system data. Pass a comma-separated list, or use `all` to select everything. **Nothing is deleted until you add `--confirm`.**
432
+
433
+ ```sh
434
+ xy system delete events,categories,buckets
435
+ xy system delete jobs,activity
436
+ xy system delete all
437
+ ```
438
+
439
+ Names normally select the matching configuration list or database index. `alerts` selects both Alert definitions and Alert history. Use an explicit `list:` or `db:` prefix when you only want one, such as `list:alerts` or `db:alerts`.
440
+
441
+ Bulk deletion may pause the scheduler. This operation cannot be undone, so export a backup first.
442
+
443
+ ## system maintenance
444
+
445
+ Run the normal nightly maintenance process immediately. Expired data is removed, and a database backup is created when backups are configured. The work continues as an internal background job.
446
+
447
+ ```sh
448
+ xy system maintenance
449
+ xy system maint
450
+ xy system maintenance --dry
451
+ ```
452
+
453
+ ## system optimize
454
+
455
+ Compact the database to reclaim unused disk space and run an integrity check. The database may be locked while this work runs, so stop active jobs and pause the scheduler first. Results are sent to the administrator by email when email is configured.
456
+
457
+ ```sh
458
+ xy system optimize
459
+ xy system optimize --dry
460
+ ```
461
+
462
+ ## system reset
463
+
464
+ Reset daily dashboard statistics, job rate-limit windows, or the global sync state map. You can reset one rate-limit pool by ID, or omit `--id` to reset every pool.
465
+
466
+ ```sh
467
+ xy system reset daily
468
+ xy system reset rates
469
+ xy system reset rates --id RATE_POOL_ID
470
+ xy system reset rates --dry
471
+ xy system reset sync
472
+ xy system reset sync --dry
473
+ ```
474
+
475
+ Resetting rate limits immediately restores their full allowance, so queued jobs may begin launching on the next scheduler tick.
476
+
477
+ Resetting sync state clears every remote-management flag. It does not change any xyOps definition, local file, or saved sync configuration. The web interface and CLI stop showing their sync-management edit warnings until a later up-only sync publishes a new map. The command displays the target and makes no change until you add `--confirm`.
478
+
479
+ ## system restart
480
+
481
+ Restart a conductor server by hostname. The command shows the selected hostname first. **The restart request is not sent until you add `--confirm`.**
482
+
483
+ ```sh
484
+ xy system restart conductor xyops02.example.com
485
+ ```
486
+
487
+ Restarting a conductor may briefly interrupt service while the process starts again.
488
+
489
+ ## system shutdown
490
+
491
+ Shut down a conductor server by hostname. The command shows the selected hostname first. **The shutdown request is not sent until you add `--confirm`.**
492
+
493
+ ```sh
494
+ xy system shutdown conductor xyops02.example.com
495
+ ```
496
+
497
+ The conductor remains offline until it is started again outside the CLI.
498
+
499
+ ## system upgrade
500
+
501
+ Upgrade or downgrade selected worker or conductor servers. Worker targets may be server IDs or group IDs. Conductor targets are host IDs.
502
+
503
+ ```sh
504
+ xy system upgrade conductors joemax.lan --version v1.0.96
505
+ xy system upgrade workers server1,server2
506
+ xy system upgrade workers GROUP_ID --version latest --stagger 30
507
+ ```
508
+
509
+ The default version is `latest`, and the default delay between servers is 60 seconds. Use `--stagger SECONDS` to change the delay. Review the target summary, then add `--confirm` to start the upgrade.
510
+
511
+ ## system email
512
+
513
+ Send a test email and show the delivery result and mailer log. Use this to verify the xyOps email configuration.
514
+
515
+ ```sh
516
+ xy system email test@example.com
517
+ xy system email --to test@example.com
518
+ xy system email test@example.com --dry
519
+ ```
520
+
521
+ ## system diagnostic
522
+
523
+ Print a detailed System diagnostic snapshot as JSON. The snapshot includes system and storage statistics, conductors, workers, active work, scheduler state, and connections.
524
+
525
+ ```sh
526
+ xy system diagnostic
527
+ xy system diag
528
+ xy system diagnostic --format jsonc
529
+ ```
530
+
531
+ Diagnostic output can contain hostnames, IP addresses, usernames, job parameters, and other private system details. Review it carefully before sharing it.
532
+
533
+ ## system broadcast
534
+
535
+ Send a plain-text notification to every connected xyOps user. The default notification type is `info`.
536
+
537
+ ```sh
538
+ xy system broadcast "System maintenance begins soon"
539
+ xy system broadcast "Please save your work" --type warning
540
+ xy system broadcast --message "All systems are operational" --type info
541
+ xy system broadcast "Deployment complete" --sound bell.mp3
542
+ xy system broadcast "Test message" --dry
543
+ ```
544
+
545
+ Available notification types are `info`, `warning`, `error`, and `critical`. Use `--sound FILENAME` to play a sound that is already available in xyOps.
546
+
547
+ ## snapshots
548
+
549
+ List saved Server and Group snapshots, newest first. Use the optional indexed filters to narrow the history by source, exact Server ID, or exact Group ID.
550
+
551
+ ```sh
552
+ xy snapshots
553
+ xy snapshots --source user
554
+ xy snapshots --server SERVER_ID
555
+ xy snapshots --group GROUP_ID
556
+ xy snapshots --limit 20 --page 2
557
+ xy snapshots --format json
558
+ ```
559
+
560
+ Snapshot sources are `alert`, `user`, `watch`, and `job`. Filters may be combined. Free-form keyword search and custom date ranges are not supported by this command.
561
+
562
+ ## snapshot
563
+
564
+ View one saved Server or Group snapshot by its exact ID. The CLI detects the snapshot type and displays the matching point-in-time view automatically.
565
+
566
+ ```sh
567
+ xy snapshot SNAPSHOT_ID
568
+ xy snapshot SNAPSHOT_ID --monitors
569
+ xy snapshot SNAPSHOT_ID --processes
570
+ xy snapshot SNAPSHOT_ID --connections
571
+ xy snapshot SNAPSHOT_ID --verbose
572
+ xy snapshot SNAPSHOT_ID --delete
573
+ ```
574
+
575
+ The default view includes the captured summary, Alerts, Jobs, Quick Look charts, memory and CPU details, monitor summary, Containers, network interfaces, and filesystems when available. Group snapshots also include the captured Server table.
576
+
577
+ Add `--monitors` to fetch and chart the 60 one-minute historical samples ending at the snapshot. The snapshot minute is the final sample on the right side of each chart. Add `--processes` or `--connections` for the larger captured tables, or use `--verbose` to include all optional sections.
578
+
579
+ Deletion first displays the selected snapshot and makes no change until you add `--confirm`. Snapshot deletion cannot be undone.
580
+
581
+ ## servers
582
+
583
+ List connected Servers and recently disconnected Servers in one view. Results are sorted alphabetically by custom label or hostname.
584
+
585
+ Add search text to match Server IDs, labels, hostnames, IP addresses, operating systems, CPU details, xySat versions, or Server Groups. Named filters use case-insensitive partial matching, so a partial IP address is accepted here.
586
+
587
+ ```sh
588
+ xy servers
589
+ xy servers SEARCH_TEXT
590
+ xy servers --os linux
591
+ xy servers --ip 192.168.1.
592
+ xy servers --group production
593
+ xy servers --online true
594
+ xy servers --limit 20 --page 2
595
+ ```
596
+
597
+ Available named filters include `--id`, `--title`, `--hostname`, `--ip`, `--os`, `--platform`, `--distro`, `--release`, `--arch`, `--cpu`, `--satellite`, `--group`, `--status`, `--online`, and `--enabled`.
598
+
599
+ ## server
600
+
601
+ View a Server's live or last-known state, generate an installation command for a new Server, or search current and historical Server records.
602
+
603
+ ```sh
604
+ xy server SERVER_ID
605
+ xy server SERVER_ID --verbose
606
+ xy server list
607
+ xy server add --platform linux
608
+ xy server search
609
+ xy server search SEARCH_TEXT
610
+ xy server history SERVER_ID YYYY/MM/DD
611
+ xy server SERVER_ID --label "My Custom Label"
612
+ xy server SERVER_ID --snapshot
613
+ xy server SERVER_ID --watch 300
614
+ xy server SERVER_ID --delete
615
+ ```
616
+
617
+ ## server get
618
+
619
+ View the current state of a connected Server, or the last-known state of an offline Server. You can identify the Server by ID, hostname, or label when it is connected or recently disconnected. The summary includes system information, alerts, jobs, monitoring charts, memory, CPU, network interfaces, and filesystems.
620
+
621
+ Use the optional detail flags to show larger tables and monitoring timelines:
622
+
623
+ ```sh
624
+ xy server SERVER_ID
625
+ xy server minecraft2
626
+ xy server render-worker-03
627
+ xy server get SERVER_ID
628
+ xy server SERVER_ID --verbose
629
+ xy server SERVER_ID --monitors
630
+ xy server SERVER_ID --processes
631
+ xy server SERVER_ID --connections
632
+ xy server SERVER_ID --pid 1234
633
+ xy server SERVER_ID --limit 20 --page 2
634
+ ```
635
+
636
+ The `--pid` option opens a focused process view containing only the selected process details and its parent and child processes. Use `--verbose` to include monitors, processes, and network connections together in the main Server view.
637
+
638
+ Quick Look charts are available for connected Servers that support per-second monitoring. Offline Servers display their last-known monitoring state instead.
639
+
640
+ ## server history
641
+
642
+ View historical monitoring charts, alerts, and completed jobs for one Server. Each command displays exactly one hour, day, month, or year. Dates and times are interpreted in the Server's local time zone.
643
+
644
+ ```sh
645
+ xy server history SERVER_ID 2026/09/08/14
646
+ xy server history SERVER_ID 2026/09/08
647
+ xy server history SERVER_ID 2026/09
648
+ xy server history SERVER_ID 2026
649
+ xy server history SERVER_ID 2026/09/08 --limit 20 --page 2
650
+ ```
651
+
652
+ The number of date components selects the zoom level. Use `YYYY/MM/DD/HH` for an hour, `YYYY/MM/DD` for a day, `YYYY/MM` for a month, or `YYYY` for a year.
653
+
654
+ You can use a hostname or Server label in place of the ID when that Server is connected or recently disconnected. The global `--page` and `--limit` options apply to both the alert and completed-job tables.
655
+
656
+ ## server add
657
+
658
+ Generate a one-line xySat installation command for Linux, macOS, Windows, or Docker. Copy the resulting command and run it on the Server you want to add.
659
+
660
+ ```sh
661
+ xy server add --platform linux
662
+ xy server add --platform windows --title "My Custom Server"
663
+ xy server add --platform macos --icon fire-truck
664
+ xy server add --platform docker --groups GROUP1,GROUP2
665
+ xy server add --platform linux --enabled false
666
+ xy server add --platform linux --expires 3600
667
+ ```
668
+
669
+ The installation token is valid for 24 hours by default. Use `--expires SECONDS` to choose a shorter lifetime. Treat the generated command as sensitive until its token expires.
670
+
671
+ If you specify Server Groups, each value must be an existing Group ID. Leave `--groups` unset to use automatic hostname-based grouping.
672
+
673
+ ## server search
674
+
675
+ Search all current and historical Server records. Unlike the active `servers` view, this searches the database and requires complete indexed terms such as a full IP address.
676
+
677
+ Both singular and plural command forms are supported:
678
+
679
+ ```sh
680
+ xy server search
681
+ xy servers search
682
+ xy server search SEARCH_TEXT
683
+ xy server search "192.168.1.25"
684
+ xy server search --os_platform linux --os_arch arm64
685
+ xy server search --groups GROUP_ID
686
+ xy server search --modified today
687
+ xy server search --limit 20 --page 2
688
+ ```
689
+
690
+ Available fields include `--groups`, `--os_platform`, `--os_distro`, `--os_release`, `--os_arch`, `--cpu_virt`, `--cpu_brand`, `--cpu_cores`, `--created`, and `--modified`. Short aliases such as `--group`, `--os`, `--platform`, `--distro`, `--release`, `--arch`, `--virt`, and `--cpu` are also accepted.
691
+
692
+ ## server commands
693
+
694
+ Edit a Server, take a snapshot, set a temporary snapshot watch, or permanently delete it. You can identify a connected or recently disconnected Server by ID, hostname, or label.
695
+
696
+ ```sh
697
+ xy server SERVER_ID --label "My Custom Label"
698
+ xy server SERVER_ID --enabled false
699
+ xy server SERVER_ID --icon baguette
700
+ xy server SERVER_ID --groups "group1,group2"
701
+ xy server SERVER_ID --groups ""
702
+ xy server SERVER_ID --max_jobs 5
703
+ xy server SERVER_ID --user_data '{"foo":"bar"}'
704
+ xy server SERVER_ID --user_data @server-data.json
705
+ xy server SERVER_ID --snapshot
706
+ xy server SERVER_ID --watch 300
707
+ xy server SERVER_ID --watch 0
708
+ xy server SERVER_ID --delete
709
+ ```
710
+
711
+ An empty `--groups` value restores automatic hostname-based grouping. Snapshot and watch commands require a connected Server. A watch takes one snapshot per minute for the requested number of seconds, and `--watch 0` removes it.
712
+
713
+ Server deletion always removes the Server record, all monitoring history, and all snapshots. If the Server is connected, xySat is also uninstalled. The command shows a detailed preview first and does nothing until you add `--confirm`.
714
+
715
+ ## groups
716
+
717
+ List Server Groups in their saved order. The table includes each Group's ID, title, connected Server count, hostname pattern, Alert Action count, author, and modification time. Search text matches IDs, titles, hostname patterns, and notes. Named filters may also be combined.
718
+
719
+ ```sh
720
+ xy groups
721
+ xy groups SEARCH_TEXT
722
+ xy groups --title Production
723
+ xy groups --hostname_match "^db"
724
+ xy groups --limit 10 --page 2
725
+ xy groups --format json
726
+ ```
727
+
728
+ The Server count includes currently connected Servers. Recently offline Servers may appear in a Group's detail view, but are not included in this count.
729
+
730
+ ## group
731
+
732
+ View, create, update, or delete a Server Group. A bare ID or fuzzy title opens the combined live monitoring view. Updates and deletes require an exact Group ID.
733
+
734
+ ```sh
735
+ xy group GROUP_ID_OR_TITLE
736
+ xy group get GROUP_ID_OR_TITLE
737
+ xy group list
738
+ xy group create --title "Production DBs" --hostname_match "db\\d+\\.prod\\."
739
+ xy group update GROUP_ID --icon baguette
740
+ xy group delete GROUP_ID
741
+ xy group history GROUP_ID YYYY/MM/DD
742
+ ```
743
+
744
+ ## group list
745
+
746
+ List and filter Server Groups. This is an alias for `xy groups`, with the same options.
747
+
748
+ ```sh
749
+ xy group list
750
+ xy group list SEARCH_TEXT
751
+ xy group list --limit 10 --page 2
752
+ ```
753
+
754
+ ## group get
755
+
756
+ Show the combined live or recently offline state for all selected Servers in a Group. The view includes the Group summary, Server table, active Alerts and Jobs, Quick Look charts, memory and CPU details, Containers, and optional Monitor, Process, and connection sections.
757
+
758
+ ```sh
759
+ xy group GROUP_ID
760
+ xy group GROUP_ID --verbose
761
+ xy group GROUP_ID --monitors
762
+ xy group GROUP_ID --processes
763
+ xy group GROUP_ID --connections
764
+ xy group GROUP_ID --merge total
765
+ xy group GROUP_ID --merge max
766
+ xy group GROUP_ID --limit 20 --page 2
767
+ ```
768
+
769
+ Chart and detail values default to `--merge average`. The accepted modes are `average` (or `avg`), `maximum` (or `max`), `minimum` (or `min`), and `total`. The selected merge mode is included in each chart title.
770
+
771
+ Use `--verbose` to show Monitors, Processes, and network connections together, or enable those sections individually. Containers are always shown when available. Process and Container actions are intentionally read-only in the Group view.
772
+
773
+ You can limit the live view to matching Servers:
774
+
775
+ ```sh
776
+ xy group GROUP_ID SEARCH_TEXT
777
+ xy group GROUP_ID --os linux
778
+ xy group GROUP_ID --ip 192.168.
779
+ xy group GROUP_ID --arch arm64
780
+ xy group GROUP_ID --online true
781
+ ```
782
+
783
+ Search text checks Server IDs, labels, hostnames, IP addresses, operating system details, CPU details, xySat versions, and Group names. Named filters use the same case-insensitive partial matching as `xy servers`.
784
+
785
+ Add `--upcoming` to show only the Group summary and predicted upcoming Jobs:
786
+
787
+ ```sh
788
+ xy group GROUP_ID --upcoming
789
+ xy group GROUP_ID --upcoming --limit 20 --page 2
790
+ ```
791
+
792
+ ## group history
793
+
794
+ View merged historical Monitor charts, Alerts, and completed Jobs for a Server Group. The view includes Servers that belonged to the Group during the selected period.
795
+
796
+ ```sh
797
+ xy group history GROUP_ID 2026/09/09/14
798
+ xy group history GROUP_ID 2026/09/09
799
+ xy group history GROUP_ID 2026/09
800
+ xy group history GROUP_ID 2026
801
+ xy group history GROUP_ID 2026/09/09 --merge maximum
802
+ xy group history GROUP_ID 2026/09/09 --limit 20 --page 2
803
+ ```
804
+
805
+ The number of date components selects exactly one hour, day, month, or year. Dates and times use the xyOps Server's local time zone. Server filters such as `--os` and `--ip` apply only to live Group views.
806
+
807
+ The `--merge` modes are the same as the live view, and historical Monitor charts are always shown. Pagination applies to the Server, Alert, and completed Job tables.
808
+
809
+ ## group create
810
+
811
+ Create a Server Group with a required title. The hostname pattern defaults to a regular expression that matches no Servers when omitted. xyOps generates an ID unless you provide one.
812
+
813
+ ```sh
814
+ xy group create --title "Production DBs" --hostname_match "db\\d+\\.prod\\."
815
+ xy group create --id production --title "Production" --hostname_match ".+"
816
+ xy group create --title "Manual Group" --icon server-network
817
+ xy group create --title "Limited Workers" --max_jobs_per_server 4
818
+ xy group create --title "Notifications" --action '{ "type":"web_hook", "enabled":true, "condition":"alert_new", "web_hook":"example_hook" }'
819
+ xy group create --json @group.json
820
+ xy group create --title "Preview" --dry
821
+ ```
822
+
823
+ Supported fields are `id`, `title`, `hostname_match`, `icon`, `notes`, `max_jobs_per_server`, and `alert_actions`. The singular `--action` option appends one Alert Action and may be repeated. Use `--alert_actions` to provide a complete JSON array.
824
+
825
+ `max_jobs_per_server` sets the default concurrent Job limit for each Server in the Group. Zero means unlimited. Individual Server settings may override it.
826
+
827
+ ## group update
828
+
829
+ Update a Server Group by exact ID. Omitted fields remain unchanged. Use `--alert_actions` to replace the complete Alert Action list, dotted options to edit existing Actions, or `--action` to append a new one.
830
+
831
+ ```sh
832
+ xy group update GROUP_ID --title "New Title" --notes "Updated notes"
833
+ xy group update GROUP_ID --hostname_match "^prod-db-"
834
+ xy group update GROUP_ID --icon baguette --max_jobs_per_server 8
835
+ xy group update GROUP_ID --alert_actions.0.enabled false
836
+ xy group update GROUP_ID --action @action.json
837
+ xy group update GROUP_ID --alert_actions '[]'
838
+ xy group update GROUP_ID --json @group-update.json
839
+ xy group update GROUP_ID --notes "Preview" --dry
840
+ ```
841
+
842
+ An empty `hostname_match` matches no Servers. Invalid regular expressions are rejected without changing the Group. The Group ID cannot be changed.
843
+
844
+ ## group delete
845
+
846
+ Permanently delete a Server Group by exact ID. The command shows the selected Group and does nothing until you add `--confirm`.
847
+
848
+ ```sh
849
+ xy group delete GROUP_ID
850
+ xy group delete --id GROUP_ID
851
+ xy group delete GROUP_ID --dry
852
+ ```
853
+
854
+ Deleting a Group changes Server membership and may affect Event targets, Monitor scopes, Alert definitions, and other saved configuration. Review those references before confirming.
855
+
856
+ ## upcoming
857
+
858
+ Show the main dashboard with the upcoming-jobs section included. This is a convenient shortcut for `xy dashboard --upcoming`.
859
+
860
+ ```sh
861
+ xy upcoming
862
+ xy dashboard --upcoming
863
+ ```
864
+
865
+ ## alerts
866
+
867
+ List Alert definitions, or search Alert invocations when the next word is `search`.
868
+
869
+ ```sh
870
+ xy alerts
871
+ xy alerts list
872
+ xy alerts SEARCH_TEXT
873
+ xy alerts --enabled false
874
+ xy alerts --group ID_OR_TITLE
875
+ xy alerts --monitor ID_OR_TITLE
876
+ xy alerts search
877
+ xy alerts search --active
878
+ ```
879
+
880
+ The bare and `list` forms always show definitions. Search text matches definition IDs, titles, expressions, and messages. Definition filters may be combined.
881
+
882
+ ## alerts search
883
+
884
+ Search historical and active alert invocations. A positional query uses the native xyOps search syntax, while common filters have shorter named options.
885
+
886
+ ```sh
887
+ xy alerts search
888
+ xy alerts search 'active:true server:SERVER_ID'
889
+ xy alerts search --alert ID_OR_TITLE
890
+ xy alerts search --server ID_OR_TITLE
891
+ xy alerts search --group ID_OR_TITLE
892
+ xy alerts search --active
893
+ xy alerts search --cleared
894
+ xy alerts search --date today
895
+ xy alerts search --date 2026-09-01
896
+ xy alerts search --job JOB_ID
897
+ xy alerts search --ticket TICKET_ID
898
+ xy alerts search --oldest
899
+ xy alerts search --format json
900
+ ```
901
+
902
+ `--alert`, `--server`, and `--group` accept an ID or fuzzy title. Built-in date ranges are `now`, `hour`, `lasthour`, `today`, `yesterday`, `month`, `lastmonth`, `year`, `lastyear`, and `older`. Newest invocations are shown first unless `--oldest` or `--sort asc` is supplied.
903
+
904
+ Other named options may be used for additional searchable fields.
905
+
906
+ ## alert
907
+
908
+ Work with alert definitions and alert invocations through one short command. Operations that create, update, or test always target definitions. Search always targets invocations.
909
+
910
+ ```sh
911
+ xy alert ID_OR_TITLE
912
+ xy alert get ID_OR_TITLE
913
+ xy alert create --title "My Alert" --expression "cpu.currentLoad > 80" --message "CPU is high"
914
+ xy alert update DEFINITION_ID --enabled false
915
+ xy alert test DEFINITION_ID --server SERVER_ID_OR_TITLE
916
+ xy alert delete ALERT_ID
917
+ ```
918
+
919
+ Get and delete can refer to either resource type. Use an exact Alert ID for an invocation, or an exact definition ID or fuzzy definition title for a definition.
920
+
921
+ ## alert get
922
+
923
+ View either an alert definition or alert invocation. A bare selector is the short form of `alert get`.
924
+
925
+ ```sh
926
+ xy alert ID_OR_TITLE
927
+ xy alert get ID_OR_TITLE
928
+ xy alert get ALERT_ID --format json
929
+ xy alert ALERT_DEFINITION_ID --export alert.json
930
+ ```
931
+
932
+ Definition detail includes its expression, message, groups, monitor overlay, behavior flags, revision metadata, and configured actions. Invocation detail includes its definition, server, status, timing, evaluated message and expression, executed actions, snapshots, tickets, and jobs.
933
+
934
+ ## alert create
935
+
936
+ Create an alert definition. Title, expression, and message are required. The remaining fields use the same defaults as the xyOps web interface.
937
+
938
+ ```sh
939
+ xy alert create --title "High CPU" --expression "cpu.currentLoad > 80" --message "CPU is {{pct(cpu.currentLoad)}}"
940
+ xy alert create --title "Main Servers" --expression "cpu.cores > 0" --message "Online" --group main
941
+ xy alert create --title "Careful" --expression "monitors.load_avg > 10" --message "High load" --samples 3
942
+ xy alert create --title "Job Guard" --expression "monitors.load_avg > 20" --message "High load" --limit-jobs --abort-jobs
943
+ xy alert create --title "Custom Action" --expression "cpu.cores > 0" --message "Online" --action @action.json
944
+ xy alert create --title "Preview" --expression "cpu.cores > 0" --message "Online" --dry
945
+ ```
946
+
947
+ Repeat `--group` to restrict the definition to multiple server groups. Use `--monitor ID`, `--samples N`, `--exclusive`, `--limit-jobs`, and `--abort-jobs` for the corresponding definition settings. Actions may be supplied as a complete JSON array in `--actions` or appended as JSON objects with repeated `--action` options.
948
+
949
+ Alert definitions normally inherit alert actions from matching server groups and the universal configuration. `--exclusive` limits execution to actions stored directly on the definition.
950
+
951
+ ## alert update
952
+
953
+ Update an alert definition by its exact internal ID. Alert invocations cannot be updated.
954
+
955
+ ```sh
956
+ xy alert update DEFINITION_ID --title "New Title"
957
+ xy alert update DEFINITION_ID --enabled false
958
+ xy alert update DEFINITION_ID --expression "monitors.load_avg > 12" --samples 2
959
+ xy alert update DEFINITION_ID --monitor none
960
+ xy alert update DEFINITION_ID --group main
961
+ xy alert update DEFINITION_ID --exclusive true --limit-jobs false
962
+ xy alert update DEFINITION_ID --actions.0.enabled false
963
+ xy alert update DEFINITION_ID --delete actions.0.params.example
964
+ xy alert update DEFINITION_ID --notes "Preview" --dry
965
+ ```
966
+
967
+ Dotted options preserve other nested values. Repeat `--delete PATH` to remove nested object properties. Paths are strict, so missing properties and attempts to delete array elements are rejected.
968
+
969
+ ## alert test
970
+
971
+ Test an alert definition against the current monitor data for one server. This validates the expression and message macros, then shows whether the definition would trigger and previews the evaluated message.
972
+
973
+ ```sh
974
+ xy alert test DEFINITION_ID --server SERVER_ID_OR_TITLE
975
+ xy alert test "High CPU" --server web-01
976
+ xy alert test --server SERVER_ID --expression "cpu.cores > 0" --message "{{os.hostname}} is online"
977
+ xy alert test DEFINITION_ID --server SERVER_ID --expression "false"
978
+ ```
979
+
980
+ The final two forms provide temporary overrides and do not update the stored definition.
981
+
982
+ ## alert delete
983
+
984
+ Permanently delete an alert definition or one alert invocation by exact internal ID. Explicit confirmation is always required.
985
+
986
+ ```sh
987
+ xy alert delete DEFINITION_ID
988
+ xy alert delete INVOCATION_ID
989
+ xy alert delete ALERT_ID --dry
990
+ ```
991
+
992
+ Deleting an invocation removes only that historical record. Deleting a definition also removes its current state and invocation history.
993
+
994
+ ## buckets
995
+
996
+ List storage Bucket definitions and their metadata. Use `bucket get` to view a Bucket's JSON data and files.
997
+
998
+ ```sh
999
+ xy buckets
1000
+ xy buckets list
1001
+ xy buckets SEARCH_TEXT
1002
+ xy buckets --enabled false
1003
+ xy buckets --disabled
1004
+ xy buckets --format json
1005
+ ```
1006
+
1007
+ Search text matches bucket IDs, titles, notes, and authors. The first table column contains the complete internal Bucket ID, which is used by all mutating commands.
1008
+
1009
+ ## bucket
1010
+
1011
+ Work with a storage bucket's metadata, JSON data, and files. A bare ID or fuzzy title opens the complete bucket details.
1012
+
1013
+ ```sh
1014
+ xy bucket BUCKET_ID_OR_TITLE
1015
+ xy bucket get BUCKET_ID_OR_TITLE
1016
+ xy bucket create --title "Build Artifacts"
1017
+ xy bucket update BUCKET_ID --title "Release Artifacts"
1018
+ xy bucket write BUCKET_ID --data @data.json
1019
+ xy bucket upload BUCKET_ID --file report.csv
1020
+ xy bucket file download BUCKET_ID report.csv
1021
+ xy bucket file delete BUCKET_ID report.csv
1022
+ xy bucket empty BUCKET_ID --data --files
1023
+ xy bucket delete BUCKET_ID
1024
+ ```
1025
+
1026
+ Bucket metadata, JSON data, and files have separate commands. Use `bucket update` for metadata, `bucket write` for JSON data, and the file commands for attachments.
1027
+
1028
+ ## bucket get
1029
+
1030
+ View a bucket definition together with all current JSON data and file metadata. The file list includes complete File IDs and normalized filenames.
1031
+
1032
+ ```sh
1033
+ xy bucket BUCKET_ID_OR_TITLE
1034
+ xy bucket get BUCKET_ID_OR_TITLE
1035
+ xy bucket get BUCKET_ID --format json
1036
+ xy bucket BUCKET_ID --export bucket.json
1037
+ ```
1038
+
1039
+ JSON output contains `bucket`, `data`, and `files`. The `--export` variant writes only the Bucket definition to XYPDF; see `xy help export`.
1040
+
1041
+ ## bucket create
1042
+
1043
+ Create a storage bucket with optional initial JSON data and files. The title is required. Status, icon, and notes use the same fields as the web interface.
1044
+
1045
+ ```sh
1046
+ xy bucket create --title "Build Artifacts"
1047
+ xy bucket create --title "Disabled Bucket" --enabled false
1048
+ xy bucket create --title "Release Data" --icon archive --notes "Production releases"
1049
+ xy bucket create --title "Counters" --data.count 1 --data.status ready
1050
+ xy bucket create --title "From Data" --data @data.json
1051
+ cat data.json | xy bucket create --title "From STDIN" --data @-
1052
+ xy bucket create --json @bucket.json
1053
+ xy bucket create --title "With Files" --file report.csv --file summary.txt
1054
+ xy bucket create --title "Preview" --data @data.json --file report.csv --dry
1055
+ ```
1056
+
1057
+ ## bucket update
1058
+
1059
+ Update bucket metadata using the exact internal Bucket ID.
1060
+
1061
+ ```sh
1062
+ xy bucket update BUCKET_ID --title "Release Artifacts"
1063
+ xy bucket update BUCKET_ID --enabled false
1064
+ xy bucket update BUCKET_ID --icon archive --notes "Production releases"
1065
+ xy bucket update BUCKET_ID --notes "Preview" --dry
1066
+ ```
1067
+
1068
+ This command only accepts `title`, `enabled`, `icon`, and `notes`. Use `bucket write` for JSON data and the file commands for file contents.
1069
+
1070
+ ## bucket write
1071
+
1072
+ Merge a JSON object into a Bucket's existing data. The exact internal Bucket ID is required.
1073
+
1074
+ ```sh
1075
+ xy bucket write BUCKET_ID --data.status ready --data.build 42
1076
+ xy bucket write BUCKET_ID --data @data.json
1077
+ cat data.json | xy bucket write BUCKET_ID --data @-
1078
+ xy bucket write BUCKET_ID --json @request.json
1079
+ cat request.json | xy bucket write BUCKET_ID --json @-
1080
+ xy bucket write BUCKET_ID --data @data.json --format json
1081
+ ```
1082
+
1083
+ `--data @-` treats the piped object as the Bucket data itself. The `--json` forms expect an object containing a `data` property. This is a shallow merge, so existing top-level keys not present in the input are preserved.
1084
+
1085
+ ## bucket upload
1086
+
1087
+ Upload one or more local files without changing bucket metadata. Existing files with the same normalized filename are replaced.
1088
+
1089
+ ```sh
1090
+ xy bucket upload BUCKET_ID --file report.csv
1091
+ xy bucket upload BUCKET_ID --file report.csv --file summary.txt
1092
+ xy bucket upload BUCKET_ID --files '["report.csv", "summary.txt"]'
1093
+ xy bucket upload BUCKET_ID --file report.csv --dry
1094
+ ```
1095
+
1096
+ xyOps normalizes uploaded filenames to lowercase and replaces unsupported characters with underscores. Server-configured file count, size, and type limits still apply.
1097
+
1098
+ ## bucket file
1099
+
1100
+ Download or permanently delete one file. Supply either the exact normalized filename or the internal File ID shown by `bucket get`.
1101
+
1102
+ ```sh
1103
+ xy bucket file download BUCKET_ID report.csv
1104
+ xy bucket file download BUCKET_ID FILE_ID ./downloads/report.csv
1105
+ xy bucket file delete BUCKET_ID report.csv
1106
+ xy bucket file delete BUCKET_ID FILE_ID
1107
+ ```
1108
+
1109
+ ## bucket file download
1110
+
1111
+ Download a bucket file to disk. The output path defaults to the stored filename in the current directory, or it can be supplied as the final positional argument, with `--output`, or with `--download`.
1112
+
1113
+ ```sh
1114
+ xy bucket file download BUCKET_ID report.csv
1115
+ xy bucket file download BUCKET_ID report.csv ./downloads/report.csv
1116
+ xy bucket file download BUCKET_ID report.csv --output ./report-copy.csv
1117
+ xy bucket download BUCKET_ID report.csv --download ./report-copy.csv
1118
+ xy bucket file download BUCKET_ID report.csv --dry
1119
+ ```
1120
+
1121
+ The command refuses to overwrite an existing local file.
1122
+
1123
+ ## bucket file delete
1124
+
1125
+ Permanently delete one bucket file. Explicit confirmation is required.
1126
+
1127
+ ```sh
1128
+ xy bucket file delete BUCKET_ID report.csv
1129
+ xy bucket file delete BUCKET_ID FILE_ID
1130
+ xy bucket file delete BUCKET_ID report.csv --dry
1131
+ ```
1132
+
1133
+ ## bucket empty
1134
+
1135
+ Permanently clear all data, all files, or both while keeping the bucket definition. Explicit confirmation is required.
1136
+
1137
+ ```sh
1138
+ xy bucket empty BUCKET_ID --data
1139
+ xy bucket empty BUCKET_ID --files
1140
+ xy bucket empty BUCKET_ID --data --files
1141
+ xy bucket empty BUCKET_ID --all
1142
+ xy bucket empty BUCKET_ID --all --dry
1143
+ ```
1144
+
1145
+ ## bucket delete
1146
+
1147
+ Permanently delete a bucket definition together with all of its data and files. The exact internal Bucket ID and explicit confirmation are required.
1148
+
1149
+ ```sh
1150
+ xy bucket delete BUCKET_ID
1151
+ xy bucket delete BUCKET_ID --dry
1152
+ ```
1153
+
1154
+ Bucket deletion cannot be undone.
1155
+
1156
+ ## keys
1157
+
1158
+ List API Keys and their safe metadata. The plaintext secret is never included. You can search by ID, title, description, or partial key, and filter by status, direct privilege, or role ID.
1159
+
1160
+ ```sh
1161
+ xy keys
1162
+ xy keys SEARCH_TEXT
1163
+ xy keys --active false
1164
+ xy keys --expired true
1165
+ xy keys --privilege run_jobs
1166
+ xy keys --role ROLE_ID
1167
+ xy keys --format json
1168
+ ```
1169
+
1170
+ The list includes the internal Key ID, which is safe to display and is used by update and delete commands. `--active false` includes disabled keys. `--expired true` includes enabled or disabled keys whose expiration time has passed.
1171
+
1172
+ ## key
1173
+
1174
+ Work with one API Key by viewing, creating, updating, or deleting it. A bare ID or fuzzy title opens the key details directly.
1175
+
1176
+ ```sh
1177
+ xy key KEY_ID_OR_TITLE
1178
+ xy key get KEY_ID_OR_TITLE
1179
+ xy key create --title "My App" --privileges.admin
1180
+ xy key update KEY_ID --active false
1181
+ xy key delete KEY_ID
1182
+ ```
1183
+
1184
+ Updates and deletes require the exact internal Key ID. The authentication secret itself can never be updated or retrieved.
1185
+
1186
+ ## key get
1187
+
1188
+ View one API Key's safe metadata, including its partial key, status, privileges, roles, rate limit, expiration, and last-used time. Normal detail output omits the stored key hash and plaintext secret. The `--export` variant preserves the key definition for restoration; see `xy help export`.
1189
+
1190
+ ```sh
1191
+ xy key KEY_ID_OR_TITLE
1192
+ xy key get KEY_ID_OR_TITLE
1193
+ xy key get KEY_ID --format json
1194
+ xy key KEY_ID --export key.json
1195
+ ```
1196
+
1197
+ ## key create
1198
+
1199
+ Create a new API Key. xyOps generates the authentication secret and the CLI displays it exactly once. Copy it immediately and store it securely.
1200
+
1201
+ ```sh
1202
+ xy key create --title "My App"
1203
+ xy key create --title "Admin Tool" --privileges.admin
1204
+ xy key create --title "Runner" --privileges.run_jobs --description "Production runner"
1205
+ xy key create --title "Service" --privilege run_jobs --privilege tag_jobs
1206
+ xy key create --title "Service" --role ROLE_ID --rate 10
1207
+ xy key create --title "Temporary" --expires "2026-12-31"
1208
+ xy key create --title "Dormant" --active false
1209
+ xy key create --title "From JSON" --json @key.json
1210
+ xy key create --title "Preview" --dry
1211
+ ```
1212
+
1213
+ Without an explicit privilege selection, new keys inherit the server's default user privileges. Use dotted options such as `--privileges.admin`, a JSON object in `--privileges`, or repeat `--privilege PRIVILEGE_ID`. Selecting `admin` removes redundant direct privileges because administrators already have every privilege.
1214
+
1215
+ Roles can be supplied using `--roles ROLE_ID_1,ROLE_ID_2`, a JSON array, or repeated `--role ROLE_ID` options. `--rate 0` means unlimited. Expiration accepts a date or time understood by Node.js, a Unix timestamp, or `never`.
1216
+
1217
+ With `--format json`, the one-time secret is returned as `plain_key`; the accompanying `api_key` object contains safe metadata only.
1218
+
1219
+ ## key update
1220
+
1221
+ Update an API Key using its exact internal ID. Dotted privilege options preserve the key's other direct privileges.
1222
+
1223
+ ```sh
1224
+ xy key update KEY_ID --title "New App Title"
1225
+ xy key update KEY_ID --active false
1226
+ xy key update KEY_ID --privileges.run_jobs true
1227
+ xy key update KEY_ID --delete privileges.tag_jobs
1228
+ xy key update KEY_ID --delete privileges.tag_jobs --delete privileges.run_jobs
1229
+ xy key update KEY_ID --role ROLE_ID
1230
+ xy key update KEY_ID --roles '[]'
1231
+ xy key update KEY_ID --rate 25 --expires "2027-01-01"
1232
+ xy key update KEY_ID --expires never
1233
+ xy key update KEY_ID --description "Preview" --dry
1234
+ ```
1235
+
1236
+ Repeat `--delete PATH` to remove one or more existing nested object properties. Paths are strict, so missing properties and attempts to delete array elements are rejected. Setting a dotted privilege to `false` also removes it from the privilege hash.
1237
+
1238
+ Pass a complete privilege object or roles array when you want to replace the current collection. For example, `--roles '[]'` removes all roles. The API Key secret cannot be updated. Create a replacement key instead.
1239
+
1240
+ ## key delete
1241
+
1242
+ Permanently delete an API Key using its exact internal ID. Explicit confirmation is required.
1243
+
1244
+ ```sh
1245
+ xy key delete KEY_ID
1246
+ xy key delete KEY_ID --dry
1247
+ ```
1248
+
1249
+ Deletion cannot be undone. Any service using the deleted key immediately loses access.
1250
+
1251
+ ## secrets
1252
+
1253
+ List Secret Vault metadata without decrypting any variable values. Search text matches vault IDs, titles, notes, and variable names. Named filters may be combined.
1254
+
1255
+ ```sh
1256
+ xy secrets
1257
+ xy secrets SEARCH_TEXT
1258
+ xy secrets --enabled false
1259
+ xy secrets --name API_TOKEN
1260
+ xy secrets --event EVENT_ID
1261
+ xy secrets --category CATEGORY_ID --plugin PLUGIN_ID
1262
+ xy secrets --hook WEB_HOOK_ID
1263
+ xy secrets --limit 10 --page 2
1264
+ xy secrets --format json
1265
+ ```
1266
+
1267
+ The list includes variable names and assignment counts, but never encrypted or decrypted values. `--web_hook` is also accepted as a longer alias for `--hook`.
1268
+
1269
+ ## secret
1270
+
1271
+ Work with one Secret Vault by viewing, creating, updating, decrypting, or deleting it. A bare ID or fuzzy title opens safe vault metadata. Updates, decryption, and deletion require the exact internal Vault ID.
1272
+
1273
+ ```sh
1274
+ xy secret SECRET_VAULT_ID_OR_TITLE
1275
+ xy secret get SECRET_VAULT_ID_OR_TITLE
1276
+ xy secret list
1277
+ xy secret create --title "My Vault" --fields @secrets.json
1278
+ xy secret update SECRET_VAULT_ID --notes "Updated notes"
1279
+ xy secret decrypt SECRET_VAULT_ID
1280
+ xy secret delete SECRET_VAULT_ID
1281
+ ```
1282
+
1283
+ Creating, updating, decrypting, and deleting Secret Vaults requires an administrator API Key.
1284
+
1285
+ ## secret list
1286
+
1287
+ List and filter Secret Vault metadata using the same options as `xy secrets`.
1288
+
1289
+ ```sh
1290
+ xy secret list
1291
+ xy secret list --enabled true
1292
+ xy secret list --plugin PLUGIN_ID
1293
+ xy secret list --hook WEB_HOOK_ID
1294
+ ```
1295
+
1296
+ ## secret get
1297
+
1298
+ View one Secret Vault's safe metadata, including variable names, assignments, notes, author, dates, and revision. Variable values are not returned by this operation.
1299
+
1300
+ ```sh
1301
+ xy secret SECRET_VAULT_ID_OR_TITLE
1302
+ xy secret get --id SECRET_VAULT_ID
1303
+ xy secret get --title "My Vault"
1304
+ xy secret SECRET_VAULT_ID --format json
1305
+ ```
1306
+
1307
+ ## secret create
1308
+
1309
+ Create a Secret Vault with a required title. New vaults default to enabled with no variables or assignments. Supply `fields` as a complete JSON array containing `name` and `value` strings.
1310
+
1311
+ ```json
1312
+ [
1313
+ { "name": "API_TOKEN", "value": "replace-me" },
1314
+ { "name": "PRIVATE_KEY", "value": "line one\nline two" }
1315
+ ]
1316
+ ```
1317
+
1318
+ Use a private file or standard input whenever practical. Putting plaintext values directly on the command line can save them in your shell history.
1319
+
1320
+ ```sh
1321
+ xy secret create --title "My Vault" --fields @secrets.json
1322
+ cat secrets.json | xy secret create --title "My Vault" --fields @-
1323
+ xy secret create --title "Service" --fields @secrets.json --events "EVENT_ID,EVENT_ID_2"
1324
+ xy secret create --title "Shared" --fields @secrets.json --category CATEGORY_ID --plugin PLUGIN_ID --hook WEB_HOOK_ID
1325
+ xy secret create --title "Empty Vault"
1326
+ xy secret create --title "Preview" --fields @secrets.json --dry
1327
+ ```
1328
+
1329
+ Complete assignment lists are accepted through `events`, `categories`, `plugins`, and `web_hooks` as comma-separated strings or JSON arrays. The singular `event`, `category`, `plugin`, `web_hook`, and `hook` options append one or more IDs and may be repeated. Assignments must refer to objects visible to the configured API Key.
1330
+
1331
+ Variable names use the portable environment-variable form: letters, digits, and underscores, with a letter or underscore first. Names must be unique within a vault. Dry-run and verbose previews replace every variable value with `[REDACTED]`. `--format json` returns safe vault metadata only.
1332
+
1333
+ ## secret update
1334
+
1335
+ Update a Secret Vault by exact ID. Omitted settings and encrypted variables remain unchanged.
1336
+
1337
+ ```sh
1338
+ xy secret update SECRET_VAULT_ID --title "New Title" --notes "Updated notes"
1339
+ xy secret update SECRET_VAULT_ID --enabled false
1340
+ xy secret update SECRET_VAULT_ID --events "EVENT_ID,EVENT_ID_2"
1341
+ xy secret update SECRET_VAULT_ID --plugins '[]' --hook WEB_HOOK_ID
1342
+ xy secret update SECRET_VAULT_ID --fields @secrets.json
1343
+ cat secrets.json | xy secret update SECRET_VAULT_ID --fields @-
1344
+ xy secret update SECRET_VAULT_ID --fields '[]'
1345
+ xy secret update SECRET_VAULT_ID --notes "Preview" --dry
1346
+ ```
1347
+
1348
+ When `fields` is supplied, it must contain the complete replacement array. Individual variable updates, dotted field paths, and a singular `field` option are not supported. Omitting `fields` leaves all encrypted values untouched. Supplying `[]` removes every variable.
1349
+
1350
+ Complete assignment lists replace the saved lists. Singular assignment aliases append to the saved list without duplicates. Use an empty array to clear a list. Dry-run and verbose output always redact variable values.
1351
+
1352
+ ## secret decrypt
1353
+
1354
+ Decrypt every variable in a Secret Vault by exact ID. Explicit confirmation is required because xyOps records this access in its activity log.
1355
+
1356
+ ```sh
1357
+ xy secret decrypt SECRET_VAULT_ID
1358
+ xy secret decrypt SECRET_VAULT_ID --format json
1359
+ xy secret decrypt SECRET_VAULT_ID --dry
1360
+ ```
1361
+
1362
+ Human-readable output gives each variable its own titled section and prints the value exactly, without a table or surrounding box. This preserves multiline values for selection and copying. JSON output is an array of plaintext `{ "name", "value" }` objects. Treat both forms as sensitive and avoid redirecting them to an insecure destination.
1363
+
1364
+ Without `--confirm`, the command displays the target vault and a warning without decrypting it. `--dry` does not decrypt the vault or create a secret-access audit event. Verbose diagnostics are redacted, while the final confirmed output intentionally contains plaintext.
1365
+
1366
+ ## secret delete
1367
+
1368
+ Permanently delete a Secret Vault by exact ID. Explicit confirmation is required.
1369
+
1370
+ ```sh
1371
+ xy secret delete SECRET_VAULT_ID
1372
+ xy secret delete --id SECRET_VAULT_ID
1373
+ xy secret delete SECRET_VAULT_ID --dry
1374
+ ```
1375
+
1376
+ Deletion cannot be undone. Review Events, Categories, Plugins, and Web Hooks that may rely on the vault before deleting it. `--dry` previews the deletion without making changes.
1377
+
1378
+ ## tags
1379
+
1380
+ List Tag definitions alphabetically by title. Search text matches IDs, titles, notes, and authors. Named filters may be combined.
1381
+
1382
+ ```sh
1383
+ xy tags
1384
+ xy tags SEARCH_TEXT
1385
+ xy tags --icon alert-rhombus
1386
+ xy tags --title Production
1387
+ xy tags --limit 10 --page 2
1388
+ xy tags --format json
1389
+ ```
1390
+
1391
+ The table includes each Tag's ID, title, icon, number of matching Events, author, and modification time. Use `--limit`, `--page`, or `--offset` to page through human-readable output. JSON output includes every matching Tag definition.
1392
+
1393
+ ## tag
1394
+
1395
+ Work with one Tag by viewing, creating, updating, or deleting it. A bare ID or fuzzy title opens the Tag details directly. Updates and deletes require the exact internal Tag ID.
1396
+
1397
+ ```sh
1398
+ xy tag TAG_ID_OR_TITLE
1399
+ xy tag get TAG_ID_OR_TITLE
1400
+ xy tag list
1401
+ xy tag create --title "Production" --icon server
1402
+ xy tag update TAG_ID --notes "Production workloads"
1403
+ xy tag delete TAG_ID
1404
+ ```
1405
+
1406
+ The configured API Key needs `create_tags`, `edit_tags`, or `delete_tags` for the corresponding mutation. Listing and viewing Tags only require a valid API Key.
1407
+
1408
+ ## tag list
1409
+
1410
+ List and filter Tag definitions using the same options as `xy tags`.
1411
+
1412
+ ```sh
1413
+ xy tag list
1414
+ xy tag list SEARCH_TEXT
1415
+ xy tag list --icon tag-outline
1416
+ xy tag list --limit 10 --page 2
1417
+ ```
1418
+
1419
+ ## tag get
1420
+
1421
+ View a Tag's title, icon, Event count, notes, author, dates, and revision. Exact IDs take precedence over fuzzy title matches.
1422
+
1423
+ ```sh
1424
+ xy tag TAG_ID_OR_TITLE
1425
+ xy tag get --id TAG_ID
1426
+ xy tag get --title "Production"
1427
+ xy tag TAG_ID --format json
1428
+ xy tag TAG_ID --export tag.json
1429
+ xy events --tags TAG_ID
1430
+ ```
1431
+
1432
+ ## tag create
1433
+
1434
+ Create a Tag with a required title. xyOps generates an ID unless you provide one. New Tags use the `tag-outline` icon by default and start with empty notes.
1435
+
1436
+ ```sh
1437
+ xy tag create --title "Production"
1438
+ xy tag create --id production --title "Production"
1439
+ xy tag create --title "High Priority" --icon alert-rhombus --notes "Needs attention"
1440
+ xy tag create --title "From JSON" --json @tag.json
1441
+ cat tag.json | xy tag create --json @-
1442
+ xy tag create --title "Preview" --dry
1443
+ ```
1444
+
1445
+ Supported creation fields are `id`, `title`, `icon`, and `notes`. Tag IDs contain lowercase letters, digits, and underscores. IDs beginning with an underscore are reserved for system Tags, so user-defined IDs should not use that prefix. Material Design icon names may be supplied with or without the `mdi-` prefix.
1446
+
1447
+ ## tag update
1448
+
1449
+ Update a Tag by exact ID. Omitted fields remain unchanged.
1450
+
1451
+ ```sh
1452
+ xy tag update TAG_ID --title "New Title"
1453
+ xy tag update TAG_ID --icon tag-heart-outline
1454
+ xy tag update TAG_ID --notes "Updated notes"
1455
+ xy tag update TAG_ID --icon '' --notes ''
1456
+ xy tag update TAG_ID --json @tag-update.json
1457
+ cat tag-update.json | xy tag update TAG_ID --json @-
1458
+ xy tag update TAG_ID --notes "Preview" --dry
1459
+ ```
1460
+
1461
+ Editable fields are `title`, `icon`, and `notes`. The Tag ID cannot be changed. Notes may contain multiple lines. `--dry` previews the changes, and `--format json` prints the updated Tag.
1462
+
1463
+ ## tag delete
1464
+
1465
+ Permanently delete a Tag by exact ID. Explicit confirmation is required.
1466
+
1467
+ ```sh
1468
+ xy tag delete TAG_ID
1469
+ xy tag delete --id TAG_ID
1470
+ xy tag delete TAG_ID --dry
1471
+ ```
1472
+
1473
+ Deletion cannot be undone. Existing Events, historical Jobs, Tickets, Actions, and Limits may still refer to the deleted Tag. `--dry` previews the deletion without making changes.
1474
+
1475
+ ## tickets
1476
+
1477
+ Search Tickets using the same search syntax as the xyOps web interface. A plain invocation lists all Tickets, newest first.
1478
+
1479
+ ```sh
1480
+ xy tickets
1481
+ xy tickets "backup failure"
1482
+ xy tickets 'subject:"release plan" status:open'
1483
+ xy tickets --status open --type issue
1484
+ xy tickets --assignee admin --tag important
1485
+ xy tickets --category Production --created today
1486
+ xy tickets --due '<today' --sort_dir asc
1487
+ xy tickets --limit 25 --page 2
1488
+ xy tickets --format json
1489
+ ```
1490
+
1491
+ Named search options include `subject`, `body`, `changes`, `status`, `username`, `assignees`, `cc`, `type`, `category`, `tags`, `created`, `due`, and `num`. Friendly aliases include `assignee`, `assign`, `tag`, `number`, and `date`. Category and Tag names may be supplied in place of IDs. Repeated or comma-separated values for one field are joined as alternatives.
1492
+
1493
+ Positional searches support quoted phrases, exclusions, alternatives, comparisons, and date ranges. Results show the newest Tickets first. Use `--sort_by FIELD` with `--sort_dir asc|desc` to change the order.
1494
+
1495
+ ## ticket
1496
+
1497
+ Work with one Ticket using its friendly number or internal ID. Ticket numbers are shown with a `#` prefix, while internal IDs begin with `t`.
1498
+
1499
+ ```sh
1500
+ xy ticket 12345
1501
+ xy ticket '#12345'
1502
+ xy ticket get --num 12345
1503
+ xy ticket get --id tabc123
1504
+ xy ticket create --subject "Investigate backup failure" --status draft
1505
+ xy ticket update 12345 close
1506
+ xy ticket 12345 --comment "Investigation started."
1507
+ xy ticket upload 12345 --file report.txt
1508
+ xy ticket download 12345 FILE_ID
1509
+ xy ticket delete 12345
1510
+ ```
1511
+
1512
+ Ticket numbers and internal IDs are accepted by all Ticket commands.
1513
+
1514
+ ## ticket list
1515
+
1516
+ Search Tickets using the same interface as `xy tickets`.
1517
+
1518
+ ```sh
1519
+ xy ticket list
1520
+ xy ticket list --status draft
1521
+ xy ticket search "database timeout" --tag important
1522
+ ```
1523
+
1524
+ ## ticket get
1525
+
1526
+ Display a Ticket summary with its number, internal ID, subject, status, type, assignments, due date, Tags, author, and timestamps. The Markdown body and each Markdown comment are rendered for the terminal. Attached Events, files, active Jobs, and completed Jobs are shown in separate sections.
1527
+
1528
+ ```sh
1529
+ xy ticket 12345
1530
+ xy ticket get 12345
1531
+ xy ticket get tabc123
1532
+ xy ticket 12345 --limit 10 --page 2
1533
+ xy ticket 12345 --format json
1534
+ ```
1535
+
1536
+ Pagination options apply to the completed Jobs attached to the Ticket. JSON output contains the complete Ticket.
1537
+
1538
+ ## ticket create
1539
+
1540
+ Create a Ticket with a required subject. Defaults match the web editor: status `open`, type `change`, no assignments, no due date, and empty body, category, server, recipient, and Tag fields.
1541
+
1542
+ ```sh
1543
+ xy ticket create --subject "Investigate backup failure"
1544
+ xy ticket create --subject "Draft release plan" --status draft --assign admin
1545
+ xy ticket create --subject "Maintenance" --type maintenance --due "3 days"
1546
+ xy ticket create --subject "Incident" --category Production --server host01
1547
+ xy ticket create --subject "Review" --assignees "admin,oncall" --cc manager
1548
+ xy ticket create --subject "External update" --notify "ops@example.com"
1549
+ xy ticket create --subject "Detailed Ticket" --body @ticket.md
1550
+ xy ticket create --subject "With files" --file report.txt --file metrics.json
1551
+ xy ticket create --json @ticket.json
1552
+ cat ticket.json | xy ticket create --json @-
1553
+ xy ticket create --subject "Preview" --status draft --dry
1554
+ ```
1555
+
1556
+ Supported fields are `id`, `subject`, `body`, `type`, `status`, `category`, `server`, `assignees`, `cc`, `notify`, `due`, and `tags`. Ticket types are `issue`, `feature`, `release`, `change`, `maintenance`, `question`, and `other`. Statuses are `draft`, `open`, and `closed`.
1557
+
1558
+ List fields accept JSON arrays, comma-separated strings, or repeated singular `--assign` and `--tag` options. The `body` is always treated as Markdown text, including JSON-looking content loaded from a `.json` file. A due date may be a Unix timestamp or a relative duration such as `3 days`.
1559
+
1560
+ Draft Tickets suppress email notifications. This is useful when composing a Ticket incrementally or creating test data.
1561
+
1562
+ ## ticket update
1563
+
1564
+ Update a Ticket using its number or internal ID. Omitted fields remain unchanged.
1565
+
1566
+ ```sh
1567
+ xy ticket update 12345 --subject "Updated subject"
1568
+ xy ticket update 12345 --body @ticket.md
1569
+ xy ticket update 12345 --status closed
1570
+ xy ticket update 12345 close
1571
+ xy ticket update 12345 open
1572
+ xy ticket update 12345 draft
1573
+ xy ticket update 12345 --assign admin
1574
+ xy ticket update 12345 --tag important
1575
+ xy ticket update 12345 --assignees '["admin","oncall"]'
1576
+ xy ticket update 12345 --tags "important,production"
1577
+ xy ticket update 12345 --due "1 week"
1578
+ xy ticket update 12345 --due 0
1579
+ xy ticket update 12345 --json @ticket-update.json
1580
+ xy ticket update 12345 --subject "Preview" --dry
1581
+ ```
1582
+
1583
+ The plain actions `close`, `open`, and `draft` set the corresponding status. `reopen` is also accepted as an alias for `open`. `--assign USERNAME` appends to the complete saved `assignees` array, and `--tag TAG_ID_OR_TITLE` appends to the saved `tags` array. Existing values are not duplicated. In contrast, `--assignees` and `--tags` replace their respective arrays completely.
1584
+
1585
+ Ticket Event assignments are read-only in the CLI. Use the xyOps web interface to edit them.
1586
+
1587
+ ## ticket comment
1588
+
1589
+ Add a Markdown comment to a Ticket. Comments may be supplied with the convenient detail shortcut or with the explicit command.
1590
+
1591
+ ```sh
1592
+ xy ticket 12345 --comment "Investigation started."
1593
+ xy ticket comment 12345 --body "**Resolved:** Restarted the service."
1594
+ xy ticket comment 12345 --body @comment.md
1595
+ cat comment.md | xy ticket comment 12345 --body @-
1596
+ xy ticket comment 12345 --body @comment.md --dry
1597
+ ```
1598
+
1599
+ Adding a comment can notify Ticket assignees and recipients unless the Ticket status is `draft`. Editing and deleting comments are not currently supported by the CLI.
1600
+
1601
+ ## ticket upload
1602
+
1603
+ Upload one or more files and save them as Ticket attachments. Both `--file` and `--files` may be repeated, and every local path must identify a regular file.
1604
+
1605
+ ```sh
1606
+ xy ticket upload 12345 --file report.txt
1607
+ xy ticket upload 12345 --file report.txt --file metrics.json
1608
+ xy ticket upload 12345 --files '["report.txt","metrics.json"]'
1609
+ xy ticket upload 12345 --file report.txt --dry
1610
+ ```
1611
+
1612
+ Attachment deletion is not currently supported by the CLI.
1613
+
1614
+ ## ticket download
1615
+
1616
+ Download one Ticket attachment to disk. Supply either the unique File ID shown by `ticket get`, or an exact filename. If a Ticket contains multiple attachments with the same filename, use the File ID to select one unambiguously.
1617
+
1618
+ ```sh
1619
+ xy ticket download 12345 FILE_ID
1620
+ xy ticket download 12345 report.txt
1621
+ xy ticket download 12345 FILE_ID ./downloads/report.txt
1622
+ xy ticket download 12345 FILE_ID --output ./report-copy.txt
1623
+ xy ticket download --id tabc123 --file FILE_ID --download ./report-copy.txt
1624
+ xy ticket download 12345 FILE_ID --dry
1625
+ ```
1626
+
1627
+ The output path defaults to the attachment's original filename in the current directory. The command refuses to overwrite an existing local file. A dry run shows the selected Ticket, attachment, and destination without writing anything.
1628
+
1629
+ ## ticket delete
1630
+
1631
+ Permanently delete a Ticket using its number or internal ID. Explicit confirmation is required.
1632
+
1633
+ ```sh
1634
+ xy ticket delete 12345
1635
+ xy ticket delete --id tabc123
1636
+ xy ticket delete 12345 --dry
1637
+ ```
1638
+
1639
+ Deletion cannot be undone. `--dry` previews the deletion without making changes.
1640
+
1641
+ ## hooks
1642
+
1643
+ List Web Hook definitions alphabetically by title. Search text matches IDs, titles, URLs, notes, and authors. Named filters may be combined.
1644
+
1645
+ ```sh
1646
+ xy hooks
1647
+ xy hooks SEARCH_TEXT
1648
+ xy hooks --enabled false
1649
+ xy hooks --method POST
1650
+ xy hooks --url example.com
1651
+ xy hooks --limit 10 --page 2
1652
+ xy hooks --format json
1653
+ ```
1654
+
1655
+ The table includes each Hook's ID, title, HTTP method, URL, status, and modification time. Use `--limit`, `--page`, or `--offset` to page through human-readable output. JSON output includes every matching Web Hook definition.
1656
+
1657
+ ## hook
1658
+
1659
+ Work with one Web Hook by viewing, creating, updating, testing, or deleting it. A bare ID or fuzzy title opens the Hook details directly. Updates, tests, and deletes require the exact internal Hook ID.
1660
+
1661
+ ```sh
1662
+ xy hook HOOK_ID_OR_TITLE
1663
+ xy hook get HOOK_ID_OR_TITLE
1664
+ xy hook list
1665
+ xy hook create --title "My Hook" --url https://example.com/hook
1666
+ xy hook update HOOK_ID --enabled false
1667
+ xy hook test HOOK_ID
1668
+ xy hook delete HOOK_ID
1669
+ ```
1670
+
1671
+ The configured API Key needs `create_web_hooks`, `edit_web_hooks`, or `delete_web_hooks` for the corresponding mutation. Testing requires `edit_web_hooks`. Listing and viewing Hooks only require a valid API Key.
1672
+
1673
+ ## hook list
1674
+
1675
+ List and filter Web Hook definitions using the same options as `xy hooks`.
1676
+
1677
+ ```sh
1678
+ xy hook list
1679
+ xy hook list SEARCH_TEXT
1680
+ xy hook list --enabled true --method POST
1681
+ xy hook list --limit 10 --page 2
1682
+ ```
1683
+
1684
+ ## hook get
1685
+
1686
+ View a Web Hook's request settings, headers, body, notes, author, dates, and revision. Exact IDs take precedence over fuzzy title matches.
1687
+
1688
+ ```sh
1689
+ xy hook HOOK_ID_OR_TITLE
1690
+ xy hook get --id HOOK_ID
1691
+ xy hook get --title "My Hook"
1692
+ xy hook HOOK_ID --format json
1693
+ xy hook HOOK_ID --export hook.json
1694
+ ```
1695
+
1696
+ ## hook create
1697
+
1698
+ Create a Web Hook with a required title and URL. New Hooks default to enabled with method `POST`, a 30-second timeout, no retries, no redirect following, normal TLS certificate verification, and an unlimited daily cap.
1699
+
1700
+ ```sh
1701
+ xy hook create --title "My Hook" --url https://example.com/hook
1702
+ xy hook create --id deploy_hook --title "Deploy" --url https://example.com/deploy --method POST
1703
+ xy hook create --title "JSON API" --url https://example.com/api --headers @headers.json --body @body.json
1704
+ xy hook create --title "Custom Header" --url https://example.com/api --header '{ "name":"Authorization", "value":"Bearer {{ secrets.API_TOKEN }}" }'
1705
+ xy hook create --title "From JSON" --json @hook.json
1706
+ cat hook.json | xy hook create --json @-
1707
+ xy hook create --title "Preview" --url https://example.com/hook --dry
1708
+ ```
1709
+
1710
+ Supported fields are `id`, `title`, `enabled`, `icon`, `url`, `method`, `headers`, `body`, `timeout`, `retries`, `follow`, `ssl_cert_bypass`, `max_per_day`, and `notes`. The URL must begin with `http://`, `https://`, or `{{` for a complete template expression. Methods are `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, and `DELETE`.
1711
+
1712
+ The default headers are `Content-Type: application/json` and `User-Agent: xyOps/WebHook`. Use `--headers '[]'` to start with no headers. A whole `headers` array replaces the default, while each `header` option appends one `{ "name", "value" }` object. Both options accept JSON files, and singular options may be repeated.
1713
+
1714
+ `timeout`, `retries`, and `max_per_day` are non-negative integers. A timeout of `0` waits indefinitely, and a daily cap of `0` is unlimited. `follow` and `ssl_cert_bypass` are booleans. TLS bypass is intended only for endpoints using self-signed certificates.
1715
+
1716
+ URLs, header values, and bodies may contain xyOps template expressions such as `{{ text }}` and `{{ secrets.API_TOKEN }}`. Assign the Secret Vault to the Web Hook before using a secret expression.
1717
+
1718
+ ## hook update
1719
+
1720
+ Update a Web Hook by exact ID. Omitted settings remain unchanged.
1721
+
1722
+ ```sh
1723
+ xy hook update HOOK_ID --title "New Title" --enabled false
1724
+ xy hook update HOOK_ID --url https://example.com/new --method PUT
1725
+ xy hook update HOOK_ID --timeout 60 --retries 2 --follow true
1726
+ xy hook update HOOK_ID --ssl_cert_bypass true --max_per_day 100
1727
+ xy hook update HOOK_ID --body @body.txt
1728
+ xy hook update HOOK_ID --headers '[{"name":"X-My-Name","value":"My Value"}]'
1729
+ xy hook update HOOK_ID --headers @headers.json
1730
+ xy hook update HOOK_ID --headers.0.name "X-New-Name" --headers.0.value "New Value"
1731
+ xy hook update HOOK_ID --header '{ "name":"X-Another", "value":"Another Value" }'
1732
+ xy hook update HOOK_ID --headers '[]'
1733
+ xy hook update HOOK_ID --json @hook-update.json
1734
+ cat hook-update.json | xy hook update HOOK_ID --json @-
1735
+ xy hook update HOOK_ID --timeout 60 --dry
1736
+ ```
1737
+
1738
+ A complete `headers` array replaces all saved headers. Dotted paths edit existing zero-based entries, and repeated `header` options append after replacement and dotted edits. Use `[]` to clear the list. Header names and values are checked using the same rules as the xyOps editor, including rejection of newline characters in values.
1739
+
1740
+ The Hook ID cannot be changed. `--dry` previews the changes, and `--format json` prints the updated Web Hook.
1741
+
1742
+ ## hook test
1743
+
1744
+ Perform a real HTTP request using a saved Web Hook and show a detailed report. Testing does not save changes to the Hook.
1745
+
1746
+ ```sh
1747
+ xy hook test HOOK_ID
1748
+ xy hook test HOOK_ID --timeout 10
1749
+ xy hook test HOOK_ID --url https://httpbin.org/post --method POST
1750
+ xy hook test HOOK_ID --headers @test-headers.json --body @test-body.json
1751
+ xy hook test HOOK_ID --format json
1752
+ xy hook test HOOK_ID --dry
1753
+ ```
1754
+
1755
+ Any supplied Hook fields apply only to the test. Without overrides, the saved definition is used exactly. `--dry` previews the test without contacting the destination.
1756
+
1757
+ The report includes the result, request, response, and performance metrics. Template expressions are expanded as they would be during a real execution. This can include decrypted Secret Vault values in request headers or bodies, so review terminal logging and redirection before testing a Hook that uses secrets. Use `--format json` for structured output.
1758
+
1759
+ ## hook delete
1760
+
1761
+ Permanently delete a Web Hook by exact ID. Explicit confirmation is required.
1762
+
1763
+ ```sh
1764
+ xy hook delete HOOK_ID
1765
+ xy hook delete --id HOOK_ID
1766
+ xy hook delete HOOK_ID --dry
1767
+ ```
1768
+
1769
+ Deletion cannot be undone. Events, workflows, Categories, server groups, Alerts, and Secret Vaults may still refer to the deleted Web Hook. `--dry` previews the deletion without making changes.
1770
+
1771
+ ## categories
1772
+
1773
+ List categories in their saved sort order, including IDs, titles, status, event counts, authors, and modification times. Search text matches IDs, titles, and notes. Named filters may be combined.
1774
+
1775
+ ```sh
1776
+ xy categories
1777
+ xy categories SEARCH_TEXT
1778
+ xy categories --enabled false
1779
+ xy categories --color blue
1780
+ xy categories --title Production --enabled true
1781
+ xy categories --limit 10 --page 2
1782
+ xy categories --format json
1783
+ ```
1784
+
1785
+ Use `--limit`, `--page`, or `--offset` to page through the table. JSON output includes all matching category definitions. Event counts reflect the events visible to your API Key.
1786
+
1787
+ ## category
1788
+
1789
+ View, create, update, or delete a category. A bare ID or fuzzy title opens its details. Updates and deletes require an exact category ID.
1790
+
1791
+ ```sh
1792
+ xy category CAT_ID_OR_TITLE
1793
+ xy category get CAT_ID_OR_TITLE
1794
+ xy category list
1795
+ xy category create --title "My Category" --notes "Hello"
1796
+ xy category update CAT_ID --enabled false
1797
+ xy category delete CAT_ID
1798
+ ```
1799
+
1800
+ ## category list
1801
+
1802
+ List and filter categories. This is an alias for `xy categories`, with the same options.
1803
+
1804
+ ```sh
1805
+ xy category list
1806
+ xy category list --enabled true
1807
+ xy category list --limit 10 --page 2
1808
+ ```
1809
+
1810
+ ## category get
1811
+
1812
+ View category metadata and its configured actions and limits. Each array row includes a zero-based index you can use in dotted updates. An exact ID takes precedence over fuzzy title matching.
1813
+
1814
+ ```sh
1815
+ xy category CAT_ID_OR_TITLE
1816
+ xy category get --id CAT_ID
1817
+ xy category get --title "My Category"
1818
+ xy category CAT_ID --format json
1819
+ xy category CAT_ID --export category.json
1820
+ xy events --category CAT_ID
1821
+ ```
1822
+
1823
+ The action and limit tables show the category's own settings. These apply to jobs belonging to the category alongside event settings and universal defaults.
1824
+
1825
+ ## category create
1826
+
1827
+ Create a category with a required title. New categories default to enabled, plain color, empty notes and icon, and empty action and limit arrays. xyOps generates an ID unless you provide `--id`, and places the category at the end of the saved sort order.
1828
+
1829
+ ```sh
1830
+ xy category create --title "My Category" --notes "Hello"
1831
+ xy category create --id maintenance --title "Maintenance" --enabled false
1832
+ xy category create --title "Production" --color blue --icon folder-outline
1833
+ xy category create --title "Notifications" --action '{ "type":"email", "enabled":true, "condition":"success", "users":["admin"] }'
1834
+ xy category create --title "Short Jobs" --limit '{ "type":"time", "enabled":true, "duration":300, "abort":true }'
1835
+ xy category create --title "Imported Settings" --actions @actions.json --limits @limits.json
1836
+ xy category create --json @category.json
1837
+ cat category.json | xy category create --json @-
1838
+ xy category create --title "Preview" --dry
1839
+ ```
1840
+
1841
+ Supported creation fields are `id`, `title`, `enabled`, `color`, `icon`, `notes`, `actions`, and `limits`. Common colors include `plain`, `red`, `orange`, `yellow`, `green`, `blue`, and `purple`. Set `color` to `false` in your CLI configuration to disable terminal colors (for example, `xy config --color false`). The category `--color` option sets the category color.
1842
+
1843
+ As with events, `--actions` and `--limits` supply complete JSON arrays, while `--action` and `--limit` append objects. Singular options can be repeated. Here `--limit` is a resource limit object, while list commands use it for pagination. Add `--format json` to print the created Category.
1844
+
1845
+ ## category update
1846
+
1847
+ Update a Category by exact ID. Omitted fields remain unchanged. Dotted updates preserve the other array entries and settings.
1848
+
1849
+ ```sh
1850
+ xy category update CAT_ID --title "New Title" --notes "Updated notes"
1851
+ xy category update CAT_ID --enabled false
1852
+ xy category update CAT_ID --color green --icon folder-outline
1853
+ xy category update CAT_ID --actions.0.condition complete --actions.0.enabled true
1854
+ xy category update CAT_ID --action '{ "type":"email", "enabled":true, "condition":"success", "users":["admin"] }'
1855
+ xy category update CAT_ID --limits.0.duration 600
1856
+ xy category update CAT_ID --limit '{ "type":"time", "enabled":true, "duration":300, "abort":true }'
1857
+ xy category update CAT_ID --actions @actions.json --limits @limits.json
1858
+ xy category update CAT_ID --actions '[]' --limits '[]'
1859
+ xy category update --id CAT_ID --sort_order 0
1860
+ xy category update CAT_ID --enabled false --dry
1861
+ ```
1862
+
1863
+ Editable fields are `title`, `enabled`, `color`, `icon`, `notes`, `sort_order`, `actions`, and `limits`. The ID cannot be changed. `sort_order` is a non-negative integer and does not renumber other Categories.
1864
+
1865
+ Numerical array indexes must already exist. Use the singular `--action` or `--limit` option to append, or the plural option to replace an entire array. Supply `[]` to clear an array; to remove one entry, submit a replacement array without it. When combining array replacement and dotted edits, the replacement is applied first, followed by dotted edits and then singular appends.
1866
+
1867
+ Disabling a Category prevents scheduling and manual launches for all its Events and workflows. `--dry` previews the changes. `--format json` prints the updated Category.
1868
+
1869
+ ## category delete
1870
+
1871
+ Permanently delete a category by exact ID. Explicit confirmation is required, and xyOps refuses deletion while any events or workflows still belong to the category. Move or delete those events first.
1872
+
1873
+ ```sh
1874
+ xy category delete CAT_ID
1875
+ xy category delete --id CAT_ID
1876
+ xy category delete CAT_ID --dry
1877
+ ```
1878
+
1879
+ `--dry` previews the deletion without making changes.
1880
+
1881
+ ## channels
1882
+
1883
+ List notification channels alphabetically by title, including IDs, status, subscribed-user counts, daily caps, and modification times. Search text matches IDs, titles, notes, and email recipients.
1884
+
1885
+ ```sh
1886
+ xy channels
1887
+ xy channels SEARCH_TEXT
1888
+ xy channels --enabled false
1889
+ xy channels --user admin
1890
+ xy channels --title Production --enabled true
1891
+ xy channels --limit 10 --page 2
1892
+ xy channels --format json
1893
+ ```
1894
+
1895
+ Named filters can be combined. `--user` matches a complete username; repeat it to require multiple subscribed users. `--limit`, `--page`, and `--offset` page through the table. JSON output includes all matching channel definitions.
1896
+
1897
+ ## channel
1898
+
1899
+ View, create, update, or delete a notification channel. A bare ID or fuzzy title opens its details. Updates and deletes require an exact channel ID.
1900
+
1901
+ ```sh
1902
+ xy channel CHANNEL_ID_OR_TITLE
1903
+ xy channel get CHANNEL_ID_OR_TITLE
1904
+ xy channel list
1905
+ xy channel create --title "Operations" --users admin
1906
+ xy channel update CHANNEL_ID --enabled false
1907
+ xy channel delete CHANNEL_ID
1908
+ ```
1909
+
1910
+ Channels bundle email recipients, in-app notifications, an optional web hook, and an optional follow-up event. They run when referenced by an event, category, or alert action. Creating or updating a channel only changes its configuration.
1911
+
1912
+ ## channel list
1913
+
1914
+ List and filter notification channels using the same options as `xy channels`.
1915
+
1916
+ ```sh
1917
+ xy channel list
1918
+ xy channel list --user admin --enabled true
1919
+ xy channel list --limit 10 --page 2
1920
+ ```
1921
+
1922
+ ## channel get
1923
+
1924
+ View a channel's recipients, web hook, follow-up event, sound, daily cap, notes, and revision metadata. Exact IDs take precedence over fuzzy title matches.
1925
+
1926
+ ```sh
1927
+ xy channel CHANNEL_ID_OR_TITLE
1928
+ xy channel get --id CHANNEL_ID
1929
+ xy channel get --title "Operations"
1930
+ xy channel CHANNEL_ID --format json
1931
+ xy channel CHANNEL_ID --export channel.json
1932
+ ```
1933
+
1934
+ ## channel create
1935
+
1936
+ Create a channel with a required title. Defaults are enabled, no recipients or follow-up actions, no sound, empty icon and notes, and an unlimited daily cap. xyOps generates the ID unless you supply `--id`.
1937
+
1938
+ ```sh
1939
+ xy channel create --title "Operations" --users admin
1940
+ xy channel create --title "On Call" --users 'admin,oncall' --email 'ops@example.com,sre@example.com'
1941
+ xy channel create --id production --title "Production" --user admin --user oncall
1942
+ xy channel create --title "Remediation" --web_hook WEB_HOOK_ID --run_event EVENT_ID
1943
+ xy channel create --title "Urgent" --users '["admin"]' --sound attention-3.mp3 --max_per_day 100
1944
+ xy channel create --title "Quiet" --enabled false --icon bullhorn-outline --notes "Staging notifications"
1945
+ xy channel create --json @channel.json
1946
+ cat channel.json | xy channel create --json @-
1947
+ xy channel create --title "Preview" --dry
1948
+ ```
1949
+
1950
+ Supported fields are `id`, `title`, `enabled`, `icon`, `users`, `email`, `web_hook`, `run_event`, `sound`, `max_per_day`, and `notes`. Use usernames in `users`, a comma-separated string for extra `email` recipients, and exact resource IDs for `web_hook` and `run_event`. `sound` is an optional `.mp3` filename available on your xyOps server.
1951
+
1952
+ `--users` accepts a JSON array, a comma-separated string, or `@users.json`. Repeated `--user USERNAME` options append subscribed users without duplicates. `max_per_day` must be a non-negative integer; `0` means unlimited. The daily cap resets at midnight in the server's time zone. Add `--format json` to print the created channel object.
1953
+
1954
+ To use the channel in a job or alert action:
1955
+
1956
+ ```sh
1957
+ xy event update EVENT_ID --action '{ "type":"channel", "enabled":true, "condition":"error", "channel_id":"CHANNEL_ID" }'
1958
+ xy alert update ALERT_ID --action '{ "type":"channel", "enabled":true, "condition":"alert_new", "channel_id":"CHANNEL_ID" }'
1959
+ ```
1960
+
1961
+ ## channel update
1962
+
1963
+ Update a Channel by exact ID. Omitted settings remain unchanged. The ID cannot be changed.
1964
+
1965
+ ```sh
1966
+ xy channel update CHANNEL_ID --title "Production Operations" --notes "On-call team"
1967
+ xy channel update CHANNEL_ID --enabled false
1968
+ xy channel update CHANNEL_ID --users '["admin","oncall"]'
1969
+ xy channel update CHANNEL_ID --user admin --user oncall
1970
+ xy channel update CHANNEL_ID --users.0 admin
1971
+ xy channel update CHANNEL_ID --max_per_day 50 --sound attention-3.mp3
1972
+ xy channel update CHANNEL_ID --email '' --web_hook '' --run_event '' --sound ''
1973
+ xy channel update CHANNEL_ID --users '[]'
1974
+ xy channel update --id CHANNEL_ID --json @changes.json
1975
+ xy channel update CHANNEL_ID --enabled false --dry
1976
+ ```
1977
+
1978
+ `--users` replaces the complete user list, `--user` appends users, and dotted paths edit existing zero-based array indexes. When combined, replacement runs first, then indexed edits, then appends. Use `[]` to clear the user list, or a replacement array to remove selected users. Empty strings clear optional text fields and notification targets.
1979
+
1980
+ Disabling a Channel causes actions that reference it to skip its notifications. `--dry` previews the changes, and `--format json` prints the updated Channel.
1981
+
1982
+ ## channel delete
1983
+
1984
+ Permanently delete a channel by exact ID. Explicit confirmation is required.
1985
+
1986
+ ```sh
1987
+ xy channel delete CHANNEL_ID
1988
+ xy channel delete --id CHANNEL_ID
1989
+ xy channel delete CHANNEL_ID --dry
1990
+ ```
1991
+
1992
+ Deletion does not remove references from Events, workflows, Categories, server groups, or Alerts. Update those actions when replacing a Channel. `--dry` previews the deletion without making changes.
1993
+
1994
+ ## monitors
1995
+
1996
+ List monitor definitions in their configured sort order, including IDs, titles, display settings, data types, server groups, and modification times. Search text matches IDs, titles, source expressions, and notes.
1997
+
1998
+ ```sh
1999
+ xy monitors
2000
+ xy monitors SEARCH_TEXT
2001
+ xy monitors --display false
2002
+ xy monitors --data_type bytes --delta true
2003
+ xy monitors --group GROUP_ID_OR_TITLE
2004
+ xy monitors --limit 10 --page 2
2005
+ xy monitors --format json
2006
+ ```
2007
+
2008
+ Named filters can be combined. `--group` includes monitors assigned to the selected group and monitors that apply to all groups. Boolean filters include `--display`, `--delta`, and `--divide_by_delta`. `--limit`, `--page`, and `--offset` page through the table. JSON output includes all matching definitions.
2009
+
2010
+ ## monitor
2011
+
2012
+ View, create, update, test, or delete a server monitor. A bare ID or fuzzy title opens its details. Updates and deletes require an exact monitor ID.
2013
+
2014
+ ```sh
2015
+ xy monitor MONITOR_ID_OR_TITLE
2016
+ xy monitor get MONITOR_ID_OR_TITLE
2017
+ xy monitor list
2018
+ xy monitor create --title "CPU Usage" --source cpu.currentLoad --suffix %
2019
+ xy monitor update MONITOR_ID --display false
2020
+ xy monitor test MONITOR_ID_OR_TITLE --server SERVER_ID_OR_TITLE
2021
+ xy monitor delete MONITOR_ID
2022
+ ```
2023
+
2024
+ Monitors extract numeric metrics from server data using xyOps expressions. `display` controls visibility in the web interface; hiding a monitor does not stop collection or prevent alerts from using its values.
2025
+
2026
+ ## monitor list
2027
+
2028
+ List and filter monitor definitions using the same options as `xy monitors`.
2029
+
2030
+ ```sh
2031
+ xy monitor list
2032
+ xy monitor list --display true --data_type float
2033
+ xy monitor list --limit 10 --page 2
2034
+ ```
2035
+
2036
+ ## monitor get
2037
+
2038
+ View a monitor's source expression, data type, regular expression, delta settings, server groups, display settings, notes, and revision metadata. Exact IDs take precedence over fuzzy titles.
2039
+
2040
+ ```sh
2041
+ xy monitor MONITOR_ID_OR_TITLE
2042
+ xy monitor get --id MONITOR_ID
2043
+ xy monitor get --title "CPU Usage"
2044
+ xy monitor MONITOR_ID --format json
2045
+ xy monitor MONITOR_ID --export monitor.json
2046
+ ```
2047
+
2048
+ ## monitor create
2049
+
2050
+ Create a monitor with a required title and source expression. Defaults are `float` data, visible display, all server groups, no delta processing, and empty suffix, regular expression, icon, and notes. xyOps generates the ID unless you supply `--id`, and places the monitor at the end of the list.
2051
+
2052
+ ```sh
2053
+ xy monitor create --title "CPU Usage" --source cpu.currentLoad --suffix % --min_vert_scale 100
2054
+ xy monitor create --id free_memory --title "Free Memory" --source memory.available --data_type bytes
2055
+ xy monitor create --title "Network Bytes per Second" --source stats.network.rx_bytes --data_type bytes --delta true --divide_by_delta true --delta_min_value 0
2056
+ xy monitor create --title "Process Count" --source processes.all --data_type integer --groups '["GROUP_ID"]'
2057
+ xy monitor create --title "Hidden Metric" --source cpu.currentLoad --display false --notes "Used by alerts"
2058
+ xy monitor create --json @monitor.json
2059
+ cat monitor.json | xy monitor create --json @-
2060
+ xy monitor create --title "Preview" --source cpu.currentLoad --dry
2061
+ ```
2062
+
2063
+ Supported fields are `id`, `title`, `source`, `data_type`, `data_match`, `display`, `icon`, `groups`, `suffix`, `min_vert_scale`, `delta`, `divide_by_delta`, `delta_min_value`, and `notes`.
2064
+
2065
+ `source` is an xyOps expression evaluated against server data. `data_type` is one of `integer`, `float`, `bytes`, `seconds`, or `milliseconds`. Optional `data_match` is a JavaScript regular expression string; its first capture group, or the whole match if there are no captures, supplies the numeric value. Use `xy monitor test` to check an expression against a server before saving it.
2066
+
2067
+ `--groups` accepts a JSON array, comma-separated group IDs, or `@groups.json`. Repeated `--group GROUP_ID` options append groups without duplicates. An empty array means all groups.
2068
+
2069
+ `--delta true` tracks changes between samples. `--divide_by_delta true` divides those changes by elapsed seconds. `--delta_min_value 0` clamps negative changes to zero; `--delta_min_value false` disables the minimum. Other numeric minimums are also accepted. `min_vert_scale` is a non-negative minimum chart range and defaults to `0`, or `1` for integer monitors. Add `--format json` to print the created monitor object.
2070
+
2071
+ ## monitor update
2072
+
2073
+ Update a Monitor by exact ID. Omitted settings remain unchanged. The ID cannot be changed.
2074
+
2075
+ ```sh
2076
+ xy monitor update MONITOR_ID --title "Production CPU" --notes "Primary load metric"
2077
+ xy monitor update MONITOR_ID --source cpu.currentLoad --data_type float --suffix %
2078
+ xy monitor update MONITOR_ID --display false
2079
+ xy monitor update MONITOR_ID --delta true --divide_by_delta true --delta_min_value 0
2080
+ xy monitor update MONITOR_ID --delta_min_value false
2081
+ xy monitor update MONITOR_ID --groups '["GROUP_ID"]'
2082
+ xy monitor update MONITOR_ID --group GROUP_ID --group ANOTHER_GROUP_ID
2083
+ xy monitor update MONITOR_ID --groups.0 GROUP_ID
2084
+ xy monitor update MONITOR_ID --groups '[]' --data_match '' --suffix ''
2085
+ xy monitor update MONITOR_ID --sort_order 1
2086
+ xy monitor update --id MONITOR_ID --json @changes.json
2087
+ xy monitor update MONITOR_ID --display false --dry
2088
+ ```
2089
+
2090
+ The editable fields are the same as create, and `sort_order` can be set to an integer to change the Monitor's position. Lower sort orders appear first. Supply negative numbers through a JSON file or standard input. A whole `--groups` list replaces the saved list, dotted paths edit existing indexes, and repeated `--group` options append IDs afterward. Use `--groups '[]'` to apply the Monitor to all groups.
2091
+
2092
+ `--dry` previews the changes, and `--format json` prints the updated Monitor.
2093
+
2094
+ ## monitor test
2095
+
2096
+ Evaluate a saved monitor or an unsaved expression against a server's current data, without changing the monitor. Select a server by exact ID or fuzzy title, hostname, or IP address. Saved monitors support ID or fuzzy title lookup, with optional source, data type, and regular expression overrides.
2097
+
2098
+ ```sh
2099
+ xy monitor test MONITOR_ID_OR_TITLE --server SERVER_ID_OR_TITLE
2100
+ xy monitor test --id MONITOR_ID --server SERVER_ID --source cpu.currentLoad
2101
+ xy monitor test --server SERVER_ID_OR_TITLE --source cpu.currentLoad --data_type float
2102
+ xy monitor test --server SERVER_ID --source '"42 workers"' --data_match '(\d+)' --data_type integer
2103
+ xy monitor test MONITOR_ID --server SERVER_ID --data_match '' --format json
2104
+ xy monitor test --server SERVER_ID --source '1 + 2' --dry
2105
+ ```
2106
+
2107
+ An unsaved expression defaults to `float`. Tests evaluate the source, apply `data_match` if set, and convert the result to the selected data type. They do not calculate changes between samples or apply delta settings. A successful zero is displayed as `0`; an expression that cannot be evaluated displays `No Value`. Invalid expressions and unmatched regular expressions are reported as errors.
2108
+
2109
+ JSON output includes the calculated value or failure status. Testing requires the `edit_monitors` privilege.
2110
+
2111
+ ## monitor delete
2112
+
2113
+ Permanently delete a monitor by exact ID. Explicit confirmation is required.
2114
+
2115
+ ```sh
2116
+ xy monitor delete MONITOR_ID
2117
+ xy monitor delete --id MONITOR_ID
2118
+ xy monitor delete MONITOR_ID --dry
2119
+ ```
2120
+
2121
+ Review any Alert expressions that refer to the Monitor before deleting it. `--dry` previews the deletion without making changes.
2122
+
2123
+ ## marketplace
2124
+
2125
+ Search the xyOps Plugin Marketplace. The Marketplace currently contains Plugins for Events, Monitors, Actions, and Schedulers.
2126
+
2127
+ ```sh
2128
+ xy marketplace
2129
+ xy marketplace AI
2130
+ xy marketplace search backup
2131
+ xy marketplace --plugin_type event
2132
+ xy marketplace --author PixlCore
2133
+ xy marketplace --license MIT --requires npx
2134
+ xy marketplace --tags AI,Prompt
2135
+ xy marketplace --status installed
2136
+ xy marketplace --status not
2137
+ xy marketplace --sort_by modified --sort_dir desc
2138
+ xy marketplace --limit 10 --page 2
2139
+ xy marketplace --format json
2140
+ ```
2141
+
2142
+ Positional text or `--query` searches titles, descriptions, IDs, licenses, tags, and requirements. Plugin types are `event`, `monitor`, `action`, and `scheduler`. The `tags` and `requires` filters accept comma-separated values or repeated options, and all selected values must match. Status is either `installed` or `not`.
2143
+
2144
+ Sort fields are `title`, `author`, `license`, `plugin_type`, `created`, and `modified`; sort direction is `asc` or `desc`. JSON output contains the current page of Marketplace results.
2145
+
2146
+ ## marketplace list
2147
+
2148
+ List Marketplace Plugins using the same filters and pagination options as `xy marketplace`.
2149
+
2150
+ ```sh
2151
+ xy marketplace list
2152
+ xy marketplace list --plugin_type monitor
2153
+ xy marketplace list --status installed
2154
+ ```
2155
+
2156
+ ## marketplace search
2157
+
2158
+ Search Marketplace Plugins using the same filters and pagination options as `xy marketplace`.
2159
+
2160
+ ```sh
2161
+ xy marketplace search AI
2162
+ xy marketplace search backup --requires npx
2163
+ xy marketplace search --query notification --license MIT
2164
+ ```
2165
+
2166
+ ## marketplace get
2167
+
2168
+ View one Marketplace Plugin by its exact `AUTHOR/REPO` ID. The detail view includes listing metadata, installation status, available versions, requirements, tags, and the complete README rendered for the terminal. Images are omitted because terminals cannot display them.
2169
+
2170
+ ```sh
2171
+ xy marketplace pixlcore/xyplug-ai
2172
+ xy marketplace get pixlcore/xyplug-ai
2173
+ xy marketplace get pixlcore/xyplug-ai --version v1.0.9
2174
+ xy marketplace get --id pixlcore/xyplug-ai
2175
+ xy marketplace pixlcore/xyplug-ai --format json
2176
+ ```
2177
+
2178
+ The latest published version is shown by default. Use `--version` to read an older published version. Use `--format json` for the complete listing details and original README Markdown.
2179
+
2180
+ ## marketplace install
2181
+
2182
+ Preview and install one Marketplace Plugin by its exact `AUTHOR/REPO` ID. The preview shows the Plugin definition and displays embedded scripts separately with syntax highlighting. **No Plugin is installed or upgraded until you add `--confirm`.**
2183
+
2184
+ ```sh
2185
+ xy marketplace install pixlcore/xyplug-ai
2186
+ xy marketplace install pixlcore/xyplug-ai --version v1.0.9
2187
+ xy marketplace install pixlcore/xyplug-ai --dry
2188
+ xy marketplace install pixlcore/xyplug-ai --format json
2189
+ ```
2190
+
2191
+ The preview verifies that the package is compatible and explains whether it will install a new Plugin or upgrade an existing one. It also warns if the matching Plugin ID belongs to a local Plugin from another source. Use `--format json` for a structured preview.
2192
+
2193
+ Installation requires permission to create or update Plugins. The command does not execute or test the Plugin. Review its README, requirements, source repository, embedded script, and parameter definitions before confirming installation.
2194
+
2195
+ ## plugins
2196
+
2197
+ List Plugin definitions alphabetically by title, including IDs, types, status, parameter counts, and modification times. Search text matches IDs, titles, executable commands, scripts, and notes.
2198
+
2199
+ ```sh
2200
+ xy plugins
2201
+ xy plugins SEARCH_TEXT
2202
+ xy plugins --type event
2203
+ xy plugins --type monitor --enabled true
2204
+ xy plugins --enabled false
2205
+ xy plugins --limit 10 --page 2
2206
+ xy plugins --format json
2207
+ ```
2208
+
2209
+ Supported Plugin types are `event`, `monitor`, `action`, and `scheduler`. Named filters can be combined. `--limit`, `--page`, and `--offset` page through the table. JSON output includes all matching Plugin definitions.
2210
+
2211
+ ## plugin
2212
+
2213
+ View, create, update, or delete a Plugin. A bare ID or fuzzy title opens its details. Updates and deletes require an exact Plugin ID.
2214
+
2215
+ ```sh
2216
+ xy plugin PLUGIN_ID_OR_TITLE
2217
+ xy plugin get PLUGIN_ID_OR_TITLE
2218
+ xy plugin list
2219
+ xy plugin create --title "My Plugin" --type event --command node --script @plugin.js
2220
+ xy plugin update PLUGIN_ID --enabled false
2221
+ xy plugin delete PLUGIN_ID
2222
+ ```
2223
+
2224
+ xyOps supports four kinds of Plugin. Event Plugins run jobs, Monitor Plugins gather server metrics, Action Plugins respond to job or alert conditions, and Scheduler Plugins provide custom scheduling decisions.
2225
+
2226
+ ## plugin list
2227
+
2228
+ List and filter Plugin definitions using the same options as `xy plugins`.
2229
+
2230
+ ```sh
2231
+ xy plugin list
2232
+ xy plugin list --type action --enabled true
2233
+ xy plugin list --limit 10 --page 2
2234
+ ```
2235
+
2236
+ ## plugin get
2237
+
2238
+ View a Plugin's executable, script summary, type-specific settings, notes, source, and revision metadata. Non-monitor Plugins also show their parameter definitions. Exact IDs take precedence over fuzzy title matches.
2239
+
2240
+ ```sh
2241
+ xy plugin PLUGIN_ID_OR_TITLE
2242
+ xy plugin get --id PLUGIN_ID
2243
+ xy plugin get --title "My Plugin"
2244
+ xy plugin PLUGIN_ID --format json
2245
+ xy plugin PLUGIN_ID --verbose
2246
+ xy plugin PLUGIN_ID --export plugin.json
2247
+ ```
2248
+
2249
+ Normal output summarizes the embedded script without printing its contents. Add `--verbose` to display the complete syntax-highlighted script and expanded values for code, textarea, and JSON parameter defaults.
2250
+
2251
+ ## plugin create
2252
+
2253
+ Create an Event, Monitor, Action, or Scheduler Plugin. Every Plugin requires a title, type, and executable command. The default type is `event`, so `--type event` may be omitted. xyOps generates an ID unless you supply `--id`.
2254
+
2255
+ ```sh
2256
+ xy plugin create --title "My Event Plugin" --type event --command node --script @plugin.js
2257
+ xy plugin create --id cleanup --title "Cleanup" --command /bin/sh --script @cleanup.sh
2258
+ xy plugin create --title "Remote Runner" --type event --command node --runner true --kill all
2259
+ xy plugin create --title "CPU Sensor" --type monitor --command /bin/sh --script @sensor.sh --plugin_format json --groups '["GROUP_ID"]'
2260
+ xy plugin create --title "Fast Sensor" --type monitor --command node --quick true --group GROUP_ID
2261
+ xy plugin create --title "Notify Service" --type action --command python3 --script @notify.py
2262
+ xy plugin create --title "Business Calendar" --type scheduler --command node --script @calendar.js
2263
+ xy plugin create --title "Parameterized" --command node --param '{ "id":"name", "title":"Name", "type":"text", "value":"World" }'
2264
+ xy plugin create --title "Imported Parameters" --command node --params @params.json
2265
+ xy plugin create --json @plugin.json
2266
+ cat plugin.json | xy plugin create --json @-
2267
+ xy plugin create --title "Preview" --command node --dry
2268
+ ```
2269
+
2270
+ Common fields are `id`, `title`, `enabled`, `type`, `icon`, `command`, `script`, `uid`, `gid`, and `notes`. Use `--script @FILE` for source code or `--script @-` to read it from standard input. `command` contains the executable and optional arguments, without pipes or redirects. `uid` and `gid` select the Unix account used to run the process when supported.
2271
+
2272
+ Event Plugins also accept `kill` with `none`, `parent`, or `all`, plus the `runner` boolean for remote job runners. Monitor Plugins accept `groups`, `plugin_format`, and `quick`; `plugin_format` is `text`, `json`, or `xml`, an empty group list means all groups, and `quick` also runs the Plugin through QuickMon every second. When loading a complete Plugin definition with `--json`, use `format` instead of `plugin_format`. Action and Scheduler Plugins use the common fields and may define parameters.
2273
+
2274
+ Non-monitor Plugins accept parameter definitions through `params` and `param`. `--params` supplies the complete JSON array, while each `--param` appends one object. Supported parameter types are `text`, `textarea`, `code`, `json`, `checkbox`, `select`, `bucket`, `system`, `hidden`, `toolset`, and `group`. Add `--format json` to print the created Plugin.
2275
+
2276
+ ## plugin update
2277
+
2278
+ Update a Plugin by exact ID. Omitted settings remain unchanged. A Plugin's ID and type cannot be changed after creation.
2279
+
2280
+ ```sh
2281
+ xy plugin update PLUGIN_ID --title "New Title" --notes "Updated notes"
2282
+ xy plugin update PLUGIN_ID --enabled false
2283
+ xy plugin update PLUGIN_ID --command node --script @plugin.js
2284
+ xy plugin update PLUGIN_ID --uid worker --gid workers
2285
+ xy plugin update PLUGIN_ID --params @params.json
2286
+ cat params.json | xy plugin update PLUGIN_ID --params @-
2287
+ xy plugin update PLUGIN_ID --param '{ "id":"foo", "title":"Foo", "type":"text", "value":"hello" }'
2288
+ xy plugin update PLUGIN_ID --params.0.title "New Parameter Title"
2289
+ xy plugin update PLUGIN_ID --params.0.required true
2290
+ xy plugin update PLUGIN_ID --params '[]'
2291
+ xy plugin update EVENT_PLUGIN_ID --kill parent --runner false
2292
+ xy plugin update MONITOR_PLUGIN_ID --groups '["GROUP_ID"]' --plugin_format json --quick true
2293
+ xy plugin update MONITOR_PLUGIN_ID --group GROUP_ID --group ANOTHER_GROUP_ID
2294
+ xy plugin update MONITOR_PLUGIN_ID --groups.0 GROUP_ID
2295
+ xy plugin update PLUGIN_ID --enabled false --dry
2296
+ ```
2297
+
2298
+ For non-monitor Plugins, a whole `--params` array replaces all parameter definitions, dotted paths edit existing zero-based indexes, and repeated `--param` options append definitions afterward. Use `[]` to clear the list or submit a replacement array without an item to remove it. When the options are combined, replacement happens first, followed by dotted edits and appends.
2299
+
2300
+ For Monitor Plugins, `--groups` replaces the complete server-group list, dotted paths edit existing indexes, and repeated `--group` options append IDs without duplicates. Monitor Plugins do not support parameter definitions, and other Plugin types do not support monitor-only settings. `--dry` previews the changes, and `--format json` prints the updated Plugin.
2301
+
2302
+ ## plugin delete
2303
+
2304
+ Permanently delete a Plugin by exact ID. Explicit confirmation is required.
2305
+
2306
+ ```sh
2307
+ xy plugin delete PLUGIN_ID
2308
+ xy plugin delete --id PLUGIN_ID
2309
+ xy plugin delete PLUGIN_ID --dry
2310
+ ```
2311
+
2312
+ Before deleting a Plugin, review Events, workflows, Monitors, triggers, and Actions that may reference it. Deletion does not remove those references. `--dry` previews the deletion without making changes.
2313
+
2314
+ ## events
2315
+
2316
+ List all events or narrow the collection using fuzzy names, titles, categories, plugins, and targets. Filters may be combined to find exactly the events you need.
2317
+
2318
+ ```sh
2319
+ xy events
2320
+ xy events SEARCH_TEXT
2321
+ xy events --category ID_OR_TITLE
2322
+ xy events --plugin ID_OR_TITLE
2323
+ xy events --target ID_OR_TITLE
2324
+ xy events --category ID_OR_TITLE --plugin ID_OR_TITLE
2325
+ ```
2326
+
2327
+ `SEARCH_TEXT` performs a fuzzy title search. `--target` accepts either a server group or an individual server.
2328
+
2329
+ ## event
2330
+
2331
+ View, create, update, delete, or run an Event. A bare ID or title opens the Event details directly.
2332
+
2333
+ ```sh
2334
+ xy event ID_OR_TITLE
2335
+ xy event get ID_OR_TITLE
2336
+ xy event create --title "My Event" --plugin testplug
2337
+ xy event update EVENT_ID --enabled false
2338
+ xy event delete EVENT_ID
2339
+ xy event run ID_OR_TITLE
2340
+ ```
2341
+
2342
+ ## event get
2343
+
2344
+ View the configuration and current activity for a single event. Optional switches can focus the output on queued, upcoming, or completed jobs for that event.
2345
+
2346
+ ```sh
2347
+ xy event ID_OR_TITLE
2348
+ xy event get ID_OR_TITLE
2349
+ xy event ID_OR_TITLE --queued
2350
+ xy event ID_OR_TITLE --upcoming
2351
+ xy event ID_OR_TITLE --completed
2352
+ xy event ID_OR_TITLE --export event.json
2353
+ xy event ID_OR_TITLE --export event.json --deps all
2354
+ ```
2355
+
2356
+ `xy event ID_OR_TITLE` is the short form of `xy event get ID_OR_TITLE`. See `xy help export` for XYPDF export options and dependency selection.
2357
+
2358
+ ## event create
2359
+
2360
+ Create a new event from command-line options, with sensible defaults filled in where possible. Convenience options make it easy to add common triggers without constructing the complete event object yourself.
2361
+
2362
+ ```sh
2363
+ xy event create --title "Foo" --plugin testplug --params.duration 30
2364
+ xy event create --title "Script" --plugin shellplug --params.script @script.sh
2365
+ xy event create --title "Daily" --cron "30 4 * * *" --seconds 15
2366
+ xy event create --title "Interval" --interval "5 minutes" --catchup
2367
+ xy event create --title "Preview" --plugin testplug --dry
2368
+ ```
2369
+
2370
+ Default Category, Plugin, target, and algorithm values are used where possible. Dotted options set nested values, while `--cron`, `--interval`, `--seconds`, and `--catchup` add common triggers.
2371
+
2372
+ ## event update
2373
+
2374
+ Update an existing event using an ID or fuzzy title, with support for both ordinary properties and deeply nested values. You can also append common event objects using their singular convenience options.
2375
+
2376
+ ```sh
2377
+ xy event update EVENT_ID --title "New Title"
2378
+ xy event update EVENT_ID --params.duration 15
2379
+ xy event update EVENT_ID --actions.0.condition complete --actions.0.enabled true
2380
+ xy event update EVENT_ID --action '{ "type":"email", "enabled":true, "condition":"success", "users":["admin"] }'
2381
+ xy event update EVENT_ID --field '{ "id":"foo", "title":"Foo", "type":"text", "value":"hello" }'
2382
+ xy event update EVENT_ID --magic
2383
+ xy event update EVENT_ID --enabled false --dry
2384
+ ```
2385
+
2386
+ Dotted options preserve other settings, and numerical array indexes must already exist. The singular `--action`, `--trigger`, `--limit`, and `--field` options append new objects to their corresponding arrays.
2387
+
2388
+ ## event delete
2389
+
2390
+ Permanently delete an event using its exact ID. The command requires explicit confirmation and can optionally remove the event's historical jobs in the background.
2391
+
2392
+ ```sh
2393
+ xy event delete EVENT_ID
2394
+ xy event delete EVENT_ID --delete_jobs
2395
+ xy event delete EVENT_ID --dry
2396
+ ```
2397
+
2398
+ Deletion is blocked while the Event has active Jobs. Use `--dry` to preview the deletion without making changes.
2399
+
2400
+ ## event run
2401
+
2402
+ Launch an event on demand, optionally overriding parameters, attaching files, or providing input data. Add `--follow` to stream the resulting job until it completes.
2403
+
2404
+ ```sh
2405
+ xy run ID_OR_TITLE
2406
+ xy event run ID_OR_TITLE
2407
+ xy run ID_OR_TITLE --follow
2408
+ xy run ID_OR_TITLE --dry
2409
+ xy run ID_OR_TITLE --file ./input.txt
2410
+ xy run ID_OR_TITLE --file ./one.txt --file ./two.txt
2411
+ xy run ID_OR_TITLE --params.example VALUE
2412
+ xy run ID_OR_TITLE --input.data.example VALUE
2413
+ xy run ID_OR_TITLE --actions @my-actions.json
2414
+ cat request.json | xy run ID_OR_TITLE --json @-
2415
+ ```
2416
+
2417
+ `xy run` is the short form of `xy event run`. Extra options temporarily override the saved Event settings, and dotted option names set nested values.
2418
+
2419
+ ## run
2420
+
2421
+ Run an event on demand using the short top-level command. It accepts the same event selector, overrides, files, input data, dry-run mode, and follow mode as `xy event run`.
2422
+
2423
+ ```sh
2424
+ xy run ID_OR_TITLE
2425
+ xy run ID_OR_TITLE --params.example VALUE
2426
+ xy run ID_OR_TITLE --file ./input.txt
2427
+ xy run ID_OR_TITLE --follow
2428
+ xy run ID_OR_TITLE --dry
2429
+ ```
2430
+
2431
+ ## jobs
2432
+
2433
+ Show active jobs and search recent completed jobs using either structured filters or the raw xyOps job-search syntax. With no filters, the command displays active jobs followed by recent completed jobs.
2434
+
2435
+ ```sh
2436
+ xy jobs
2437
+ xy jobs RAW_SEARCH_QUERY
2438
+ xy jobs upcoming
2439
+ xy jobs --upcoming
2440
+ xy jobs --success
2441
+ xy jobs --error --date today
2442
+ xy jobs --workflows
2443
+ xy jobs --category ID_OR_TITLE
2444
+ xy jobs --event ID_OR_TITLE --date yesterday
2445
+ ```
2446
+
2447
+ Common filters:
2448
+
2449
+ | Option | Matches |
2450
+ | --- | --- |
2451
+ | `--event ID_OR_TITLE` | Event |
2452
+ | `--category ID_OR_TITLE` | Category |
2453
+ | `--plugin ID_OR_TITLE` | Plugin |
2454
+ | `--server ID_OR_TITLE` | Server ID, title, hostname, or IP address |
2455
+ | `--group ID_OR_TITLE` | Server group |
2456
+ | `--tag ID_OR_TITLE` | Tag |
2457
+ | `--success` | Successful jobs |
2458
+ | `--error` | Failed jobs |
2459
+ | `--files` | Jobs with attached files |
2460
+ | `--warning` | Warning result code |
2461
+ | `--critical` | Critical result code |
2462
+ | `--abort` | Aborted jobs |
2463
+ | `--workflow` or `--workflows` | Workflow jobs |
2464
+ | `--date RANGE` | Completion date or date expression |
2465
+
2466
+ Built-in date ranges are `now`, `hour`, `lasthour`, `today`, `yesterday`, `month`, `lastmonth`, `year`, `lastyear`, and `older`.
2467
+
2468
+ ## job
2469
+
2470
+ Work with one job by viewing, streaming, rerunning, resuming, aborting, deleting, or downloading its output. A bare job ID automatically chooses the live stream or completed report based on the job's current state.
2471
+
2472
+ ```sh
2473
+ xy job JOB_ID
2474
+ xy job get JOB_ID
2475
+ xy job stream JOB_ID
2476
+ xy job log JOB_ID
2477
+ xy job run JOB_ID --follow
2478
+ xy job resume JOB_ID
2479
+ xy job abort JOB_ID
2480
+ xy job delete JOB_ID
2481
+ ```
2482
+
2483
+ ## job get
2484
+
2485
+ View a job in its current state using either the short or explicit form. Active jobs automatically switch to streaming, while completed jobs display their full report.
2486
+
2487
+ ```sh
2488
+ xy job JOB_ID
2489
+ xy job get JOB_ID
2490
+ xy job JOB_ID --verbose
2491
+ xy job JOB_ID --format json
2492
+ ```
2493
+
2494
+ ## job stream
2495
+
2496
+ Stream the live status and output of an active job until it completes. If the job has already completed, the command automatically displays its completed report instead.
2497
+
2498
+ ```sh
2499
+ xy job stream JOB_ID
2500
+ ```
2501
+
2502
+ ## job log
2503
+
2504
+ Print the raw output log for a job or download it directly to a file. This is useful when the job report only shows an output summary or when another tool needs the unformatted log.
2505
+
2506
+ ```sh
2507
+ xy job log JOB_ID
2508
+ xy job log JOB_ID --download JOB_ID.log
2509
+ ```
2510
+
2511
+ ## job run
2512
+
2513
+ Rerun a completed, Event-backed Job using its previous settings. Add `--follow` to stream the new Job, or use `--dry` to preview the rerun first.
2514
+
2515
+ ```sh
2516
+ xy job run JOB_ID
2517
+ xy job run JOB_ID --follow
2518
+ xy job run JOB_ID --dry
2519
+ ```
2520
+
2521
+ Ad hoc jobs and ad hoc workflow sub-jobs cannot be rerun independently.
2522
+
2523
+ ## job resume
2524
+
2525
+ Resume a suspended active Job, optionally providing new parameter or input values. Use dotted options for nested values.
2526
+
2527
+ ```sh
2528
+ xy job resume JOB_ID
2529
+ xy job resume JOB_ID --params.example VALUE
2530
+ xy job resume JOB_ID --input.data.example VALUE
2531
+ xy job resume JOB_ID --dry
2532
+ ```
2533
+
2534
+ ## job abort
2535
+
2536
+ Abort an active Job that should no longer continue running. Use `--dry` to preview the action without interrupting the Job.
2537
+
2538
+ ```sh
2539
+ xy job abort JOB_ID
2540
+ xy job abort JOB_ID --dry
2541
+ ```
2542
+
2543
+ ## job delete
2544
+
2545
+ Permanently delete a completed job, including its stored output and attached files. Active jobs must be aborted and allowed to finish before they can be deleted.
2546
+
2547
+ ```sh
2548
+ xy job delete JOB_ID
2549
+ xy job delete JOB_ID --dry
2550
+ ```
2551
+
2552
+ ## log
2553
+
2554
+ Search current or archived xyOps system logs. This command requires an administrator API Key. The log name defaults to `xyOps`, and the row limit defaults to **100**.
2555
+
2556
+ ```sh
2557
+ xy log
2558
+ xy log xyOps --rows 100 --format json
2559
+ xy log xyOps --match "error"
2560
+ xy log xyOps --match "ERROR" --case
2561
+ xy log xyOps --match "error|warning" --regex
2562
+ xy log xyOps --cols hires_epoch,component,category,code,msg
2563
+ xy log xyOps --cols '["msg","data"]' --format json
2564
+ xy log xyOps --date 2026-09-04 --rows 100
2565
+ xy log xyOps --sort date_desc
2566
+ xy log --log xyOps --match "timeout" --dry
2567
+ ```
2568
+
2569
+ | Option | Description |
2570
+ | --- | --- |
2571
+ | `--rows N` | Return the last N matching rows, from 1 to 1000. Defaults to 100. |
2572
+ | `--match TEXT` | Search complete log lines for literal text. Omit to match all rows. |
2573
+ | `--regex` | Interpret `--match` as a regular expression. |
2574
+ | `--case` | Match case sensitively. Searches are case insensitive by default. |
2575
+ | `--cols LIST` | Select columns using comma-separated names or a JSON array. |
2576
+ | `--date YYYY-MM-DD` | Search the archive for a day in the server's time zone. Omit to search the current live log. |
2577
+ | `--sort date_asc` | Show the returned rows in file order, oldest first (the default). |
2578
+ | `--sort date_desc` | Reverse the returned rows to show newest first. |
2579
+ | `--format json` | Print the matching row objects as a JSON array. |
2580
+
2581
+ Specify the log's base filename without its extension, such as `xyOps`. Standard column IDs are `hires_epoch`, `date`, `hostname`, `pid`, `component`, `category`, `code`, `msg`, and `data`; available columns follow your server configuration.
2582
+
2583
+ Default output shows complete bracket-delimited log lines using the server's configured column order. Brackets are gray and column values are color-coded. JSON output includes all log columns by default, including `data` as a string. An explicit `--cols` selection applies to either output format and does not limit which parts of each line are searched.
2584
+
2585
+ The search selects the last N matches before applying the display order, so `--sort date_asc` does not select the earliest N matches. There is no numbered pagination; use `--rows` rather than `--limit`, `--offset`, or `--page`. The summary's total row count includes non-matching lines.
2586
+
2587
+ Missing logs or archives return an empty result. `--dry` previews the search. To view a particular Job's output instead, use `xy job log JOB_ID`.