@velaro/cli 1.4.80 → 1.4.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/velaro.js CHANGED
@@ -92,6 +92,7 @@ import { supportCommand } from '../lib/commands/support.js';
92
92
  import { routingCommand } from '../lib/commands/routing.js';
93
93
  import { diagnosticsCommand } from '../lib/commands/diagnostics.js';
94
94
  import { aiSpendCommand } from '../lib/commands/ai-spend.js';
95
+ import { statusPageCommand } from '../lib/commands/status-page.js';
95
96
  import { emailInboxCommand } from '../lib/commands/email-inbox.js';
96
97
  import { callbackCommand } from '../lib/commands/callback.js';
97
98
  import { caseCommand } from '../lib/commands/case.js';
@@ -104,6 +105,7 @@ import { featureDiscoveryCommand } from '../lib/commands/feature-discovery.js';
104
105
  import { tourPolicyCommand } from '../lib/commands/tour-policy.js';
105
106
  import { scraperCommand } from '../lib/commands/scraper.js';
106
107
  import { campaignsCommand } from '../lib/commands/campaigns.js';
108
+ import { senderDomainHealthCommand } from '../lib/commands/sender-domain-health.js';
107
109
  import { contactsCommand } from '../lib/commands/contacts.js';
108
110
  import { contactListCommand } from '../lib/commands/contact-list.js';
109
111
  import { startUpdateCheck } from '../lib/update-check.js';
@@ -209,6 +211,7 @@ await yargs(hideBin(process.argv))
209
211
  .command(routingCommand)
210
212
  .command(diagnosticsCommand)
211
213
  .command(aiSpendCommand)
214
+ .command(statusPageCommand)
212
215
  .command(emailInboxCommand)
213
216
  .command(callbackCommand)
214
217
  .command(caseCommand)
@@ -221,6 +224,7 @@ await yargs(hideBin(process.argv))
221
224
  .command({ command: 'scraper', desc: 'Velaro staff: scraper / upload / chunk usage for any site', builder: scraperCommand, handler: () => {} })
222
225
  .command({ command: 'tour-policy', desc: 'Velaro staff: guided-tour auto-open policy (versioned, rollback-able)', builder: tourPolicyCommand, handler: () => {} })
223
226
  .command(campaignsCommand)
227
+ .command(senderDomainHealthCommand)
224
228
  .command(contactsCommand)
225
229
  .command(contactListCommand)
226
230
  .demandCommand(1, 'Specify a command. Run "velaro --help" for options.')
