@mailmodo/cli 0.0.30-beta.pr32.50 → 0.0.30-beta.pr32.52

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.
@@ -62,7 +62,8 @@ export default class Deploy extends BaseCommand {
62
62
  async buildDeployPayload(yamlConfig) {
63
63
  const emailsWithHtml = await Promise.all(yamlConfig.emails.map(async (email) => {
64
64
  const html = (await loadTemplate(`${email.id}.html`)) || '';
65
- return { ...this.mapEmailToPayload(email), html, plainHtml: html };
65
+ const plainHtml = (await loadTemplate(`${email.id}_plain.html`)) || html;
66
+ return { ...this.mapEmailToPayload(email), html, plainHtml };
66
67
  }));
67
68
  return {
68
69
  ...this.buildProjectPayload(yamlConfig.project),
@@ -3,7 +3,7 @@ import { confirm, input, select } from '@inquirer/prompts';
3
3
  import chalk from 'chalk';
4
4
  import { BaseCommand } from '../../lib/base-command.js';
5
5
  import { API_ENDPOINTS } from '../../lib/constants.js';
6
- import { loadTemplate, saveTemplate, saveYaml, } from '../../lib/yaml-config.js';
6
+ import { loadTemplate, resolveTemplateFilename, saveTemplate, saveYaml, } from '../../lib/yaml-config.js';
7
7
  export default class Edit extends BaseCommand {
8
8
  static args = {
9
9
  id: Args.string({
@@ -30,17 +30,20 @@ export default class Edit extends BaseCommand {
30
30
  if (emailIndex === -1) {
31
31
  this.error(`Email '${args.id}' not found in mailmodo.yaml.`);
32
32
  }
33
+ const email = yamlConfig.emails[emailIndex];
34
+ const templateFilename = resolveTemplateFilename(email.id, email.style, yamlConfig.project?.emailStyle);
33
35
  const ctx = {
34
- email: yamlConfig.emails[emailIndex],
36
+ email,
35
37
  emailIndex,
36
- templateHtml: await loadTemplate(`${yamlConfig.emails[emailIndex].id}.html`),
38
+ templateFilename,
39
+ templateHtml: await loadTemplate(templateFilename),
37
40
  yamlConfig,
38
41
  };
39
42
  const editFlags = {
40
43
  json: flags.json ?? false,
41
44
  yes: flags.yes ?? false,
42
45
  };
43
- const initialChange = flags.change ?? (await this.askChangeDescription());
46
+ const initialChange = flags.change?.trim() || (await this.askChangeDescription());
44
47
  await this.runEditStep(ctx, initialChange, editFlags);
45
48
  }
46
49
  async runEditStep(ctx, changeDescription, flags) {
@@ -119,7 +122,7 @@ export default class Edit extends BaseCommand {
119
122
  updatedYaml.emails[ctx.emailIndex] = ctx.email;
120
123
  await saveYaml(updatedYaml);
121
124
  if (updated.html) {
122
- await saveTemplate(`${ctx.email.id}.html`, updated.html);
125
+ await saveTemplate(ctx.templateFilename, updated.html);
123
126
  }
124
127
  }
125
128
  logJsonResult(email, updated, oldSubject) {
@@ -79,11 +79,16 @@ export default class Emails extends BaseCommand {
79
79
  this.log(`\n Opening ${template}...\n`);
80
80
  const editor = process.env.VISUAL || process.env.EDITOR;
81
81
  if (editor) {
82
- const child = spawn(editor, [templatePath], { stdio: 'inherit' });
83
- await new Promise((resolve) => {
84
- child.on('close', resolve);
82
+ const [cmd, ...editorArgs] = editor.trim().split(/\s+/);
83
+ const launched = await new Promise((resolve) => {
84
+ const child = spawn(cmd, [...editorArgs, templatePath], {
85
+ stdio: 'inherit',
86
+ });
87
+ child.on('error', () => resolve(false));
88
+ child.on('close', () => resolve(true));
85
89
  });
86
- return;
90
+ if (launched)
91
+ return;
87
92
  }
88
93
  if (await this.trySpawnEditor('code', templatePath))
89
94
  return;
@@ -139,7 +139,7 @@ export default class Init extends BaseCommand {
139
139
  project: {
140
140
  brandColor: analysisPayload.brand?.color || DEFAULT_BRAND_COLOR,
141
141
  description: analysisPayload.description,
142
- emailStyle: 'branded',
142
+ emailStyle: 'plain',
143
143
  fromEmail: '',
144
144
  fromName: `Team ${analysisPayload.productName}`,
145
145
  logoUrl: analysisPayload.brand?.logoUrl || '',
@@ -4,7 +4,7 @@ import chalk from 'chalk';
4
4
  import open from 'open';
5
5
  import { BaseCommand } from '../../lib/base-command.js';
6
6
  import { API_ENDPOINTS, PREVIEW_PORT } from '../../lib/constants.js';
7
- import { loadTemplate } from '../../lib/yaml-config.js';
7
+ import { loadTemplate, resolveTemplateFilename, } from '../../lib/yaml-config.js';
8
8
  /* eslint-disable camelcase */
9
9
  const SAMPLE_DATA = Object.freeze({
10
10
  app_url: 'https://yourapp.com',
@@ -84,7 +84,7 @@ export default class Preview extends BaseCommand {
84
84
  app_url: yamlConfig.project?.url || 'https://yourapp.com', // eslint-disable-line camelcase
85
85
  product_name: yamlConfig.project?.name || 'YourApp', // eslint-disable-line camelcase
86
86
  };
87
- const templateHtml = await loadTemplate(`${email.id}.html`);
87
+ const templateHtml = await loadTemplate(resolveTemplateFilename(email.id, email.style, yamlConfig.project?.emailStyle));
88
88
  if (flags.send) {
89
89
  const rendered = templateHtml
90
90
  ? renderTemplate(templateHtml, sampleData)
@@ -68,3 +68,4 @@ export declare function saveTemplate(filename: string, html: string, cwd?: strin
68
68
  * or null if the file doesn't exist or can't be read.
69
69
  */
70
70
  export declare function loadTemplate(filename: string, cwd?: string): Promise<null | string>;
71
+ export declare function resolveTemplateFilename(emailId: string, emailStyle?: 'branded' | 'plain', projectStyle?: 'branded' | 'plain'): string;
@@ -72,3 +72,7 @@ export async function loadTemplate(filename, cwd) {
72
72
  return null;
73
73
  }
74
74
  }
75
+ export function resolveTemplateFilename(emailId, emailStyle, projectStyle) {
76
+ const style = emailStyle ?? projectStyle ?? 'branded';
77
+ return style === 'plain' ? `${emailId}_plain.html` : `${emailId}.html`;
78
+ }
@@ -137,45 +137,6 @@
137
137
  "index.js"
138
138
  ]
139
139
  },
140
- "deploy": {
141
- "aliases": [],
142
- "args": {},
143
- "description": "Deploy email sequences and verify sending domain",
144
- "examples": [
145
- "<%= config.bin %> deploy",
146
- "<%= config.bin %> deploy --yes"
147
- ],
148
- "flags": {
149
- "json": {
150
- "description": "Output as JSON",
151
- "name": "json",
152
- "allowNo": false,
153
- "type": "boolean"
154
- },
155
- "yes": {
156
- "char": "y",
157
- "description": "Skip confirmation prompts",
158
- "name": "yes",
159
- "allowNo": false,
160
- "type": "boolean"
161
- }
162
- },
163
- "hasDynamicHelp": false,
164
- "hiddenAliases": [],
165
- "id": "deploy",
166
- "pluginAlias": "@mailmodo/cli",
167
- "pluginName": "@mailmodo/cli",
168
- "pluginType": "core",
169
- "strict": true,
170
- "enableJsonFlag": false,
171
- "isESM": true,
172
- "relativePath": [
173
- "dist",
174
- "commands",
175
- "deploy",
176
- "index.js"
177
- ]
178
- },
179
140
  "domain": {
180
141
  "aliases": [],
181
142
  "args": {},
@@ -228,13 +189,13 @@
228
189
  "index.js"
229
190
  ]
230
191
  },
231
- "emails": {
192
+ "deploy": {
232
193
  "aliases": [],
233
194
  "args": {},
234
- "description": "List and view configured email sequences",
195
+ "description": "Deploy email sequences and verify sending domain",
235
196
  "examples": [
236
- "<%= config.bin %> emails",
237
- "<%= config.bin %> emails --json"
197
+ "<%= config.bin %> deploy",
198
+ "<%= config.bin %> deploy --yes"
238
199
  ],
239
200
  "flags": {
240
201
  "json": {
@@ -253,7 +214,7 @@
253
214
  },
254
215
  "hasDynamicHelp": false,
255
216
  "hiddenAliases": [],
256
- "id": "emails",
217
+ "id": "deploy",
257
218
  "pluginAlias": "@mailmodo/cli",
258
219
  "pluginName": "@mailmodo/cli",
259
220
  "pluginType": "core",
@@ -263,7 +224,7 @@
263
224
  "relativePath": [
264
225
  "dist",
265
226
  "commands",
266
- "emails",
227
+ "deploy",
267
228
  "index.js"
268
229
  ]
269
230
  },
@@ -319,13 +280,13 @@
319
280
  "index.js"
320
281
  ]
321
282
  },
322
- "init": {
283
+ "emails": {
323
284
  "aliases": [],
324
285
  "args": {},
325
- "description": "Analyze your product and generate email sequences",
286
+ "description": "List and view configured email sequences",
326
287
  "examples": [
327
- "<%= config.bin %> init",
328
- "<%= config.bin %> init --url https://myapp.com --yes"
288
+ "<%= config.bin %> emails",
289
+ "<%= config.bin %> emails --json"
329
290
  ],
330
291
  "flags": {
331
292
  "json": {
@@ -340,18 +301,11 @@
340
301
  "name": "yes",
341
302
  "allowNo": false,
342
303
  "type": "boolean"
343
- },
344
- "url": {
345
- "description": "Product URL to analyze",
346
- "name": "url",
347
- "hasDynamicHelp": false,
348
- "multiple": false,
349
- "type": "option"
350
304
  }
351
305
  },
352
306
  "hasDynamicHelp": false,
353
307
  "hiddenAliases": [],
354
- "id": "init",
308
+ "id": "emails",
355
309
  "pluginAlias": "@mailmodo/cli",
356
310
  "pluginName": "@mailmodo/cli",
357
311
  "pluginType": "core",
@@ -361,17 +315,17 @@
361
315
  "relativePath": [
362
316
  "dist",
363
317
  "commands",
364
- "init",
318
+ "emails",
365
319
  "index.js"
366
320
  ]
367
321
  },
368
- "login": {
322
+ "init": {
369
323
  "aliases": [],
370
324
  "args": {},
371
- "description": "Authenticate with Mailmodo using your API key",
325
+ "description": "Analyze your product and generate email sequences",
372
326
  "examples": [
373
- "<%= config.bin %> login",
374
- "MAILMODO_API_KEY=mm_live_xxx <%= config.bin %> login"
327
+ "<%= config.bin %> init",
328
+ "<%= config.bin %> init --url https://myapp.com --yes"
375
329
  ],
376
330
  "flags": {
377
331
  "json": {
@@ -386,11 +340,18 @@
386
340
  "name": "yes",
387
341
  "allowNo": false,
388
342
  "type": "boolean"
343
+ },
344
+ "url": {
345
+ "description": "Product URL to analyze",
346
+ "name": "url",
347
+ "hasDynamicHelp": false,
348
+ "multiple": false,
349
+ "type": "option"
389
350
  }
390
351
  },
391
352
  "hasDynamicHelp": false,
392
353
  "hiddenAliases": [],
393
- "id": "login",
354
+ "id": "init",
394
355
  "pluginAlias": "@mailmodo/cli",
395
356
  "pluginName": "@mailmodo/cli",
396
357
  "pluginType": "core",
@@ -400,16 +361,17 @@
400
361
  "relativePath": [
401
362
  "dist",
402
363
  "commands",
403
- "login",
364
+ "init",
404
365
  "index.js"
405
366
  ]
406
367
  },
407
- "logout": {
368
+ "login": {
408
369
  "aliases": [],
409
370
  "args": {},
410
- "description": "Sign out by removing saved credentials from this machine",
371
+ "description": "Authenticate with Mailmodo using your API key",
411
372
  "examples": [
412
- "<%= config.bin %> logout"
373
+ "<%= config.bin %> login",
374
+ "MAILMODO_API_KEY=mm_live_xxx <%= config.bin %> login"
413
375
  ],
414
376
  "flags": {
415
377
  "json": {
@@ -428,7 +390,7 @@
428
390
  },
429
391
  "hasDynamicHelp": false,
430
392
  "hiddenAliases": [],
431
- "id": "logout",
393
+ "id": "login",
432
394
  "pluginAlias": "@mailmodo/cli",
433
395
  "pluginName": "@mailmodo/cli",
434
396
  "pluginType": "core",
@@ -438,19 +400,16 @@
438
400
  "relativePath": [
439
401
  "dist",
440
402
  "commands",
441
- "logout",
403
+ "login",
442
404
  "index.js"
443
405
  ]
444
406
  },
445
- "logs": {
407
+ "logout": {
446
408
  "aliases": [],
447
409
  "args": {},
448
- "description": "View email send logs and delivery events",
410
+ "description": "Sign out by removing saved credentials from this machine",
449
411
  "examples": [
450
- "<%= config.bin %> logs",
451
- "<%= config.bin %> logs --email sarah@example.com",
452
- "<%= config.bin %> logs --failed",
453
- "<%= config.bin %> logs --json"
412
+ "<%= config.bin %> logout"
454
413
  ],
455
414
  "flags": {
456
415
  "json": {
@@ -465,40 +424,11 @@
465
424
  "name": "yes",
466
425
  "allowNo": false,
467
426
  "type": "boolean"
468
- },
469
- "email": {
470
- "description": "Filter logs by contact email",
471
- "name": "email",
472
- "hasDynamicHelp": false,
473
- "multiple": false,
474
- "type": "option"
475
- },
476
- "failed": {
477
- "description": "Show only failed/bounced events",
478
- "name": "failed",
479
- "allowNo": false,
480
- "type": "boolean"
481
- },
482
- "limit": {
483
- "description": "Entries per page (max 200)",
484
- "name": "limit",
485
- "default": 50,
486
- "hasDynamicHelp": false,
487
- "multiple": false,
488
- "type": "option"
489
- },
490
- "page": {
491
- "description": "Page number",
492
- "name": "page",
493
- "default": 1,
494
- "hasDynamicHelp": false,
495
- "multiple": false,
496
- "type": "option"
497
427
  }
498
428
  },
499
429
  "hasDynamicHelp": false,
500
430
  "hiddenAliases": [],
501
- "id": "logs",
431
+ "id": "logout",
502
432
  "pluginAlias": "@mailmodo/cli",
503
433
  "pluginName": "@mailmodo/cli",
504
434
  "pluginType": "core",
@@ -508,7 +438,7 @@
508
438
  "relativePath": [
509
439
  "dist",
510
440
  "commands",
511
- "logs",
441
+ "logout",
512
442
  "index.js"
513
443
  ]
514
444
  },
@@ -570,13 +500,15 @@
570
500
  "index.js"
571
501
  ]
572
502
  },
573
- "status": {
503
+ "logs": {
574
504
  "aliases": [],
575
505
  "args": {},
576
- "description": "View email performance metrics and quota usage",
506
+ "description": "View email send logs and delivery events",
577
507
  "examples": [
578
- "<%= config.bin %> status",
579
- "<%= config.bin %> status --json"
508
+ "<%= config.bin %> logs",
509
+ "<%= config.bin %> logs --email sarah@example.com",
510
+ "<%= config.bin %> logs --failed",
511
+ "<%= config.bin %> logs --json"
580
512
  ],
581
513
  "flags": {
582
514
  "json": {
@@ -591,11 +523,40 @@
591
523
  "name": "yes",
592
524
  "allowNo": false,
593
525
  "type": "boolean"
526
+ },
527
+ "email": {
528
+ "description": "Filter logs by contact email",
529
+ "name": "email",
530
+ "hasDynamicHelp": false,
531
+ "multiple": false,
532
+ "type": "option"
533
+ },
534
+ "failed": {
535
+ "description": "Show only failed/bounced events",
536
+ "name": "failed",
537
+ "allowNo": false,
538
+ "type": "boolean"
539
+ },
540
+ "limit": {
541
+ "description": "Entries per page (max 200)",
542
+ "name": "limit",
543
+ "default": 50,
544
+ "hasDynamicHelp": false,
545
+ "multiple": false,
546
+ "type": "option"
547
+ },
548
+ "page": {
549
+ "description": "Page number",
550
+ "name": "page",
551
+ "default": 1,
552
+ "hasDynamicHelp": false,
553
+ "multiple": false,
554
+ "type": "option"
594
555
  }
595
556
  },
596
557
  "hasDynamicHelp": false,
597
558
  "hiddenAliases": [],
598
- "id": "status",
559
+ "id": "logs",
599
560
  "pluginAlias": "@mailmodo/cli",
600
561
  "pluginName": "@mailmodo/cli",
601
562
  "pluginType": "core",
@@ -605,7 +566,7 @@
605
566
  "relativePath": [
606
567
  "dist",
607
568
  "commands",
608
- "status",
569
+ "logs",
609
570
  "index.js"
610
571
  ]
611
572
  },
@@ -655,7 +616,46 @@
655
616
  "settings",
656
617
  "index.js"
657
618
  ]
619
+ },
620
+ "status": {
621
+ "aliases": [],
622
+ "args": {},
623
+ "description": "View email performance metrics and quota usage",
624
+ "examples": [
625
+ "<%= config.bin %> status",
626
+ "<%= config.bin %> status --json"
627
+ ],
628
+ "flags": {
629
+ "json": {
630
+ "description": "Output as JSON",
631
+ "name": "json",
632
+ "allowNo": false,
633
+ "type": "boolean"
634
+ },
635
+ "yes": {
636
+ "char": "y",
637
+ "description": "Skip confirmation prompts",
638
+ "name": "yes",
639
+ "allowNo": false,
640
+ "type": "boolean"
641
+ }
642
+ },
643
+ "hasDynamicHelp": false,
644
+ "hiddenAliases": [],
645
+ "id": "status",
646
+ "pluginAlias": "@mailmodo/cli",
647
+ "pluginName": "@mailmodo/cli",
648
+ "pluginType": "core",
649
+ "strict": true,
650
+ "enableJsonFlag": false,
651
+ "isESM": true,
652
+ "relativePath": [
653
+ "dist",
654
+ "commands",
655
+ "status",
656
+ "index.js"
657
+ ]
658
658
  }
659
659
  },
660
- "version": "0.0.30-beta.pr32.50"
660
+ "version": "0.0.30-beta.pr32.52"
661
661
  }
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.30-beta.pr32.50",
4
+ "version": "0.0.30-beta.pr32.52",
5
5
  "author": "provishalk",
6
6
  "bin": {
7
7
  "mailmodo": "bin/run.js"