@cakemail-org/cakemail-cli 1.5.0 → 2.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.
- package/.claude/settings.local.json +12 -0
- package/.env.example +40 -0
- package/.env.test.example +45 -0
- package/CHANGELOG.md +1031 -0
- package/README.md +319 -15
- package/audit-formats.js +128 -0
- package/cakemail.rb +20 -0
- package/dist/cli.js +27 -10
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +16 -6
- package/dist/client.js.map +1 -1
- package/dist/commands/account.js +1 -1
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/attributes.js +1 -1
- package/dist/commands/attributes.js.map +1 -1
- package/dist/commands/campaigns.d.ts.map +1 -1
- package/dist/commands/campaigns.js +103 -8
- package/dist/commands/campaigns.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +63 -4
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contacts.d.ts.map +1 -1
- package/dist/commands/contacts.js +91 -12
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/emails.js +1 -1
- package/dist/commands/emails.js.map +1 -1
- package/dist/commands/interests.d.ts +5 -0
- package/dist/commands/interests.d.ts.map +1 -0
- package/dist/commands/interests.js +172 -0
- package/dist/commands/interests.js.map +1 -0
- package/dist/commands/lists.d.ts.map +1 -1
- package/dist/commands/lists.js +6 -8
- package/dist/commands/lists.js.map +1 -1
- package/dist/commands/logs.d.ts +5 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +237 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/reports.js +1 -1
- package/dist/commands/reports.js.map +1 -1
- package/dist/commands/segments.js +1 -1
- package/dist/commands/segments.js.map +1 -1
- package/dist/commands/senders.d.ts.map +1 -1
- package/dist/commands/senders.js +11 -8
- package/dist/commands/senders.js.map +1 -1
- package/dist/commands/suppressed.js +1 -1
- package/dist/commands/suppressed.js.map +1 -1
- package/dist/commands/tags.d.ts +5 -0
- package/dist/commands/tags.d.ts.map +1 -0
- package/dist/commands/tags.js +124 -0
- package/dist/commands/tags.js.map +1 -0
- package/dist/commands/templates.js +1 -1
- package/dist/commands/templates.js.map +1 -1
- package/dist/commands/transactional-templates.d.ts +5 -0
- package/dist/commands/transactional-templates.d.ts.map +1 -0
- package/dist/commands/transactional-templates.js +354 -0
- package/dist/commands/transactional-templates.js.map +1 -0
- package/dist/commands/webhooks.js +1 -1
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/utils/auth.d.ts +8 -1
- package/dist/utils/auth.d.ts.map +1 -1
- package/dist/utils/auth.js +39 -11
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/config-file.d.ts +7 -0
- package/dist/utils/config-file.d.ts.map +1 -1
- package/dist/utils/config-file.js +15 -0
- package/dist/utils/config-file.js.map +1 -1
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +12 -4
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/errors.js +1 -1
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/list-defaults.d.ts +33 -0
- package/dist/utils/list-defaults.d.ts.map +1 -0
- package/dist/utils/list-defaults.js +52 -0
- package/dist/utils/list-defaults.js.map +1 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +36 -13
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/progress.d.ts.map +1 -1
- package/dist/utils/progress.js +32 -4
- package/dist/utils/progress.js.map +1 -1
- package/dist/utils/spinner.d.ts +17 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +43 -0
- package/dist/utils/spinner.js.map +1 -0
- package/docs/DOCUMENTATION-STANDARD.md +1068 -0
- package/docs/README.md +161 -0
- package/docs/developer/ARCHITECTURE.md +516 -0
- package/docs/developer/AUTH.md +204 -0
- package/docs/developer/CONTRIBUTING.md +227 -0
- package/docs/developer/DOCUMENTATION_SUMMARY.md +346 -0
- package/docs/developer/PROJECT_INDEX.md +365 -0
- package/docs/planning/API_COVERAGE.md +1045 -0
- package/docs/planning/BACKLOG.md +1159 -0
- package/docs/planning/PROFILE_SYSTEM_TASKS.md +287 -0
- package/docs/planning/UX_IMPLEMENTATION_PLAN.md +691 -0
- package/docs/planning/archive/RELEASE_CHECKLIST_v1.3.0.md +332 -0
- package/docs/planning/archive/RELEASE_v1.3.0.md +428 -0
- package/docs/planning/archive/cakemail-cli-ux-improvements.md +438 -0
- package/docs/planning/cakemail-profile-system-plan.md +1121 -0
- package/docs/testing/AI_USER_SIMULATION_DESIGN.md +1342 -0
- package/docs/testing/KENOGAMI_BIDIRECTIONAL_FLOW.md +1517 -0
- package/docs/testing/KENOGAMI_TRUTH_RECONCILIATION_SYSTEM.md +1369 -0
- package/docs/user-manual/.obsidian/app.json +1 -0
- package/docs/user-manual/.obsidian/appearance.json +1 -0
- package/docs/user-manual/.obsidian/core-plugins.json +33 -0
- package/docs/user-manual/.obsidian/workspace.json +167 -0
- package/docs/user-manual/01-getting-started/01-installation.md +214 -0
- package/docs/user-manual/01-getting-started/02-quick-start.md +432 -0
- package/docs/user-manual/01-getting-started/03-authentication.md +448 -0
- package/docs/user-manual/01-getting-started/04-configuration.md +430 -0
- package/docs/user-manual/01-getting-started/05-output-formats.md +447 -0
- package/docs/user-manual/02-core-concepts/01-accounts.md +514 -0
- package/docs/user-manual/02-core-concepts/02-profile-system.md +771 -0
- package/docs/user-manual/02-core-concepts/03-smart-defaults.md +485 -0
- package/docs/user-manual/02-core-concepts/04-authentication-methods.md +435 -0
- package/docs/user-manual/02-core-concepts/05-pagination-filtering.md +600 -0
- package/docs/user-manual/02-core-concepts/06-error-handling.md +718 -0
- package/docs/user-manual/02-core-concepts/07-api-coverage.md +483 -0
- package/docs/user-manual/03-email-operations/01-senders.md +490 -0
- package/docs/user-manual/03-email-operations/02-templates.md +444 -0
- package/docs/user-manual/03-email-operations/03-transactional-emails.md +706 -0
- package/docs/user-manual/03-email-operations/04-email-tracking.md +407 -0
- package/docs/user-manual/04-campaign-management/01-campaigns-basics.md +394 -0
- package/docs/user-manual/04-campaign-management/02-campaign-scheduling.md +630 -0
- package/docs/user-manual/04-campaign-management/03-campaign-testing.md +997 -0
- package/docs/user-manual/04-campaign-management/04-campaign-lifecycle.md +709 -0
- package/docs/user-manual/04-campaign-management/05-campaign-links.md +934 -0
- package/docs/user-manual/05-contact-management/01-lists.md +836 -0
- package/docs/user-manual/05-contact-management/02-contacts.md +1035 -0
- package/docs/user-manual/05-contact-management/03-custom-attributes.md +788 -0
- package/docs/user-manual/05-contact-management/04-segments.md +1028 -0
- package/docs/user-manual/05-contact-management/05-contact-import-export.md +1031 -0
- package/docs/user-manual/06-analytics-reporting/01-campaign-analytics.md +867 -0
- package/docs/user-manual/06-analytics-reporting/02-account-reports.md +227 -0
- package/docs/user-manual/07-integrations/01-webhooks-integration.md +259 -0
- package/docs/user-manual/07-integrations/02-automation.md +326 -0
- package/docs/user-manual/08-advanced-usage/01-scripting-patterns.md +672 -0
- package/docs/user-manual/08-advanced-usage/02-bulk-operations.md +932 -0
- package/docs/user-manual/08-advanced-usage/03-ci-cd-integration.md +892 -0
- package/docs/user-manual/08-advanced-usage/04-performance-optimization.md +766 -0
- package/docs/user-manual/09-command-reference/01-config.md +776 -0
- package/docs/user-manual/09-command-reference/02-account.md +652 -0
- package/docs/user-manual/09-command-reference/03-lists.md +958 -0
- package/docs/user-manual/09-command-reference/04-contacts.md +1408 -0
- package/docs/user-manual/09-command-reference/05-attributes.md +617 -0
- package/docs/user-manual/09-command-reference/06-segments.md +894 -0
- package/docs/user-manual/09-command-reference/07-senders.md +803 -0
- package/docs/user-manual/09-command-reference/08-templates.md +818 -0
- package/docs/user-manual/09-command-reference/09-campaigns.md +1250 -0
- package/docs/user-manual/09-command-reference/10-emails.md +807 -0
- package/docs/user-manual/09-command-reference/11-reports.md +1135 -0
- package/docs/user-manual/09-command-reference/12-webhooks.md +773 -0
- package/docs/user-manual/09-command-reference/13-suppressed.md +797 -0
- package/docs/user-manual/09-command-reference/14-interests.md +630 -0
- package/docs/user-manual/09-command-reference/15-tags.md +584 -0
- package/docs/user-manual/09-command-reference/16-logs.md +656 -0
- package/docs/user-manual/09-command-reference/17-transactional-templates.md +850 -0
- package/docs/user-manual/10-troubleshooting/01-common-errors.md +457 -0
- package/docs/user-manual/10-troubleshooting/02-authentication-issues.md +558 -0
- package/docs/user-manual/10-troubleshooting/03-connection-problems.md +634 -0
- package/docs/user-manual/10-troubleshooting/04-debugging.md +725 -0
- package/docs/user-manual/11-appendix/04-faq.md +484 -0
- package/docs/user-manual/11-appendix/05-glossary.md +250 -0
- package/docs/user-manual/README.md +0 -0
- package/package.json +13 -47
- package/src/cli.ts +125 -0
- package/src/client.ts +16 -0
- package/src/commands/account.ts +267 -0
- package/src/commands/accounts.ts +78 -0
- package/src/commands/actions.ts +249 -0
- package/src/commands/attributes.ts +139 -0
- package/src/commands/campaign-blueprints.ts +106 -0
- package/src/commands/campaigns.ts +469 -0
- package/src/commands/config.ts +77 -0
- package/src/commands/contacts.ts +612 -0
- package/src/commands/custom-attributes.ts +127 -0
- package/src/commands/dkims.ts +117 -0
- package/src/commands/domains.ts +82 -0
- package/src/commands/email-apis.ts +569 -0
- package/src/commands/emails.ts +197 -0
- package/src/commands/forms.ts +283 -0
- package/src/commands/interests.ts +155 -0
- package/src/commands/links.ts +38 -0
- package/src/commands/lists.ts +406 -0
- package/src/commands/logos.ts +71 -0
- package/src/commands/logs.ts +386 -0
- package/src/commands/reports.ts +306 -0
- package/src/commands/segments.ts +158 -0
- package/src/commands/senders.ts +204 -0
- package/src/commands/sub-accounts.ts +271 -0
- package/src/commands/suppressed-emails.ts +234 -0
- package/src/commands/suppressed.ts +198 -0
- package/src/commands/system-emails.ts +85 -0
- package/src/commands/tags.ts +146 -0
- package/src/commands/tasks.ts +116 -0
- package/src/commands/templates.ts +189 -0
- package/src/commands/tokens.ts +83 -0
- package/src/commands/transactional-emails.ts +374 -0
- package/src/commands/transactional-templates.ts +385 -0
- package/src/commands/users.ts +506 -0
- package/src/commands/webhooks.ts +172 -0
- package/src/commands/workflow-blueprints.ts +123 -0
- package/src/commands/workflows.ts +265 -0
- package/src/types/profile.ts +93 -0
- package/src/utils/auth.ts +272 -0
- package/src/utils/config-file.ts +96 -0
- package/src/utils/config.ts +134 -0
- package/src/utils/confirm.ts +32 -0
- package/src/utils/defaults.ts +99 -0
- package/src/utils/errors.ts +116 -0
- package/src/utils/interactive.ts +91 -0
- package/src/utils/list-defaults.ts +74 -0
- package/src/utils/output.ts +190 -0
- package/src/utils/progress.ts +320 -0
- package/src/utils/spinner.ts +22 -0
- package/tests/IMPLEMENTATION_STATUS.md +258 -0
- package/tests/PTY_SETUP.md +118 -0
- package/tests/PTY_TESTING_GUIDE.md +507 -0
- package/tests/README.md +244 -0
- package/tests/fixtures/api-responses/campaigns.json +34 -0
- package/tests/fixtures/test-config.json +13 -0
- package/tests/helpers/cli-runner.ts +128 -0
- package/tests/helpers/mock-server.ts +301 -0
- package/tests/helpers/pty-runner.ts +181 -0
- package/tests/integration/campaigns-real-api.test.ts +196 -0
- package/tests/integration/setup-integration.ts +50 -0
- package/tests/pty/campaigns.test.ts +241 -0
- package/tests/setup.ts +34 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +28 -0
|
@@ -0,0 +1,1121 @@
|
|
|
1
|
+
# Cakemail CLI - Profile-Based UX System Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Executive Summary
|
|
4
|
+
|
|
5
|
+
Create an adaptive CLI experience that automatically tailors its interface, output format, verbosity, and interactions based on user type (developer vs marketer) while remaining flexible enough for users to access any feature regardless of their profile.
|
|
6
|
+
|
|
7
|
+
## Core Principle
|
|
8
|
+
|
|
9
|
+
**Profiles are intelligent defaults, not restrictions.** Any user can access any feature; profiles simply optimize the default experience.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. User Profiles
|
|
14
|
+
|
|
15
|
+
### 1.1 Profile Types
|
|
16
|
+
|
|
17
|
+
#### Developer Profile
|
|
18
|
+
**Characteristics:**
|
|
19
|
+
- Comfortable with JSON, scripting, piping
|
|
20
|
+
- Values precision, completeness, composability
|
|
21
|
+
- Prefers minimal interactivity
|
|
22
|
+
- Expects standard exit codes and machine-readable output
|
|
23
|
+
|
|
24
|
+
**Default Settings:**
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"profile": "developer",
|
|
28
|
+
"output": {
|
|
29
|
+
"format": "json",
|
|
30
|
+
"colors": "minimal",
|
|
31
|
+
"pretty_print": false,
|
|
32
|
+
"show_tips": false
|
|
33
|
+
},
|
|
34
|
+
"behavior": {
|
|
35
|
+
"interactive_prompts": false,
|
|
36
|
+
"confirm_destructive": false,
|
|
37
|
+
"auto_open_browser": false,
|
|
38
|
+
"show_progress": false
|
|
39
|
+
},
|
|
40
|
+
"display": {
|
|
41
|
+
"date_format": "iso8601",
|
|
42
|
+
"show_ids": true,
|
|
43
|
+
"show_api_details": true,
|
|
44
|
+
"verbose_errors": true
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### Marketer Profile
|
|
50
|
+
**Characteristics:**
|
|
51
|
+
- Visual learners, appreciate color and formatting
|
|
52
|
+
- Values clarity, guidance, safety
|
|
53
|
+
- Comfortable with interactive workflows
|
|
54
|
+
- Prefers human-readable output
|
|
55
|
+
|
|
56
|
+
**Default Settings:**
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"profile": "marketer",
|
|
60
|
+
"output": {
|
|
61
|
+
"format": "compact",
|
|
62
|
+
"colors": "rich",
|
|
63
|
+
"pretty_print": true,
|
|
64
|
+
"show_tips": true
|
|
65
|
+
},
|
|
66
|
+
"behavior": {
|
|
67
|
+
"interactive_prompts": true,
|
|
68
|
+
"confirm_destructive": true,
|
|
69
|
+
"auto_open_browser": true,
|
|
70
|
+
"show_progress": true
|
|
71
|
+
},
|
|
72
|
+
"display": {
|
|
73
|
+
"date_format": "relative",
|
|
74
|
+
"show_ids": false,
|
|
75
|
+
"show_api_details": false,
|
|
76
|
+
"verbose_errors": false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Balanced Profile
|
|
82
|
+
**Characteristics:**
|
|
83
|
+
- Mix of both workflows
|
|
84
|
+
- Context-dependent preferences
|
|
85
|
+
- Default fallback
|
|
86
|
+
|
|
87
|
+
**Default Settings:**
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"profile": "balanced",
|
|
91
|
+
"output": {
|
|
92
|
+
"format": "table",
|
|
93
|
+
"colors": "moderate",
|
|
94
|
+
"pretty_print": true,
|
|
95
|
+
"show_tips": true
|
|
96
|
+
},
|
|
97
|
+
"behavior": {
|
|
98
|
+
"interactive_prompts": "auto",
|
|
99
|
+
"confirm_destructive": true,
|
|
100
|
+
"auto_open_browser": false,
|
|
101
|
+
"show_progress": true
|
|
102
|
+
},
|
|
103
|
+
"display": {
|
|
104
|
+
"date_format": "friendly",
|
|
105
|
+
"show_ids": true,
|
|
106
|
+
"show_api_details": false,
|
|
107
|
+
"verbose_errors": false
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 2. Profile Selection & Detection
|
|
115
|
+
|
|
116
|
+
### 2.1 Explicit Profile Selection
|
|
117
|
+
|
|
118
|
+
**During Initial Setup:**
|
|
119
|
+
```bash
|
|
120
|
+
$ cakemail auth setup
|
|
121
|
+
|
|
122
|
+
Welcome to Cakemail CLI! 👋
|
|
123
|
+
|
|
124
|
+
First, let's set up your authentication...
|
|
125
|
+
[auth flow]
|
|
126
|
+
|
|
127
|
+
✓ Authentication successful!
|
|
128
|
+
|
|
129
|
+
One more thing - what best describes how you'll use Cakemail?
|
|
130
|
+
|
|
131
|
+
1. 👨💻 Developer/Technical user
|
|
132
|
+
• Scripting and automation
|
|
133
|
+
• JSON output and piping
|
|
134
|
+
• Minimal interactivity
|
|
135
|
+
|
|
136
|
+
2. 📊 Marketer/Business user
|
|
137
|
+
• Campaign management
|
|
138
|
+
• Visual formatting and guides
|
|
139
|
+
• Interactive workflows
|
|
140
|
+
|
|
141
|
+
3. 🔄 Both/Balanced
|
|
142
|
+
• Mix of technical and business tasks
|
|
143
|
+
• Flexible workflow
|
|
144
|
+
|
|
145
|
+
Your choice (1-3): _
|
|
146
|
+
|
|
147
|
+
💡 You can change this anytime with: cakemail config profile <type>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 2.2 Auto-Detection (Optional Enhancement)
|
|
151
|
+
|
|
152
|
+
**Signals for Developer Profile:**
|
|
153
|
+
```javascript
|
|
154
|
+
function detectDeveloperSignals() {
|
|
155
|
+
const signals = [];
|
|
156
|
+
|
|
157
|
+
// Environment indicators
|
|
158
|
+
if (process.env.CI) signals.push({ score: 5, reason: 'CI environment' });
|
|
159
|
+
if (process.env.GITHUB_ACTIONS) signals.push({ score: 5, reason: 'GitHub Actions' });
|
|
160
|
+
if (!process.stdout.isTTY) signals.push({ score: 3, reason: 'Piped output' });
|
|
161
|
+
|
|
162
|
+
// Shell indicators
|
|
163
|
+
if (process.env.SHELL?.includes('zsh')) signals.push({ score: 1, reason: 'Zsh shell' });
|
|
164
|
+
if (process.env.TERM_PROGRAM === 'iTerm.app') signals.push({ score: 1, reason: 'iTerm' });
|
|
165
|
+
|
|
166
|
+
// Command history (if accessible)
|
|
167
|
+
// Check for: git, docker, npm, yarn, etc.
|
|
168
|
+
|
|
169
|
+
return signals;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function detectMarketerSignals() {
|
|
173
|
+
const signals = [];
|
|
174
|
+
|
|
175
|
+
// GUI indicators
|
|
176
|
+
if (process.env.DISPLAY) signals.push({ score: 2, reason: 'GUI display available' });
|
|
177
|
+
if (process.env.TERM_PROGRAM === 'Apple_Terminal') signals.push({ score: 1, reason: 'Terminal.app' });
|
|
178
|
+
|
|
179
|
+
// First-time user (no command history)
|
|
180
|
+
signals.push({ score: 1, reason: 'New user' });
|
|
181
|
+
|
|
182
|
+
return signals;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function autoDetectProfile() {
|
|
186
|
+
const devScore = detectDeveloperSignals().reduce((sum, s) => sum + s.score, 0);
|
|
187
|
+
const markScore = detectMarketerSignals().reduce((sum, s) => sum + s.score, 0);
|
|
188
|
+
|
|
189
|
+
if (devScore > markScore + 3) return 'developer';
|
|
190
|
+
if (markScore > devScore + 1) return 'marketer';
|
|
191
|
+
return 'balanced';
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Suggested Profile (Don't Auto-Apply):**
|
|
196
|
+
```bash
|
|
197
|
+
$ cakemail auth setup
|
|
198
|
+
# After auth...
|
|
199
|
+
|
|
200
|
+
💡 Based on your environment, we recommend the "Developer" profile.
|
|
201
|
+
Would you like to use this? [Y/n] _
|
|
202
|
+
|
|
203
|
+
(Or choose: 1=Developer, 2=Marketer, 3=Balanced)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 3. Profile-Aware Output
|
|
209
|
+
|
|
210
|
+
### 3.1 Output Formats by Profile
|
|
211
|
+
|
|
212
|
+
#### Developer: JSON (default)
|
|
213
|
+
```bash
|
|
214
|
+
$ cakemail campaigns list
|
|
215
|
+
[
|
|
216
|
+
{
|
|
217
|
+
"id": 123,
|
|
218
|
+
"name": "Black Friday Sale",
|
|
219
|
+
"status": "delivered",
|
|
220
|
+
"created_at": "2025-10-10T08:00:00Z",
|
|
221
|
+
"sent_at": "2025-10-11T12:00:00Z",
|
|
222
|
+
"list_id": 456,
|
|
223
|
+
"stats": {
|
|
224
|
+
"delivered": 15234,
|
|
225
|
+
"opened": 3656,
|
|
226
|
+
"clicked": 892
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Features:**
|
|
233
|
+
- No pretty printing (compact JSON for piping)
|
|
234
|
+
- All fields included
|
|
235
|
+
- ISO 8601 timestamps
|
|
236
|
+
- Exit code: 0 (success), non-zero (error)
|
|
237
|
+
|
|
238
|
+
#### Marketer: Compact (default)
|
|
239
|
+
```bash
|
|
240
|
+
$ cakemail campaigns list
|
|
241
|
+
|
|
242
|
+
📧 Recent Campaigns
|
|
243
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
244
|
+
|
|
245
|
+
✅ Black Friday Sale
|
|
246
|
+
Sent 2 hours ago • 15,234 delivered • 24% opened • 6% clicked
|
|
247
|
+
|
|
248
|
+
⏰ Weekly Newsletter
|
|
249
|
+
Scheduled for tomorrow at 10:00 AM • 8,500 recipients
|
|
250
|
+
|
|
251
|
+
📝 Product Launch
|
|
252
|
+
Draft • Last edited yesterday
|
|
253
|
+
|
|
254
|
+
🗄 Summer Sale (archived)
|
|
255
|
+
Sent Jun 15 • 12,100 delivered • 31% opened
|
|
256
|
+
|
|
257
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
258
|
+
Showing 4 campaigns • Use --all to see more
|
|
259
|
+
|
|
260
|
+
💡 Tip: Use 'cakemail campaigns get 123' to see full details
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Features:**
|
|
264
|
+
- Emoji status indicators (✅ ⏰ 📝 🗄 ❌)
|
|
265
|
+
- Relative timestamps ("2 hours ago")
|
|
266
|
+
- Percentage calculations shown
|
|
267
|
+
- Contextual tips
|
|
268
|
+
- Visual separators
|
|
269
|
+
|
|
270
|
+
#### Balanced: Table (default)
|
|
271
|
+
```bash
|
|
272
|
+
$ cakemail campaigns list
|
|
273
|
+
|
|
274
|
+
ID Name Status Sent Delivered Opens
|
|
275
|
+
────────────────────────────────────────────────────────────────────────
|
|
276
|
+
123 Black Friday Sale delivered 2 hours ago 15,234 24%
|
|
277
|
+
456 Weekly Newsletter scheduled Tomorrow 10:00am 8,500 -
|
|
278
|
+
789 Product Launch draft - - -
|
|
279
|
+
321 Summer Sale archived Jun 15 12,100 31%
|
|
280
|
+
|
|
281
|
+
4 campaigns total
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Features:**
|
|
285
|
+
- Table format with key fields
|
|
286
|
+
- Mix of relative and absolute dates
|
|
287
|
+
- Color coding (green=delivered, yellow=scheduled, gray=draft)
|
|
288
|
+
- Balanced information density
|
|
289
|
+
|
|
290
|
+
### 3.2 Error Messages by Profile
|
|
291
|
+
|
|
292
|
+
#### Developer Profile
|
|
293
|
+
```bash
|
|
294
|
+
$ cakemail campaigns send 999
|
|
295
|
+
|
|
296
|
+
Error: Campaign not found (404)
|
|
297
|
+
|
|
298
|
+
Details:
|
|
299
|
+
Request: GET /api/v1/campaigns/999
|
|
300
|
+
Response: {"error": "not_found", "message": "Campaign with ID 999 does not exist"}
|
|
301
|
+
|
|
302
|
+
Suggestions:
|
|
303
|
+
• List available campaigns: cakemail campaigns list
|
|
304
|
+
• Check campaign ID is correct
|
|
305
|
+
|
|
306
|
+
Exit code: 3
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
#### Marketer Profile
|
|
310
|
+
```bash
|
|
311
|
+
$ cakemail campaigns send 999
|
|
312
|
+
|
|
313
|
+
❌ Oops! We couldn't find that campaign.
|
|
314
|
+
|
|
315
|
+
The campaign with ID 999 doesn't exist in your account.
|
|
316
|
+
|
|
317
|
+
What you can do:
|
|
318
|
+
📋 View all campaigns: cakemail campaigns list
|
|
319
|
+
🔍 Search campaigns: cakemail campaigns find "keyword"
|
|
320
|
+
|
|
321
|
+
Need help? Visit: https://support.cakemail.com
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### 3.3 Help Content by Profile
|
|
325
|
+
|
|
326
|
+
#### Developer Profile
|
|
327
|
+
```bash
|
|
328
|
+
$ cakemail campaigns --help
|
|
329
|
+
|
|
330
|
+
SYNOPSIS
|
|
331
|
+
cakemail campaigns <command> [options]
|
|
332
|
+
|
|
333
|
+
COMMANDS
|
|
334
|
+
list List campaigns with filtering
|
|
335
|
+
get <id> Get campaign details
|
|
336
|
+
create Create new campaign
|
|
337
|
+
update <id> Update campaign
|
|
338
|
+
schedule <id> Schedule campaign
|
|
339
|
+
send <id> Send campaign immediately
|
|
340
|
+
delete <id> Delete campaign
|
|
341
|
+
|
|
342
|
+
OPTIONS
|
|
343
|
+
-f, --format <type> Output format: json|table|compact (default: json)
|
|
344
|
+
--filter <expr> Filter expression: status==delivered;name==Newsletter
|
|
345
|
+
--sort <field> Sort: +name, -created_on, +sent_at
|
|
346
|
+
-l, --limit <n> Limit results (default: 50)
|
|
347
|
+
-p, --page <n> Page number (default: 1)
|
|
348
|
+
|
|
349
|
+
EXAMPLES
|
|
350
|
+
# List delivered campaigns as JSON
|
|
351
|
+
cakemail campaigns list --filter "status==delivered" -f json
|
|
352
|
+
|
|
353
|
+
# Get campaign and extract name with jq
|
|
354
|
+
cakemail campaigns get 123 | jq -r '.name'
|
|
355
|
+
|
|
356
|
+
# Schedule campaign for specific time
|
|
357
|
+
cakemail campaigns schedule 123 -d "2025-10-15T10:00:00Z"
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### Marketer Profile
|
|
361
|
+
```bash
|
|
362
|
+
$ cakemail campaigns --help
|
|
363
|
+
|
|
364
|
+
📧 Campaign Management
|
|
365
|
+
|
|
366
|
+
Common Tasks:
|
|
367
|
+
|
|
368
|
+
📋 View all campaigns
|
|
369
|
+
cakemail campaigns list
|
|
370
|
+
|
|
371
|
+
👁 View campaign details
|
|
372
|
+
cakemail campaigns get <campaign-id>
|
|
373
|
+
|
|
374
|
+
📝 Create a new campaign
|
|
375
|
+
cakemail campaigns create
|
|
376
|
+
|
|
377
|
+
⏰ Schedule a campaign
|
|
378
|
+
cakemail campaigns schedule <campaign-id> --when "tomorrow 10am"
|
|
379
|
+
|
|
380
|
+
📤 Send a campaign now
|
|
381
|
+
cakemail campaigns send <campaign-id>
|
|
382
|
+
|
|
383
|
+
Examples:
|
|
384
|
+
|
|
385
|
+
See your recent campaigns:
|
|
386
|
+
cakemail campaigns list
|
|
387
|
+
|
|
388
|
+
Schedule a campaign for next Monday:
|
|
389
|
+
cakemail campaigns schedule 123 --when "next monday 10am"
|
|
390
|
+
|
|
391
|
+
Send a test before scheduling:
|
|
392
|
+
cakemail campaigns test 123 --email your@email.com
|
|
393
|
+
|
|
394
|
+
💡 Tip: Most commands work interactively - just leave out the options
|
|
395
|
+
and we'll ask you what you need!
|
|
396
|
+
|
|
397
|
+
Need more help? Visit: https://docs.cakemail.com
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## 4. Behavior Adaptations
|
|
403
|
+
|
|
404
|
+
### 4.1 Interactive Prompts
|
|
405
|
+
|
|
406
|
+
#### Developer Profile: Minimal/No Prompts
|
|
407
|
+
```bash
|
|
408
|
+
$ cakemail campaigns create
|
|
409
|
+
Error: Missing required argument: --name
|
|
410
|
+
|
|
411
|
+
Usage: cakemail campaigns create --name <name> --list-id <id> [options]
|
|
412
|
+
|
|
413
|
+
See 'cakemail campaigns create --help' for more information
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
#### Marketer Profile: Full Interactive
|
|
417
|
+
```bash
|
|
418
|
+
$ cakemail campaigns create
|
|
419
|
+
|
|
420
|
+
📝 Create New Campaign
|
|
421
|
+
━━━━━━━━━━━━━━━━━━━━━━━━
|
|
422
|
+
|
|
423
|
+
Campaign name: _
|
|
424
|
+
(e.g., "Weekly Newsletter - October 2025")
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
After entering name:
|
|
428
|
+
```bash
|
|
429
|
+
Campaign name: Weekly Newsletter ✓
|
|
430
|
+
|
|
431
|
+
Which list should receive this campaign?
|
|
432
|
+
|
|
433
|
+
1. 📧 Newsletter Subscribers (5,234 contacts)
|
|
434
|
+
Last updated: 2 days ago
|
|
435
|
+
|
|
436
|
+
2. 👥 Customers (1,847 contacts)
|
|
437
|
+
Last updated: 1 week ago
|
|
438
|
+
|
|
439
|
+
3. 🎯 VIP List (234 contacts)
|
|
440
|
+
Last updated: yesterday
|
|
441
|
+
|
|
442
|
+
Choose (1-3) or type to search: _
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### 4.2 Confirmation Dialogs
|
|
446
|
+
|
|
447
|
+
#### Developer Profile: No Confirmation (unless --confirm)
|
|
448
|
+
```bash
|
|
449
|
+
$ cakemail campaigns delete 123
|
|
450
|
+
Campaign 123 deleted successfully
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
#### Marketer Profile: Always Confirm Destructive Actions
|
|
454
|
+
```bash
|
|
455
|
+
$ cakemail campaigns delete 123
|
|
456
|
+
|
|
457
|
+
⚠️ Delete Campaign?
|
|
458
|
+
|
|
459
|
+
Campaign: "Black Friday Sale"
|
|
460
|
+
Status: Delivered
|
|
461
|
+
Sent to: 15,234 contacts
|
|
462
|
+
Sent at: Oct 11, 2025 12:00 PM
|
|
463
|
+
|
|
464
|
+
⚠️ This action cannot be undone!
|
|
465
|
+
|
|
466
|
+
Type the campaign name to confirm: _
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### 4.3 Progress Indicators
|
|
470
|
+
|
|
471
|
+
#### Developer Profile: No Progress (unless --verbose)
|
|
472
|
+
```bash
|
|
473
|
+
$ cakemail campaigns send 123
|
|
474
|
+
Campaign 123 sent successfully (delivered: 8234)
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
#### Marketer Profile: Rich Progress
|
|
478
|
+
```bash
|
|
479
|
+
$ cakemail campaigns send 123
|
|
480
|
+
|
|
481
|
+
📤 Sending Campaign...
|
|
482
|
+
|
|
483
|
+
✓ Validating campaign content
|
|
484
|
+
✓ Verifying sender email
|
|
485
|
+
✓ Preparing recipient list (8,234 contacts)
|
|
486
|
+
⏳ Sending emails... ████████████░░░░░░░░ 65% (5,352/8,234)
|
|
487
|
+
|
|
488
|
+
Press Ctrl+C to cancel
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## 5. Profile Management Commands
|
|
494
|
+
|
|
495
|
+
### 5.1 View Current Profile
|
|
496
|
+
```bash
|
|
497
|
+
$ cakemail config profile
|
|
498
|
+
|
|
499
|
+
Current profile: marketer
|
|
500
|
+
|
|
501
|
+
Active settings:
|
|
502
|
+
Output format: compact
|
|
503
|
+
Colors: rich
|
|
504
|
+
Interactive prompts: enabled
|
|
505
|
+
Date format: relative ("2 hours ago")
|
|
506
|
+
Show tips: enabled
|
|
507
|
+
|
|
508
|
+
Change profile: cakemail config profile <developer|marketer|balanced>
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### 5.2 Switch Profiles
|
|
512
|
+
```bash
|
|
513
|
+
$ cakemail config profile developer
|
|
514
|
+
|
|
515
|
+
✓ Switched to developer profile
|
|
516
|
+
|
|
517
|
+
Changes applied:
|
|
518
|
+
• Output format: json (was: compact)
|
|
519
|
+
• Interactive mode: disabled (was: enabled)
|
|
520
|
+
• Colors: minimal (was: rich)
|
|
521
|
+
• Show tips: disabled (was: enabled)
|
|
522
|
+
|
|
523
|
+
Try it: cakemail campaigns list
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### 5.3 Customize Profile
|
|
527
|
+
```bash
|
|
528
|
+
$ cakemail config set output.format table
|
|
529
|
+
✓ Output format set to 'table' (overrides profile default)
|
|
530
|
+
|
|
531
|
+
$ cakemail config set behavior.interactive_prompts false
|
|
532
|
+
✓ Interactive prompts disabled (overrides profile default)
|
|
533
|
+
|
|
534
|
+
$ cakemail config reset
|
|
535
|
+
⚠️ Reset all settings to profile defaults? [y/N] y
|
|
536
|
+
✓ Settings reset to 'marketer' profile defaults
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### 5.4 Profile Override (Temporary)
|
|
540
|
+
```bash
|
|
541
|
+
# Use developer mode for single command
|
|
542
|
+
$ cakemail --profile developer campaigns list
|
|
543
|
+
[{"id": 123, ...}]
|
|
544
|
+
|
|
545
|
+
# Use marketer mode for single command
|
|
546
|
+
$ cakemail --profile marketer campaigns list
|
|
547
|
+
📧 Recent Campaigns
|
|
548
|
+
━━━━━━━━━━━━━━━━━━━━━━
|
|
549
|
+
...
|
|
550
|
+
|
|
551
|
+
# Override specific settings
|
|
552
|
+
$ cakemail --format json --no-colors campaigns list
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## 6. Context-Aware Features
|
|
558
|
+
|
|
559
|
+
### 6.1 Smart Command Detection
|
|
560
|
+
|
|
561
|
+
**Detect Scripting Context:**
|
|
562
|
+
```javascript
|
|
563
|
+
function isScriptingContext() {
|
|
564
|
+
return (
|
|
565
|
+
!process.stdout.isTTY || // Output is piped
|
|
566
|
+
process.env.CI || // In CI/CD
|
|
567
|
+
process.argv.includes('--quiet') || // Explicit quiet mode
|
|
568
|
+
process.argv.includes('-q')
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Auto-disable interactive features in scripts
|
|
573
|
+
if (isScriptingContext() && profile === 'marketer') {
|
|
574
|
+
config.behavior.interactive_prompts = false;
|
|
575
|
+
config.output.colors = 'none';
|
|
576
|
+
config.output.show_tips = false;
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### 6.2 Adaptive Help
|
|
581
|
+
|
|
582
|
+
**Short Help for Developers:**
|
|
583
|
+
```bash
|
|
584
|
+
$ cakemail campaigns
|
|
585
|
+
Usage: cakemail campaigns <command>
|
|
586
|
+
|
|
587
|
+
Commands: list, get, create, update, schedule, send, delete
|
|
588
|
+
|
|
589
|
+
See 'cakemail campaigns --help' for details
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
**Guided Help for Marketers:**
|
|
593
|
+
```bash
|
|
594
|
+
$ cakemail campaigns
|
|
595
|
+
|
|
596
|
+
📧 Campaign Commands
|
|
597
|
+
|
|
598
|
+
What would you like to do?
|
|
599
|
+
|
|
600
|
+
1. 📋 View all campaigns
|
|
601
|
+
2. 📝 Create a new campaign
|
|
602
|
+
3. ⏰ Schedule a campaign
|
|
603
|
+
4. 📤 Send a campaign
|
|
604
|
+
5. 🔍 Search campaigns
|
|
605
|
+
|
|
606
|
+
Or type 'help' for full command list
|
|
607
|
+
|
|
608
|
+
Choose (1-5): _
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### 6.3 Date Input by Profile
|
|
612
|
+
|
|
613
|
+
#### Developer Profile: Accept ISO 8601
|
|
614
|
+
```bash
|
|
615
|
+
$ cakemail campaigns schedule 123 -d "2025-10-15T10:00:00Z"
|
|
616
|
+
✓ Campaign scheduled for 2025-10-15T10:00:00Z
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
#### Marketer Profile: Accept Natural Language
|
|
620
|
+
```bash
|
|
621
|
+
$ cakemail campaigns schedule 123 --when "tomorrow 10am"
|
|
622
|
+
|
|
623
|
+
⏰ Scheduling Campaign
|
|
624
|
+
|
|
625
|
+
Campaign: "Weekly Newsletter"
|
|
626
|
+
Send at: Oct 12, 2025 at 10:00 AM EDT
|
|
627
|
+
(tomorrow at 10:00 AM)
|
|
628
|
+
|
|
629
|
+
Recipients: 8,234 contacts
|
|
630
|
+
|
|
631
|
+
Confirm? [Y/n] _
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
636
|
+
## 7. Implementation Plan
|
|
637
|
+
|
|
638
|
+
### Phase 1: Foundation (Week 1-2)
|
|
639
|
+
|
|
640
|
+
**Goals:**
|
|
641
|
+
- Profile selection during setup
|
|
642
|
+
- Profile storage in config
|
|
643
|
+
- Basic profile loading
|
|
644
|
+
|
|
645
|
+
**Tasks:**
|
|
646
|
+
1. Create profile schema and defaults
|
|
647
|
+
2. Add profile selection to `cakemail auth setup`
|
|
648
|
+
3. Implement config storage (`~/.cakemail/config.json`)
|
|
649
|
+
4. Create profile loading mechanism
|
|
650
|
+
5. Add `cakemail config profile` commands
|
|
651
|
+
|
|
652
|
+
**Deliverables:**
|
|
653
|
+
- Users can select and switch profiles
|
|
654
|
+
- Profile preferences are stored and loaded
|
|
655
|
+
- Basic profile management commands work
|
|
656
|
+
|
|
657
|
+
### Phase 2: Output Adaptation (Week 3-4)
|
|
658
|
+
|
|
659
|
+
**Goals:**
|
|
660
|
+
- Different output formats per profile
|
|
661
|
+
- Profile-aware error messages
|
|
662
|
+
- Profile-specific help text
|
|
663
|
+
|
|
664
|
+
**Tasks:**
|
|
665
|
+
1. Create output formatter with profile awareness
|
|
666
|
+
2. Implement profile-specific error translation
|
|
667
|
+
3. Build adaptive help system
|
|
668
|
+
4. Add color scheme per profile
|
|
669
|
+
5. Implement date formatting per profile
|
|
670
|
+
|
|
671
|
+
**Deliverables:**
|
|
672
|
+
- Commands show different output based on profile
|
|
673
|
+
- Errors are formatted per user type
|
|
674
|
+
- Help text adapts to profile
|
|
675
|
+
|
|
676
|
+
### Phase 3: Behavior Adaptation (Week 5-6)
|
|
677
|
+
|
|
678
|
+
**Goals:**
|
|
679
|
+
- Interactive prompts for marketers
|
|
680
|
+
- Confirmation dialogs based on profile
|
|
681
|
+
- Progress indicators for marketers
|
|
682
|
+
|
|
683
|
+
**Tasks:**
|
|
684
|
+
1. Build interactive prompt system (using `inquirer`)
|
|
685
|
+
2. Implement confirmation dialogs for destructive ops
|
|
686
|
+
3. Add progress indicators with profile awareness
|
|
687
|
+
4. Create wizard flows for common tasks
|
|
688
|
+
5. Add auto-detection logic (optional)
|
|
689
|
+
|
|
690
|
+
**Deliverables:**
|
|
691
|
+
- Marketer profile has guided workflows
|
|
692
|
+
- Developer profile is scriptable
|
|
693
|
+
- Destructive actions have appropriate safeguards
|
|
694
|
+
|
|
695
|
+
### Phase 4: Polish & Testing (Week 7-8)
|
|
696
|
+
|
|
697
|
+
**Goals:**
|
|
698
|
+
- Profile override flags working
|
|
699
|
+
- Context detection (CI, piping, etc.)
|
|
700
|
+
- Comprehensive testing
|
|
701
|
+
|
|
702
|
+
**Tasks:**
|
|
703
|
+
1. Implement `--profile` flag for command override
|
|
704
|
+
2. Add scripting context detection
|
|
705
|
+
3. Create profile switching migration guide
|
|
706
|
+
4. Write tests for each profile mode
|
|
707
|
+
5. User testing with both personas
|
|
708
|
+
|
|
709
|
+
**Deliverables:**
|
|
710
|
+
- Profile system is production-ready
|
|
711
|
+
- Both developer and marketer workflows tested
|
|
712
|
+
- Documentation complete
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
716
|
+
## 8. Configuration Schema
|
|
717
|
+
|
|
718
|
+
### 8.1 Config File Structure
|
|
719
|
+
```json
|
|
720
|
+
{
|
|
721
|
+
"version": "1.0",
|
|
722
|
+
"profile": "marketer",
|
|
723
|
+
"auth": {
|
|
724
|
+
"method": "password",
|
|
725
|
+
"email": "user@example.com",
|
|
726
|
+
"token": "encrypted_token_here"
|
|
727
|
+
},
|
|
728
|
+
"profiles": {
|
|
729
|
+
"developer": {
|
|
730
|
+
"output": {
|
|
731
|
+
"format": "json",
|
|
732
|
+
"colors": "minimal",
|
|
733
|
+
"pretty_print": false,
|
|
734
|
+
"show_tips": false
|
|
735
|
+
},
|
|
736
|
+
"behavior": {
|
|
737
|
+
"interactive_prompts": false,
|
|
738
|
+
"confirm_destructive": false,
|
|
739
|
+
"auto_open_browser": false,
|
|
740
|
+
"show_progress": false
|
|
741
|
+
},
|
|
742
|
+
"display": {
|
|
743
|
+
"date_format": "iso8601",
|
|
744
|
+
"show_ids": true,
|
|
745
|
+
"show_api_details": true,
|
|
746
|
+
"verbose_errors": true
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
"marketer": {
|
|
750
|
+
"output": {
|
|
751
|
+
"format": "compact",
|
|
752
|
+
"colors": "rich",
|
|
753
|
+
"pretty_print": true,
|
|
754
|
+
"show_tips": true
|
|
755
|
+
},
|
|
756
|
+
"behavior": {
|
|
757
|
+
"interactive_prompts": true,
|
|
758
|
+
"confirm_destructive": true,
|
|
759
|
+
"auto_open_browser": true,
|
|
760
|
+
"show_progress": true
|
|
761
|
+
},
|
|
762
|
+
"display": {
|
|
763
|
+
"date_format": "relative",
|
|
764
|
+
"show_ids": false,
|
|
765
|
+
"show_api_details": false,
|
|
766
|
+
"verbose_errors": false
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
"custom": {
|
|
770
|
+
// User overrides stored here
|
|
771
|
+
"output": {
|
|
772
|
+
"format": "table" // Custom override
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
},
|
|
776
|
+
"defaults": {
|
|
777
|
+
"list_id": 123,
|
|
778
|
+
"sender_id": 456
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
### 8.2 Priority Order
|
|
784
|
+
```
|
|
785
|
+
1. Command-line flags (--format json)
|
|
786
|
+
2. Profile override flag (--profile developer)
|
|
787
|
+
3. Custom profile settings (config.profiles.custom)
|
|
788
|
+
4. Active profile settings (config.profiles[config.profile])
|
|
789
|
+
5. Hard-coded defaults
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
## 9. Testing Strategy
|
|
795
|
+
|
|
796
|
+
### 9.1 Unit Tests
|
|
797
|
+
```javascript
|
|
798
|
+
describe('Profile System', () => {
|
|
799
|
+
describe('Profile Loading', () => {
|
|
800
|
+
test('loads developer profile defaults', () => {
|
|
801
|
+
const config = loadProfile('developer');
|
|
802
|
+
expect(config.output.format).toBe('json');
|
|
803
|
+
expect(config.behavior.interactive_prompts).toBe(false);
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
test('loads marketer profile defaults', () => {
|
|
807
|
+
const config = loadProfile('marketer');
|
|
808
|
+
expect(config.output.format).toBe('compact');
|
|
809
|
+
expect(config.behavior.interactive_prompts).toBe(true);
|
|
810
|
+
});
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
describe('Profile Override', () => {
|
|
814
|
+
test('command flag overrides profile', () => {
|
|
815
|
+
const config = loadProfile('marketer');
|
|
816
|
+
const overridden = applyOverrides(config, { format: 'json' });
|
|
817
|
+
expect(overridden.output.format).toBe('json');
|
|
818
|
+
});
|
|
819
|
+
});
|
|
820
|
+
});
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
### 9.2 Integration Tests
|
|
824
|
+
```javascript
|
|
825
|
+
describe('Profile-Aware Commands', () => {
|
|
826
|
+
test('developer profile outputs JSON by default', async () => {
|
|
827
|
+
setProfile('developer');
|
|
828
|
+
const output = await exec('cakemail campaigns list');
|
|
829
|
+
expect(() => JSON.parse(output)).not.toThrow();
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
test('marketer profile outputs formatted text', async () => {
|
|
833
|
+
setProfile('marketer');
|
|
834
|
+
const output = await exec('cakemail campaigns list');
|
|
835
|
+
expect(output).toContain('📧 Recent Campaigns');
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
test('--profile flag overrides current profile', async () => {
|
|
839
|
+
setProfile('marketer');
|
|
840
|
+
const output = await exec('cakemail --profile developer campaigns list');
|
|
841
|
+
expect(() => JSON.parse(output)).not.toThrow();
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
### 9.3 User Acceptance Testing
|
|
847
|
+
|
|
848
|
+
**Developer Persona Testing:**
|
|
849
|
+
- ✅ Can pipe output to jq without issues
|
|
850
|
+
- ✅ Receives only necessary output (no tips/hints)
|
|
851
|
+
- ✅ Can script complex workflows
|
|
852
|
+
- ✅ Error messages include API details
|
|
853
|
+
- ✅ No interactive prompts interrupt automation
|
|
854
|
+
|
|
855
|
+
**Marketer Persona Testing:**
|
|
856
|
+
- ✅ Understands output without technical knowledge
|
|
857
|
+
- ✅ Interactive wizards guide through tasks
|
|
858
|
+
- ✅ Receives helpful tips and suggestions
|
|
859
|
+
- ✅ Can complete tasks without reading docs
|
|
860
|
+
- ✅ Destructive actions require confirmation
|
|
861
|
+
|
|
862
|
+
---
|
|
863
|
+
|
|
864
|
+
## 10. Migration & Rollout
|
|
865
|
+
|
|
866
|
+
### 10.1 Existing Users
|
|
867
|
+
|
|
868
|
+
**First run after update:**
|
|
869
|
+
```bash
|
|
870
|
+
$ cakemail campaigns list
|
|
871
|
+
|
|
872
|
+
🎉 New: Profile-based experience!
|
|
873
|
+
|
|
874
|
+
We've added profiles to optimize Cakemail CLI for your workflow.
|
|
875
|
+
|
|
876
|
+
Based on your usage, we recommend: Developer profile
|
|
877
|
+
• JSON output by default
|
|
878
|
+
• Optimized for scripting
|
|
879
|
+
• Minimal interactivity
|
|
880
|
+
|
|
881
|
+
Would you like to:
|
|
882
|
+
1. Use Developer profile (recommended)
|
|
883
|
+
2. Use Marketer profile
|
|
884
|
+
3. Use Balanced profile
|
|
885
|
+
4. Keep current settings (no profile)
|
|
886
|
+
|
|
887
|
+
Choose (1-4): _
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
### 10.2 New Users
|
|
891
|
+
|
|
892
|
+
**Integrated into onboarding:**
|
|
893
|
+
```bash
|
|
894
|
+
$ cakemail auth setup
|
|
895
|
+
# Profile selection happens during initial setup
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
### 10.3 Opt-Out Option
|
|
899
|
+
|
|
900
|
+
**Users can disable profiles:**
|
|
901
|
+
```bash
|
|
902
|
+
$ cakemail config profile none
|
|
903
|
+
✓ Profiles disabled - using classic mode
|
|
904
|
+
|
|
905
|
+
All settings will use defaults or explicit flags.
|
|
906
|
+
Re-enable with: cakemail config profile <type>
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
---
|
|
910
|
+
|
|
911
|
+
## 11. Success Metrics
|
|
912
|
+
|
|
913
|
+
### 11.1 Quantitative Metrics
|
|
914
|
+
- **Profile adoption rate**: % of users who select a profile
|
|
915
|
+
- **Profile retention**: % users who keep their profile vs switching
|
|
916
|
+
- **Feature usage by profile**:
|
|
917
|
+
- Interactive mode usage (marketers)
|
|
918
|
+
- Piping/scripting usage (developers)
|
|
919
|
+
- **Error rate reduction**: Fewer errors after profile-aware messaging
|
|
920
|
+
- **Time to first success**: Time for new users to send first email
|
|
921
|
+
|
|
922
|
+
### 11.2 Qualitative Metrics
|
|
923
|
+
- User feedback on profile appropriateness
|
|
924
|
+
- Support ticket reduction related to "how do I..."
|
|
925
|
+
- User testimonials from both personas
|
|
926
|
+
- Community engagement (GitHub issues, discussions)
|
|
927
|
+
|
|
928
|
+
### 11.3 Success Criteria
|
|
929
|
+
- ✅ 70%+ of users select a profile during onboarding
|
|
930
|
+
- ✅ 80%+ of marketers use interactive mode
|
|
931
|
+
- ✅ 80%+ of developers use JSON output with piping
|
|
932
|
+
- ✅ 30% reduction in basic "how to" support questions
|
|
933
|
+
- ✅ 4+ star average rating from both personas
|
|
934
|
+
|
|
935
|
+
---
|
|
936
|
+
|
|
937
|
+
## 12. Documentation Requirements
|
|
938
|
+
|
|
939
|
+
### 12.1 User Docs
|
|
940
|
+
|
|
941
|
+
**For Marketers:**
|
|
942
|
+
- Visual guide with screenshots
|
|
943
|
+
- Step-by-step tutorials
|
|
944
|
+
- Video walkthroughs
|
|
945
|
+
- "Common tasks" cookbook
|
|
946
|
+
|
|
947
|
+
**For Developers:**
|
|
948
|
+
- API reference style docs
|
|
949
|
+
- Scripting examples
|
|
950
|
+
- Integration guides
|
|
951
|
+
- JSON schema documentation
|
|
952
|
+
|
|
953
|
+
### 12.2 In-CLI Help
|
|
954
|
+
|
|
955
|
+
**Profile-aware examples in help:**
|
|
956
|
+
```bash
|
|
957
|
+
# Developer help shows scriptable examples
|
|
958
|
+
$ cakemail campaigns create --help
|
|
959
|
+
Examples:
|
|
960
|
+
cakemail campaigns create \
|
|
961
|
+
--name "Weekly" \
|
|
962
|
+
--list-id 123 \
|
|
963
|
+
--template-id 456 \
|
|
964
|
+
--format json | jq -r '.id'
|
|
965
|
+
|
|
966
|
+
# Marketer help shows interactive examples
|
|
967
|
+
$ cakemail campaigns create --help
|
|
968
|
+
Examples:
|
|
969
|
+
Create a campaign interactively:
|
|
970
|
+
cakemail campaigns create
|
|
971
|
+
|
|
972
|
+
Create with basic info (we'll ask for the rest):
|
|
973
|
+
cakemail campaigns create --name "Weekly Newsletter"
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
---
|
|
977
|
+
|
|
978
|
+
## 13. Future Enhancements
|
|
979
|
+
|
|
980
|
+
### 13.1 Advanced Auto-Detection
|
|
981
|
+
- Machine learning from usage patterns
|
|
982
|
+
- Automatic profile switching based on context
|
|
983
|
+
- Team-wide profile recommendations
|
|
984
|
+
|
|
985
|
+
### 13.2 Custom Profiles
|
|
986
|
+
```bash
|
|
987
|
+
$ cakemail config profile create automation
|
|
988
|
+
Based on: developer
|
|
989
|
+
Name: automation
|
|
990
|
+
|
|
991
|
+
$ cakemail config profile automation set output.format json
|
|
992
|
+
$ cakemail config profile automation set behavior.show_progress true
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
### 13.3 Profile Sharing
|
|
996
|
+
```bash
|
|
997
|
+
# Export profile for team
|
|
998
|
+
$ cakemail config profile export > team-profile.json
|
|
999
|
+
|
|
1000
|
+
# Import profile
|
|
1001
|
+
$ cakemail config profile import team-profile.json
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
### 13.4 Context-Aware Profiles
|
|
1005
|
+
```bash
|
|
1006
|
+
# Auto-switch based on directory
|
|
1007
|
+
# .cakemail/config in project root:
|
|
1008
|
+
{
|
|
1009
|
+
"profile": "developer", // Use developer mode in this project
|
|
1010
|
+
"defaults": {
|
|
1011
|
+
"list_id": 123
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
---
|
|
1017
|
+
|
|
1018
|
+
## 14. Risk Mitigation
|
|
1019
|
+
|
|
1020
|
+
### 14.1 Risks & Mitigation
|
|
1021
|
+
|
|
1022
|
+
**Risk: Users confused by profile selection**
|
|
1023
|
+
- Mitigation: Clear descriptions, auto-detection with suggestions
|
|
1024
|
+
- Fallback: "Balanced" profile as safe default
|
|
1025
|
+
|
|
1026
|
+
**Risk: Profiles too restrictive**
|
|
1027
|
+
- Mitigation: Easy override flags, profile switching
|
|
1028
|
+
- Fallback: "None" option to disable profiles
|
|
1029
|
+
|
|
1030
|
+
**Risk: Breaking existing scripts**
|
|
1031
|
+
- Mitigation: Only apply to new users, migration opt-in
|
|
1032
|
+
- Fallback: `--classic` flag to use old behavior
|
|
1033
|
+
|
|
1034
|
+
**Risk: Maintenance complexity**
|
|
1035
|
+
- Mitigation: Shared output formatter, test coverage
|
|
1036
|
+
- Fallback: Feature flag to disable profiles
|
|
1037
|
+
|
|
1038
|
+
### 14.2 Rollback Plan
|
|
1039
|
+
|
|
1040
|
+
**If profiles cause issues:**
|
|
1041
|
+
1. Feature flag to disable profiles system-wide
|
|
1042
|
+
2. Revert to single default behavior
|
|
1043
|
+
3. Keep config structure for future re-enable
|
|
1044
|
+
4. Communicate clearly to users
|
|
1045
|
+
|
|
1046
|
+
---
|
|
1047
|
+
|
|
1048
|
+
## 15. Next Steps
|
|
1049
|
+
|
|
1050
|
+
### Immediate (Week 1)
|
|
1051
|
+
1. Review and approve this plan
|
|
1052
|
+
2. Set up feature branch
|
|
1053
|
+
3. Create GitHub issues for each phase
|
|
1054
|
+
4. Begin Phase 1 implementation
|
|
1055
|
+
|
|
1056
|
+
### Short-term (Month 1)
|
|
1057
|
+
1. Complete Phases 1-2
|
|
1058
|
+
2. Internal testing with both personas
|
|
1059
|
+
3. Beta release to select users
|
|
1060
|
+
4. Gather initial feedback
|
|
1061
|
+
|
|
1062
|
+
### Long-term (Month 2-3)
|
|
1063
|
+
1. Complete Phases 3-4
|
|
1064
|
+
2. Public release
|
|
1065
|
+
3. Monitor metrics
|
|
1066
|
+
4. Iterate based on feedback
|
|
1067
|
+
|
|
1068
|
+
---
|
|
1069
|
+
|
|
1070
|
+
## Appendix: Example Workflows
|
|
1071
|
+
|
|
1072
|
+
### Developer Workflow Example
|
|
1073
|
+
```bash
|
|
1074
|
+
# List campaigns, filter with jq, create new campaign
|
|
1075
|
+
TEMPLATE_ID=$(cakemail templates list -f json | \
|
|
1076
|
+
jq -r '.[] | select(.name=="Newsletter") | .id')
|
|
1077
|
+
|
|
1078
|
+
CAMPAIGN_ID=$(cakemail campaigns create \
|
|
1079
|
+
--name "Weekly $(date +%Y-%m-%d)" \
|
|
1080
|
+
--list-id 123 \
|
|
1081
|
+
--template-id $TEMPLATE_ID \
|
|
1082
|
+
--quiet)
|
|
1083
|
+
|
|
1084
|
+
# Schedule for tomorrow 10am
|
|
1085
|
+
cakemail campaigns schedule $CAMPAIGN_ID \
|
|
1086
|
+
-d "$(date -d 'tomorrow 10:00' -Iseconds)" \
|
|
1087
|
+
--format json | jq -r '.scheduled_for'
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
### Marketer Workflow Example
|
|
1091
|
+
```bash
|
|
1092
|
+
# Interactive campaign creation
|
|
1093
|
+
$ cakemail campaigns create
|
|
1094
|
+
|
|
1095
|
+
📝 Create New Campaign
|
|
1096
|
+
━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1097
|
+
|
|
1098
|
+
Campaign name: Weekly Newsletter
|
|
1099
|
+
Which list? Newsletter Subscribers (5,234 contacts)
|
|
1100
|
+
Which template? Newsletter Template
|
|
1101
|
+
Subject: Your Weekly Update - October 2025
|
|
1102
|
+
|
|
1103
|
+
Preview in browser? [Y/n] y
|
|
1104
|
+
[Browser opens with preview]
|
|
1105
|
+
|
|
1106
|
+
Schedule or send now?
|
|
1107
|
+
1. 📤 Send now
|
|
1108
|
+
2. ⏰ Schedule for later
|
|
1109
|
+
3. 💾 Save as draft
|
|
1110
|
+
|
|
1111
|
+
Choose (1-3): 2
|
|
1112
|
+
|
|
1113
|
+
When should we send?
|
|
1114
|
+
tomorrow 10am
|
|
1115
|
+
|
|
1116
|
+
✓ Campaign scheduled for Oct 12, 2025 at 10:00 AM EDT
|
|
1117
|
+
|
|
1118
|
+
🎉 All set! We'll send to 5,234 contacts tomorrow morning.
|
|
1119
|
+
|
|
1120
|
+
Track it: cakemail campaigns get 123
|
|
1121
|
+
```
|