@@ -0,0 +1,58 @@
1
+ /**
2
+ * velaro sender-domain-health - registration expiry, DNS and email-provider state for your sending domains
3
+ *
4
+ * velaro sender-domain-health show Health + plain-language history
5
+ * velaro sender-domain-health settings View or change warning days / grace days
6
+ */
7
+ import { request } from '../api.js';
8
+ import { runCommand } from '../run.js';
9
+
10
+ async function showHandler() {
11
+ const r = await request('GET', '/SenderDomains/Health');
12
+ const domains = r.domains ?? [];
13
+ if (domains.length === 0) { console.log('No sender domains.'); return; }
14
+ for (const d of domains) {
15
+ const exp = d.registrationExpiresOn ? `${d.registrationExpiresOn.slice(0, 10)} (${d.daysToExpiry} days)` : 'unknown';
16
+ console.log(`${d.domainName} [${d.healthStatus}] status=${d.status} registration expires: ${exp}`);
17
+ if (d.healthDetail) console.log(` ${d.healthDetail}`);
18
+ }
19
+ const open = r.notices ?? [];
20
+ if (open.length) {
21
+ console.log('\nAction needed:');
22
+ for (const n of open) console.log(` - ${n.domainName}: ${n.message}\n What to do: ${n.remedy}`);
23
+ }
24
+ console.log(`\nWarnings start at ${r.settings.thresholds.join('/')} days; sending pauses ${r.settings.graceDays} days after expiry${r.settings.usingAccountDefault ? ' (account default)' : ''}.`);
25
+ }
26
+
27
+ async function settingsHandler(argv) {
28
+ if (argv.reset) { console.log(JSON.stringify(await request('PUT', '/SenderDomains/Health/Settings', { reset: true }))); return; }
29
+ if (argv.thresholds === undefined && argv.graceDays === undefined) {
30
+ const r = await request('GET', '/SenderDomains/Health');
31
+ console.log(JSON.stringify(r.settings, null, 2));
32
+ return;
33
+ }
34
+ console.log(JSON.stringify(await request('PUT', '/SenderDomains/Health/Settings', { thresholds: argv.thresholds, graceDays: argv.graceDays })));
35
+ }
36
+
37
+ async function dismissHandler(argv) {
38
+ console.log(JSON.stringify(await request('POST', `/SenderDomains/Health/Events/${argv.id}/Dismiss`, {})));
39
+ }
40
+
41
+ export const senderDomainHealthCommand = {
42
+ command: 'sender-domain-health <subcommand>',
43
+ describe: 'Sender domain health: registration expiry, DNS, email-provider state',
44
+ builder: y => y
45
+ .command({ command: 'show', describe: 'Health and history for your sender domains', handler: runCommand(showHandler) })
46
+ .command({
47
+ command: 'settings', describe: 'View or change warning days and grace days',
48
+ builder: yy => yy
49
+ .option('thresholds', { type: 'string', describe: 'Comma-separated days before expiry, e.g. 60,30,14,7,3,1' })
50
+ .option('grace-days', { type: 'number', describe: 'Days after expiry before sending pauses (0-90)' })
51
+ .option('reset', { type: 'boolean', describe: 'Go back to the account default' }),
52
+ handler: runCommand(settingsHandler),
53
+ })
54
+ .command({ command: 'dismiss <id>', describe: 'Dismiss a notice (do not remind me)', handler: runCommand(dismissHandler) })
55
+ .demandCommand(1, 'Specify a subcommand: show | settings | dismiss')
56
+ .strict(),
57
+ handler: () => {},
58
+ };
@@ -0,0 +1,95 @@
1
+ import { messagingRequest } from '../api.js';
2
+
3
+ const COMPONENTS = 'Messaging, Voice & Calls, AI Assistant, Database, API, Integrations, Email Campaigns, Velaro Sign, Velaro Forms, Agent Console, Core API, Chat Engagement';
4
+ const TOKENS = 'AffectedServices is a comma-separated list of component names (' + COMPONENTS + ') plus optional uptime tokens: "counts-uptime" forces the incident to count against uptime, "no-uptime-impact" forces it not to. Default: only a core chat outage counts.';
5
+
6
+ const listCommand = {
7
+ command: 'list',
8
+ describe: 'List status incidents (SuperAdmin, velaro-messaging GET /superadmin/status-incidents)',
9
+ builder: (y) => y.option('filter', { type: 'string', default: 'active', choices: ['active', 'resolved', 'all'] }).option('json', { type: 'boolean', default: false }),
10
+ handler: async (argv) => {
11
+ const rows = await messagingRequest('GET', `/superadmin/status-incidents?filter=${argv.filter}`);
12
+ if (argv.json) { console.log(JSON.stringify(rows, null, 2)); return; }
13
+ for (const r of rows ?? []) console.log(`#${r.id} ${r.status} ${r.incidentType}/${r.severity} ${r.title} [${r.affectedServices ?? ''}]`);
14
+ },
15
+ };
16
+
17
+ const createCommand = {
18
+ command: 'create',
19
+ describe: 'Create a status incident. ' + TOKENS,
20
+ builder: (y) => y
21
+ .option('title', { type: 'string', demandOption: true })
22
+ .option('description', { type: 'string', default: '' })
23
+ .option('status', { type: 'string', default: 'Investigating', describe: 'Investigating, Identified, Monitoring, Resolved' })
24
+ .option('type', { type: 'string', default: 'Incident', describe: 'Incident or Maintenance' })
25
+ .option('severity', { type: 'string', default: 'Minor', describe: 'Minor or Major' })
26
+ .option('services', { type: 'string', default: '', describe: 'AffectedServices CSV. ' + TOKENS })
27
+ .option('regions', { type: 'string', default: '' })
28
+ .option('exclude-from-uptime', { type: 'boolean', default: false })
29
+ .option('hidden', { type: 'boolean', default: false, describe: 'Hide from the public page' }),
30
+ handler: async (argv) => {
31
+ const r = await messagingRequest('POST', '/superadmin/status-incidents', {
32
+ title: argv.title, description: argv.description, status: argv.status, incidentType: argv.type, severity: argv.severity,
33
+ affectedServices: argv.services, affectedRegions: argv.regions, excludeFromUptime: argv.excludeFromUptime, isVisibleToCustomers: !argv.hidden,
34
+ });
35
+ console.log(`Created incident #${r.id}: ${r.title}`);
36
+ },
37
+ };
38
+
39
+ const updateCommand = {
40
+ command: 'update <id>',
41
+ describe: 'Update a status incident (pass every field you want kept). ' + TOKENS,
42
+ builder: (y) => y
43
+ .positional('id', { type: 'number' })
44
+ .option('title', { type: 'string' }).option('description', { type: 'string' })
45
+ .option('status', { type: 'string' }).option('type', { type: 'string' }).option('severity', { type: 'string' })
46
+ .option('services', { type: 'string', describe: 'AffectedServices CSV. ' + TOKENS })
47
+ .option('regions', { type: 'string' })
48
+ .option('end-time', { type: 'string', describe: 'ISO timestamp the incident ended' })
49
+ .option('exclude-from-uptime', { type: 'boolean' })
50
+ .option('hidden', { type: 'boolean' }),
51
+ handler: async (argv) => {
52
+ const body = {
53
+ title: argv.title, description: argv.description, status: argv.status, incidentType: argv.type, severity: argv.severity,
54
+ affectedServices: argv.services, affectedRegions: argv.regions, endTime: argv.endTime,
55
+ excludeFromUptime: argv.excludeFromUptime ?? false, isVisibleToCustomers: argv.hidden === undefined ? true : !argv.hidden,
56
+ };
57
+ const r = await messagingRequest('PUT', `/superadmin/status-incidents/${argv.id}`, body);
58
+ console.log(`Updated incident #${r?.id ?? argv.id}`);
59
+ },
60
+ };
61
+
62
+ const deleteCommand = {
63
+ command: 'delete <id>',
64
+ describe: 'Delete a status incident or clear an override',
65
+ builder: (y) => y.positional('id', { type: 'number' }),
66
+ handler: async (argv) => {
67
+ await messagingRequest('DELETE', `/superadmin/status-incidents/${argv.id}`);
68
+ console.log(`Deleted incident #${argv.id}`);
69
+ },
70
+ };
71
+
72
+ const overrideCommand = {
73
+ command: 'override',
74
+ describe: 'Force a public status page component to a status (POST /superadmin/status-overrides). Components: ' + COMPONENTS + '. Clear with: velaro status-page delete <id>',
75
+ builder: (y) => y
76
+ .option('component', { type: 'string', demandOption: true, describe: COMPONENTS })
77
+ .option('status', { type: 'string', demandOption: true, choices: ['operational', 'degraded', 'outage', 'maintenance'] })
78
+ .option('note', { type: 'string', default: '' })
79
+ .option('expires-at', { type: 'string', describe: 'ISO timestamp the override auto-clears' })
80
+ .option('counts-against-uptime', { type: 'boolean', describe: 'true adds counts-uptime, false adds no-uptime-impact; omit for default' }),
81
+ handler: async (argv) => {
82
+ const r = await messagingRequest('POST', '/superadmin/status-overrides', {
83
+ component: argv.component, status: argv.status, note: argv.note, expiresAt: argv.expiresAt ?? null, countsAgainstUptime: argv.countsAgainstUptime ?? null,
84
+ });
85
+ console.log(`Override #${r.id} created: ${r.title}`);
86
+ },
87
+ };
88
+
89
+ export const statusPageCommand = {
90
+ command: 'status-page <subcommand>',
91
+ describe: 'Public status page incidents and component overrides (SuperAdmin only)',
92
+ builder: (y) => y.command(listCommand).command(createCommand).command(updateCommand).command(deleteCommand).command(overrideCommand)
93
+ .demandCommand(1, 'Specify a subcommand: list, create, update, delete, override').strict(),
94
+ handler: () => {},
95
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velaro/cli",
3
- "version": "1.4.80",
3
+ "version": "1.4.82",
4
4
  "description": "Velaro Workspace v20 — command-line interface for managing bots, knowledge base ingestion, MCP API keys, search indexes, and ops health.",
5
5
  "type": "module",
6
6
  "bin": {