@mailmodo/cli 0.0.18-beta.pr20.29 → 0.0.18

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.
@@ -6,10 +6,7 @@ import { API_ENDPOINTS } from '../../lib/constants.js';
6
6
  import { loadTemplate, saveTemplate, saveYaml, } from '../../lib/yaml-config.js';
7
7
  export default class Edit extends BaseCommand {
8
8
  static args = {
9
- id: Args.string({
10
- description: 'Email template ID to edit',
11
- required: true,
12
- }),
9
+ id: Args.string({ description: 'Email ID to edit', required: true }),
13
10
  };
14
11
  static description = 'Edit an email using AI-assisted natural language changes';
15
12
  static examples = [
@@ -19,30 +19,27 @@ export default class Emails extends BaseCommand {
19
19
  return;
20
20
  }
21
21
  this.log(`\n ${chalk.bold(String(emails.length))} emails configured in mailmodo.yaml:\n`);
22
- const idColW = Math.max(...emails.map((e) => e.id.length), 'ID'.length) + 2;
23
- const triggerColW = Math.max(...emails.map((e) => e.trigger.length), 'Trigger'.length) + 2;
24
- const delayColW = Math.max(...emails.map((e) => String(e.delay).length), 'Delay'.length) +
25
- 2;
26
- const hasConditions = emails.some((e) => e.condition);
27
- this.log(` ${chalk.bold('ID'.padEnd(idColW))}${chalk.bold('Trigger'.padEnd(triggerColW))}${chalk.bold('Delay'.padEnd(delayColW))}${hasConditions ? chalk.bold('Condition') : ''}`);
28
- this.log(` ${'─'.repeat(idColW + triggerColW + delayColW + (hasConditions ? 'Condition'.length : 0))}`);
22
+ const maxIdLen = Math.max(...emails.map((e) => e.id.length), 2);
23
+ const maxTriggerLen = Math.max(...emails.map((e) => e.trigger.length), 7);
29
24
  for (const email of emails) {
30
- const id = chalk.cyan(email.id.padEnd(idColW));
31
- const trigger = email.trigger.padEnd(triggerColW);
32
- const delay = String(email.delay).padEnd(delayColW);
33
- const condition = email.condition ? chalk.dim(email.condition) : '';
34
- this.log(` ${id}${trigger}${delay}${condition}`);
25
+ const id = email.id.padEnd(maxIdLen + 2);
26
+ const trigger = `trigger: ${email.trigger}`.padEnd(maxTriggerLen + 12);
27
+ const delay = `delay: ${email.delay}`;
28
+ const condition = email.condition
29
+ ? chalk.dim(` [if ${email.condition}]`)
30
+ : '';
31
+ this.log(` ${chalk.cyan(id)} ${trigger} ${delay}${condition}`);
35
32
  }
36
33
  this.log('');
37
34
  if (!flags.yes) {
38
- const templateId = await input({
35
+ const emailId = await input({
39
36
  default: 'n',
40
37
  message: "View an email? (id or 'n'):",
41
38
  });
42
- if (templateId !== 'n') {
43
- const email = emails.find((e) => e.id === templateId);
39
+ if (emailId !== 'n') {
40
+ const email = emails.find((e) => e.id === emailId);
44
41
  if (!email) {
45
- this.log(`\n Template '${templateId}' not found.\n`);
42
+ this.log(`\n Email '${emailId}' not found.\n`);
46
43
  return;
47
44
  }
48
45
  this.log('');
@@ -40,11 +40,11 @@ export default class Logs extends BaseCommand {
40
40
  if (entries?.length) {
41
41
  for (const entry of entries) {
42
42
  const time = (entry.timestamp || '').padEnd(18);
43
- const templateId = (entry.emailId || '').padEnd(24);
43
+ const emailId = (entry.emailId || '').padEnd(24);
44
44
  const statusColor = this.statusColor(entry.status);
45
45
  const status = statusColor((entry.status || '').padEnd(10));
46
46
  const contact = entry.contact || '';
47
- this.log(` ${time}${templateId}${status}${contact}`);
47
+ this.log(` ${time}${emailId}${status}${contact}`);
48
48
  if (entry.reason) {
49
49
  this.log(` ${' '.repeat(52)}${chalk.dim(`(reason: ${entry.reason})`)}`);
50
50
  }
@@ -52,7 +52,7 @@ function htmlToText(html) {
52
52
  }
53
53
  export default class Preview extends BaseCommand {
54
54
  static args = {
55
- id: Args.string({ description: 'Email template ID to preview' }),
55
+ id: Args.string({ description: 'Email ID to preview' }),
56
56
  };
57
57
  static description = 'Preview an email in browser, as text, or send a test';
58
58
  static examples = [
@@ -71,13 +71,13 @@ export default class Preview extends BaseCommand {
71
71
  async run() {
72
72
  const { args, flags } = await this.parse(Preview);
73
73
  const yamlConfig = await this.ensureYaml();
74
- const templateId = args.id || yamlConfig.emails[0]?.id;
75
- if (!templateId) {
74
+ const emailId = args.id || yamlConfig.emails[0]?.id;
75
+ if (!emailId) {
76
76
  this.error('No emails configured. Run mailmodo init first.');
77
77
  }
78
- const email = yamlConfig.emails.find((e) => e.id === templateId);
78
+ const email = yamlConfig.emails.find((e) => e.id === emailId);
79
79
  if (!email) {
80
- this.error(`Template '${templateId}' not found in mailmodo.yaml.`);
80
+ this.error(`Email '${emailId}' not found in mailmodo.yaml.`);
81
81
  }
82
82
  const sampleData = {
83
83
  ...SAMPLE_DATA,
@@ -85,7 +85,7 @@ export default class Preview extends BaseCommand {
85
85
  product_name: yamlConfig.project?.name || 'YourApp', // eslint-disable-line camelcase
86
86
  };
87
87
  if (flags.send) {
88
- await this.sendTestEmail(templateId, flags.send, flags.json);
88
+ await this.sendTestEmail(emailId, flags.send, flags.json);
89
89
  return;
90
90
  }
91
91
  const templateHtml = await loadTemplate(`${email.id}.html`);
@@ -123,16 +123,16 @@ export default class Preview extends BaseCommand {
123
123
  * Calls the API to send a test email to the specified address.
124
124
  * Before domain verification, tests send via the mailmodo.com domain.
125
125
  */
126
- async sendTestEmail(templateId, toAddress, jsonOutput) {
126
+ async sendTestEmail(emailId, toAddress, jsonOutput) {
127
127
  await this.ensureAuth();
128
- const response = await this.withApiSpinner({ json: jsonOutput, text: ' Sending test email...' }, () => this.apiClient.post(`${API_ENDPOINTS.PREVIEW}/${templateId}/send`, {
128
+ const response = await this.withApiSpinner({ json: jsonOutput, text: ' Sending test email...' }, () => this.apiClient.post(`${API_ENDPOINTS.PREVIEW}/${emailId}/send`, {
129
129
  to: toAddress,
130
130
  }));
131
131
  if (!response.ok) {
132
132
  this.handleApiError(response);
133
133
  }
134
134
  if (jsonOutput) {
135
- this.log(JSON.stringify({ templateId, sentTo: toAddress, status: 'sent' }, null, 2));
135
+ this.log(JSON.stringify({ emailId, sentTo: toAddress, status: 'sent' }, null, 2));
136
136
  return;
137
137
  }
138
138
  this.log(`\n Sending test to ${chalk.cyan(toAddress)}...`);
@@ -209,7 +209,7 @@
209
209
  "aliases": [],
210
210
  "args": {
211
211
  "id": {
212
- "description": "Email template ID to edit",
212
+ "description": "Email ID to edit",
213
213
  "name": "id",
214
214
  "required": true
215
215
  }
@@ -257,13 +257,13 @@
257
257
  "index.js"
258
258
  ]
259
259
  },
260
- "emails": {
260
+ "init": {
261
261
  "aliases": [],
262
262
  "args": {},
263
- "description": "List and view configured email sequences",
263
+ "description": "Analyze your product and generate email sequences",
264
264
  "examples": [
265
- "<%= config.bin %> emails",
266
- "<%= config.bin %> emails --json"
265
+ "<%= config.bin %> init",
266
+ "<%= config.bin %> init --url https://myapp.com --yes"
267
267
  ],
268
268
  "flags": {
269
269
  "json": {
@@ -278,11 +278,18 @@
278
278
  "name": "yes",
279
279
  "allowNo": false,
280
280
  "type": "boolean"
281
+ },
282
+ "url": {
283
+ "description": "Product URL to analyze",
284
+ "name": "url",
285
+ "hasDynamicHelp": false,
286
+ "multiple": false,
287
+ "type": "option"
281
288
  }
282
289
  },
283
290
  "hasDynamicHelp": false,
284
291
  "hiddenAliases": [],
285
- "id": "emails",
292
+ "id": "init",
286
293
  "pluginAlias": "@mailmodo/cli",
287
294
  "pluginName": "@mailmodo/cli",
288
295
  "pluginType": "core",
@@ -292,17 +299,17 @@
292
299
  "relativePath": [
293
300
  "dist",
294
301
  "commands",
295
- "emails",
302
+ "init",
296
303
  "index.js"
297
304
  ]
298
305
  },
299
- "init": {
306
+ "login": {
300
307
  "aliases": [],
301
308
  "args": {},
302
- "description": "Analyze your product and generate email sequences",
309
+ "description": "Authenticate with Mailmodo using your API key",
303
310
  "examples": [
304
- "<%= config.bin %> init",
305
- "<%= config.bin %> init --url https://myapp.com --yes"
311
+ "<%= config.bin %> login",
312
+ "MAILMODO_API_KEY=mm_live_xxx <%= config.bin %> login"
306
313
  ],
307
314
  "flags": {
308
315
  "json": {
@@ -317,18 +324,11 @@
317
324
  "name": "yes",
318
325
  "allowNo": false,
319
326
  "type": "boolean"
320
- },
321
- "url": {
322
- "description": "Product URL to analyze",
323
- "name": "url",
324
- "hasDynamicHelp": false,
325
- "multiple": false,
326
- "type": "option"
327
327
  }
328
328
  },
329
329
  "hasDynamicHelp": false,
330
330
  "hiddenAliases": [],
331
- "id": "init",
331
+ "id": "login",
332
332
  "pluginAlias": "@mailmodo/cli",
333
333
  "pluginName": "@mailmodo/cli",
334
334
  "pluginType": "core",
@@ -338,17 +338,16 @@
338
338
  "relativePath": [
339
339
  "dist",
340
340
  "commands",
341
- "init",
341
+ "login",
342
342
  "index.js"
343
343
  ]
344
344
  },
345
- "login": {
345
+ "logout": {
346
346
  "aliases": [],
347
347
  "args": {},
348
- "description": "Authenticate with Mailmodo using your API key",
348
+ "description": "Sign out by removing saved credentials from this machine",
349
349
  "examples": [
350
- "<%= config.bin %> login",
351
- "MAILMODO_API_KEY=mm_live_xxx <%= config.bin %> login"
350
+ "<%= config.bin %> logout"
352
351
  ],
353
352
  "flags": {
354
353
  "json": {
@@ -367,7 +366,7 @@
367
366
  },
368
367
  "hasDynamicHelp": false,
369
368
  "hiddenAliases": [],
370
- "id": "login",
369
+ "id": "logout",
371
370
  "pluginAlias": "@mailmodo/cli",
372
371
  "pluginName": "@mailmodo/cli",
373
372
  "pluginType": "core",
@@ -377,16 +376,19 @@
377
376
  "relativePath": [
378
377
  "dist",
379
378
  "commands",
380
- "login",
379
+ "logout",
381
380
  "index.js"
382
381
  ]
383
382
  },
384
- "logout": {
383
+ "logs": {
385
384
  "aliases": [],
386
385
  "args": {},
387
- "description": "Sign out by removing saved credentials from this machine",
386
+ "description": "View email send logs and delivery events",
388
387
  "examples": [
389
- "<%= config.bin %> logout"
388
+ "<%= config.bin %> logs",
389
+ "<%= config.bin %> logs --email sarah@example.com",
390
+ "<%= config.bin %> logs --failed",
391
+ "<%= config.bin %> logs --json"
390
392
  ],
391
393
  "flags": {
392
394
  "json": {
@@ -401,11 +403,24 @@
401
403
  "name": "yes",
402
404
  "allowNo": false,
403
405
  "type": "boolean"
406
+ },
407
+ "email": {
408
+ "description": "Filter logs by contact email",
409
+ "name": "email",
410
+ "hasDynamicHelp": false,
411
+ "multiple": false,
412
+ "type": "option"
413
+ },
414
+ "failed": {
415
+ "description": "Show only failed/bounced events",
416
+ "name": "failed",
417
+ "allowNo": false,
418
+ "type": "boolean"
404
419
  }
405
420
  },
406
421
  "hasDynamicHelp": false,
407
422
  "hiddenAliases": [],
408
- "id": "logout",
423
+ "id": "logs",
409
424
  "pluginAlias": "@mailmodo/cli",
410
425
  "pluginName": "@mailmodo/cli",
411
426
  "pluginType": "core",
@@ -415,7 +430,7 @@
415
430
  "relativePath": [
416
431
  "dist",
417
432
  "commands",
418
- "logout",
433
+ "logs",
419
434
  "index.js"
420
435
  ]
421
436
  },
@@ -423,7 +438,7 @@
423
438
  "aliases": [],
424
439
  "args": {
425
440
  "id": {
426
- "description": "Email template ID to preview",
441
+ "description": "Email ID to preview",
427
442
  "name": "id"
428
443
  }
429
444
  },
@@ -477,15 +492,14 @@
477
492
  "index.js"
478
493
  ]
479
494
  },
480
- "logs": {
495
+ "settings": {
481
496
  "aliases": [],
482
497
  "args": {},
483
- "description": "View email send logs and delivery events",
498
+ "description": "View and update project settings",
484
499
  "examples": [
485
- "<%= config.bin %> logs",
486
- "<%= config.bin %> logs --email sarah@example.com",
487
- "<%= config.bin %> logs --failed",
488
- "<%= config.bin %> logs --json"
500
+ "<%= config.bin %> settings",
501
+ "<%= config.bin %> settings --set brand_color=#0F3460",
502
+ "<%= config.bin %> settings --json"
489
503
  ],
490
504
  "flags": {
491
505
  "json": {
@@ -501,23 +515,17 @@
501
515
  "allowNo": false,
502
516
  "type": "boolean"
503
517
  },
504
- "email": {
505
- "description": "Filter logs by contact email",
506
- "name": "email",
518
+ "set": {
519
+ "description": "Set a setting (format: key=value)",
520
+ "name": "set",
507
521
  "hasDynamicHelp": false,
508
522
  "multiple": false,
509
523
  "type": "option"
510
- },
511
- "failed": {
512
- "description": "Show only failed/bounced events",
513
- "name": "failed",
514
- "allowNo": false,
515
- "type": "boolean"
516
524
  }
517
525
  },
518
526
  "hasDynamicHelp": false,
519
527
  "hiddenAliases": [],
520
- "id": "logs",
528
+ "id": "settings",
521
529
  "pluginAlias": "@mailmodo/cli",
522
530
  "pluginName": "@mailmodo/cli",
523
531
  "pluginType": "core",
@@ -527,18 +535,17 @@
527
535
  "relativePath": [
528
536
  "dist",
529
537
  "commands",
530
- "logs",
538
+ "settings",
531
539
  "index.js"
532
540
  ]
533
541
  },
534
- "settings": {
542
+ "status": {
535
543
  "aliases": [],
536
544
  "args": {},
537
- "description": "View and update project settings",
545
+ "description": "View email performance metrics and quota usage",
538
546
  "examples": [
539
- "<%= config.bin %> settings",
540
- "<%= config.bin %> settings --set brand_color=#0F3460",
541
- "<%= config.bin %> settings --json"
547
+ "<%= config.bin %> status",
548
+ "<%= config.bin %> status --json"
542
549
  ],
543
550
  "flags": {
544
551
  "json": {
@@ -553,18 +560,11 @@
553
560
  "name": "yes",
554
561
  "allowNo": false,
555
562
  "type": "boolean"
556
- },
557
- "set": {
558
- "description": "Set a setting (format: key=value)",
559
- "name": "set",
560
- "hasDynamicHelp": false,
561
- "multiple": false,
562
- "type": "option"
563
563
  }
564
564
  },
565
565
  "hasDynamicHelp": false,
566
566
  "hiddenAliases": [],
567
- "id": "settings",
567
+ "id": "status",
568
568
  "pluginAlias": "@mailmodo/cli",
569
569
  "pluginName": "@mailmodo/cli",
570
570
  "pluginType": "core",
@@ -574,17 +574,17 @@
574
574
  "relativePath": [
575
575
  "dist",
576
576
  "commands",
577
- "settings",
577
+ "status",
578
578
  "index.js"
579
579
  ]
580
580
  },
581
- "status": {
581
+ "emails": {
582
582
  "aliases": [],
583
583
  "args": {},
584
- "description": "View email performance metrics and quota usage",
584
+ "description": "List and view configured email sequences",
585
585
  "examples": [
586
- "<%= config.bin %> status",
587
- "<%= config.bin %> status --json"
586
+ "<%= config.bin %> emails",
587
+ "<%= config.bin %> emails --json"
588
588
  ],
589
589
  "flags": {
590
590
  "json": {
@@ -603,7 +603,7 @@
603
603
  },
604
604
  "hasDynamicHelp": false,
605
605
  "hiddenAliases": [],
606
- "id": "status",
606
+ "id": "emails",
607
607
  "pluginAlias": "@mailmodo/cli",
608
608
  "pluginName": "@mailmodo/cli",
609
609
  "pluginType": "core",
@@ -613,10 +613,10 @@
613
613
  "relativePath": [
614
614
  "dist",
615
615
  "commands",
616
- "status",
616
+ "emails",
617
617
  "index.js"
618
618
  ]
619
619
  }
620
620
  },
621
- "version": "0.0.18-beta.pr20.29"
621
+ "version": "0.0.18"
622
622
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mailmodo/cli",
3
3
  "description": "Email lifecycle automation for the AI-native builder generation.",
4
- "version": "0.0.18-beta.pr20.29",
4
+ "version": "0.0.18",
5
5
  "author": "provishalk",
6
6
  "bin": {
7
7
  "mailmodo": "bin/run.js"