@cakemail-org/cakemail-cli 1.7.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.
Files changed (198) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/.env.example +40 -0
  3. package/.env.test.example +45 -0
  4. package/CHANGELOG.md +1031 -0
  5. package/README.md +41 -37
  6. package/audit-formats.js +128 -0
  7. package/cakemail.rb +20 -0
  8. package/dist/client.js +1 -1
  9. package/dist/client.js.map +1 -1
  10. package/dist/commands/account.js +1 -1
  11. package/dist/commands/account.js.map +1 -1
  12. package/dist/commands/attributes.js +1 -1
  13. package/dist/commands/attributes.js.map +1 -1
  14. package/dist/commands/campaigns.js +1 -1
  15. package/dist/commands/campaigns.js.map +1 -1
  16. package/dist/commands/contacts.js +1 -1
  17. package/dist/commands/contacts.js.map +1 -1
  18. package/dist/commands/emails.js +1 -1
  19. package/dist/commands/emails.js.map +1 -1
  20. package/dist/commands/interests.js +1 -1
  21. package/dist/commands/interests.js.map +1 -1
  22. package/dist/commands/lists.js +1 -1
  23. package/dist/commands/lists.js.map +1 -1
  24. package/dist/commands/logs.js +1 -1
  25. package/dist/commands/logs.js.map +1 -1
  26. package/dist/commands/reports.js +1 -1
  27. package/dist/commands/reports.js.map +1 -1
  28. package/dist/commands/segments.js +1 -1
  29. package/dist/commands/segments.js.map +1 -1
  30. package/dist/commands/senders.js +1 -1
  31. package/dist/commands/senders.js.map +1 -1
  32. package/dist/commands/suppressed.js +1 -1
  33. package/dist/commands/suppressed.js.map +1 -1
  34. package/dist/commands/tags.js +1 -1
  35. package/dist/commands/tags.js.map +1 -1
  36. package/dist/commands/templates.js +1 -1
  37. package/dist/commands/templates.js.map +1 -1
  38. package/dist/commands/transactional-templates.js +1 -1
  39. package/dist/commands/transactional-templates.js.map +1 -1
  40. package/dist/commands/webhooks.js +1 -1
  41. package/dist/commands/webhooks.js.map +1 -1
  42. package/dist/utils/config.js +2 -2
  43. package/dist/utils/config.js.map +1 -1
  44. package/dist/utils/errors.js +1 -1
  45. package/dist/utils/errors.js.map +1 -1
  46. package/dist/utils/progress.d.ts.map +1 -1
  47. package/dist/utils/progress.js +32 -4
  48. package/dist/utils/progress.js.map +1 -1
  49. package/dist/utils/spinner.d.ts +17 -0
  50. package/dist/utils/spinner.d.ts.map +1 -0
  51. package/dist/utils/spinner.js +43 -0
  52. package/dist/utils/spinner.js.map +1 -0
  53. package/docs/DOCUMENTATION-STANDARD.md +1068 -0
  54. package/docs/README.md +161 -0
  55. package/docs/developer/ARCHITECTURE.md +516 -0
  56. package/docs/developer/AUTH.md +204 -0
  57. package/docs/developer/CONTRIBUTING.md +227 -0
  58. package/docs/developer/DOCUMENTATION_SUMMARY.md +346 -0
  59. package/docs/developer/PROJECT_INDEX.md +365 -0
  60. package/docs/planning/API_COVERAGE.md +1045 -0
  61. package/docs/planning/BACKLOG.md +1159 -0
  62. package/docs/planning/PROFILE_SYSTEM_TASKS.md +287 -0
  63. package/docs/planning/UX_IMPLEMENTATION_PLAN.md +691 -0
  64. package/docs/planning/archive/RELEASE_CHECKLIST_v1.3.0.md +332 -0
  65. package/docs/planning/archive/RELEASE_v1.3.0.md +428 -0
  66. package/docs/planning/archive/cakemail-cli-ux-improvements.md +438 -0
  67. package/docs/planning/cakemail-profile-system-plan.md +1121 -0
  68. package/docs/testing/AI_USER_SIMULATION_DESIGN.md +1342 -0
  69. package/docs/testing/KENOGAMI_BIDIRECTIONAL_FLOW.md +1517 -0
  70. package/docs/testing/KENOGAMI_TRUTH_RECONCILIATION_SYSTEM.md +1369 -0
  71. package/docs/user-manual/.obsidian/app.json +1 -0
  72. package/docs/user-manual/.obsidian/appearance.json +1 -0
  73. package/docs/user-manual/.obsidian/core-plugins.json +33 -0
  74. package/docs/user-manual/.obsidian/workspace.json +167 -0
  75. package/docs/user-manual/01-getting-started/01-installation.md +214 -0
  76. package/docs/user-manual/01-getting-started/02-quick-start.md +432 -0
  77. package/docs/user-manual/01-getting-started/03-authentication.md +448 -0
  78. package/docs/user-manual/01-getting-started/04-configuration.md +430 -0
  79. package/docs/user-manual/01-getting-started/05-output-formats.md +447 -0
  80. package/docs/user-manual/02-core-concepts/01-accounts.md +514 -0
  81. package/docs/user-manual/02-core-concepts/02-profile-system.md +771 -0
  82. package/docs/user-manual/02-core-concepts/03-smart-defaults.md +485 -0
  83. package/docs/user-manual/02-core-concepts/04-authentication-methods.md +435 -0
  84. package/docs/user-manual/02-core-concepts/05-pagination-filtering.md +600 -0
  85. package/docs/user-manual/02-core-concepts/06-error-handling.md +718 -0
  86. package/docs/user-manual/02-core-concepts/07-api-coverage.md +483 -0
  87. package/docs/user-manual/03-email-operations/01-senders.md +490 -0
  88. package/docs/user-manual/03-email-operations/02-templates.md +444 -0
  89. package/docs/user-manual/03-email-operations/03-transactional-emails.md +706 -0
  90. package/docs/user-manual/03-email-operations/04-email-tracking.md +407 -0
  91. package/docs/user-manual/04-campaign-management/01-campaigns-basics.md +394 -0
  92. package/docs/user-manual/04-campaign-management/02-campaign-scheduling.md +630 -0
  93. package/docs/user-manual/04-campaign-management/03-campaign-testing.md +997 -0
  94. package/docs/user-manual/04-campaign-management/04-campaign-lifecycle.md +709 -0
  95. package/docs/user-manual/04-campaign-management/05-campaign-links.md +934 -0
  96. package/docs/user-manual/05-contact-management/01-lists.md +836 -0
  97. package/docs/user-manual/05-contact-management/02-contacts.md +1035 -0
  98. package/docs/user-manual/05-contact-management/03-custom-attributes.md +788 -0
  99. package/docs/user-manual/05-contact-management/04-segments.md +1028 -0
  100. package/docs/user-manual/05-contact-management/05-contact-import-export.md +1031 -0
  101. package/docs/user-manual/06-analytics-reporting/01-campaign-analytics.md +867 -0
  102. package/docs/user-manual/06-analytics-reporting/02-account-reports.md +227 -0
  103. package/docs/user-manual/07-integrations/01-webhooks-integration.md +259 -0
  104. package/docs/user-manual/07-integrations/02-automation.md +326 -0
  105. package/docs/user-manual/08-advanced-usage/01-scripting-patterns.md +672 -0
  106. package/docs/user-manual/08-advanced-usage/02-bulk-operations.md +932 -0
  107. package/docs/user-manual/08-advanced-usage/03-ci-cd-integration.md +892 -0
  108. package/docs/user-manual/08-advanced-usage/04-performance-optimization.md +766 -0
  109. package/docs/user-manual/09-command-reference/01-config.md +776 -0
  110. package/docs/user-manual/09-command-reference/02-account.md +652 -0
  111. package/docs/user-manual/09-command-reference/03-lists.md +958 -0
  112. package/docs/user-manual/09-command-reference/04-contacts.md +1408 -0
  113. package/docs/user-manual/09-command-reference/05-attributes.md +617 -0
  114. package/docs/user-manual/09-command-reference/06-segments.md +894 -0
  115. package/docs/user-manual/09-command-reference/07-senders.md +803 -0
  116. package/docs/user-manual/09-command-reference/08-templates.md +818 -0
  117. package/docs/user-manual/09-command-reference/09-campaigns.md +1250 -0
  118. package/docs/user-manual/09-command-reference/10-emails.md +807 -0
  119. package/docs/user-manual/09-command-reference/11-reports.md +1135 -0
  120. package/docs/user-manual/09-command-reference/12-webhooks.md +773 -0
  121. package/docs/user-manual/09-command-reference/13-suppressed.md +797 -0
  122. package/docs/user-manual/09-command-reference/14-interests.md +630 -0
  123. package/docs/user-manual/09-command-reference/15-tags.md +584 -0
  124. package/docs/user-manual/09-command-reference/16-logs.md +656 -0
  125. package/docs/user-manual/09-command-reference/17-transactional-templates.md +850 -0
  126. package/docs/user-manual/10-troubleshooting/01-common-errors.md +457 -0
  127. package/docs/user-manual/10-troubleshooting/02-authentication-issues.md +558 -0
  128. package/docs/user-manual/10-troubleshooting/03-connection-problems.md +634 -0
  129. package/docs/user-manual/10-troubleshooting/04-debugging.md +725 -0
  130. package/docs/user-manual/11-appendix/04-faq.md +484 -0
  131. package/docs/user-manual/11-appendix/05-glossary.md +250 -0
  132. package/docs/user-manual/README.md +0 -0
  133. package/package.json +13 -61
  134. package/src/cli.ts +125 -0
  135. package/src/client.ts +16 -0
  136. package/src/commands/account.ts +267 -0
  137. package/src/commands/accounts.ts +78 -0
  138. package/src/commands/actions.ts +249 -0
  139. package/src/commands/attributes.ts +139 -0
  140. package/src/commands/campaign-blueprints.ts +106 -0
  141. package/src/commands/campaigns.ts +469 -0
  142. package/src/commands/config.ts +77 -0
  143. package/src/commands/contacts.ts +612 -0
  144. package/src/commands/custom-attributes.ts +127 -0
  145. package/src/commands/dkims.ts +117 -0
  146. package/src/commands/domains.ts +82 -0
  147. package/src/commands/email-apis.ts +569 -0
  148. package/src/commands/emails.ts +197 -0
  149. package/src/commands/forms.ts +283 -0
  150. package/src/commands/interests.ts +155 -0
  151. package/src/commands/links.ts +38 -0
  152. package/src/commands/lists.ts +406 -0
  153. package/src/commands/logos.ts +71 -0
  154. package/src/commands/logs.ts +386 -0
  155. package/src/commands/reports.ts +306 -0
  156. package/src/commands/segments.ts +158 -0
  157. package/src/commands/senders.ts +204 -0
  158. package/src/commands/sub-accounts.ts +271 -0
  159. package/src/commands/suppressed-emails.ts +234 -0
  160. package/src/commands/suppressed.ts +198 -0
  161. package/src/commands/system-emails.ts +85 -0
  162. package/src/commands/tags.ts +146 -0
  163. package/src/commands/tasks.ts +116 -0
  164. package/src/commands/templates.ts +189 -0
  165. package/src/commands/tokens.ts +83 -0
  166. package/src/commands/transactional-emails.ts +374 -0
  167. package/src/commands/transactional-templates.ts +385 -0
  168. package/src/commands/users.ts +506 -0
  169. package/src/commands/webhooks.ts +172 -0
  170. package/src/commands/workflow-blueprints.ts +123 -0
  171. package/src/commands/workflows.ts +265 -0
  172. package/src/types/profile.ts +93 -0
  173. package/src/utils/auth.ts +272 -0
  174. package/src/utils/config-file.ts +96 -0
  175. package/src/utils/config.ts +134 -0
  176. package/src/utils/confirm.ts +32 -0
  177. package/src/utils/defaults.ts +99 -0
  178. package/src/utils/errors.ts +116 -0
  179. package/src/utils/interactive.ts +91 -0
  180. package/src/utils/list-defaults.ts +74 -0
  181. package/src/utils/output.ts +190 -0
  182. package/src/utils/progress.ts +320 -0
  183. package/src/utils/spinner.ts +22 -0
  184. package/tests/IMPLEMENTATION_STATUS.md +258 -0
  185. package/tests/PTY_SETUP.md +118 -0
  186. package/tests/PTY_TESTING_GUIDE.md +507 -0
  187. package/tests/README.md +244 -0
  188. package/tests/fixtures/api-responses/campaigns.json +34 -0
  189. package/tests/fixtures/test-config.json +13 -0
  190. package/tests/helpers/cli-runner.ts +128 -0
  191. package/tests/helpers/mock-server.ts +301 -0
  192. package/tests/helpers/pty-runner.ts +181 -0
  193. package/tests/integration/campaigns-real-api.test.ts +196 -0
  194. package/tests/integration/setup-integration.ts +50 -0
  195. package/tests/pty/campaigns.test.ts +241 -0
  196. package/tests/setup.ts +34 -0
  197. package/tsconfig.json +15 -0
  198. package/vitest.config.ts +28 -0
@@ -0,0 +1,204 @@
1
+ # Authentication Guide
2
+
3
+ ## How Cakemail API Authentication Works
4
+
5
+ Cakemail uses **OAuth 2.0 Password Grant** for authentication, not traditional API keys.
6
+
7
+ ### Authentication Flow
8
+
9
+ ```
10
+ 1. User provides email + password
11
+ 2. CLI sends POST /token with credentials (application/x-www-form-urlencoded)
12
+ 3. API returns: { access_token, refresh_token, expires_in }
13
+ 4. CLI uses access_token for subsequent requests (Bearer token)
14
+ 5. When access_token expires (401), CLI uses refresh_token to get new access_token
15
+ 6. If refresh fails, CLI re-authenticates with email/password
16
+ ```
17
+
18
+ ### Two Ways to Authenticate
19
+
20
+ #### Option 1: Email + Password (Recommended for CLI)
21
+
22
+ The CLI automatically handles token management:
23
+
24
+ ```bash
25
+ export CAKEMAIL_EMAIL=your@email.com
26
+ export CAKEMAIL_PASSWORD=your_password
27
+ cakemail campaigns list
28
+ ```
29
+
30
+ **What happens:**
31
+ 1. CLI calls `POST /token` with email/password
32
+ 2. Receives `access_token` and `refresh_token`
33
+ 3. Stores tokens in memory (not persisted)
34
+ 4. Uses `access_token` for all API requests
35
+ 5. Auto-refreshes when token expires
36
+
37
+ #### Option 2: Pre-existing Access Token
38
+
39
+ If you already have an access token (from another OAuth2 flow):
40
+
41
+ ```bash
42
+ export CAKEMAIL_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
43
+ cakemail campaigns list
44
+ ```
45
+
46
+ **Note:** This won't auto-refresh since there's no refresh token.
47
+
48
+ ## OAuth2 Token Request Format
49
+
50
+ The `/token` endpoint requires `application/x-www-form-urlencoded` format:
51
+
52
+ ### Get Initial Token (Password Grant)
53
+ ```http
54
+ POST /token
55
+ Content-Type: application/x-www-form-urlencoded
56
+
57
+ grant_type=password&username=user@example.com&password=secret123
58
+ ```
59
+
60
+ Response:
61
+ ```json
62
+ {
63
+ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
64
+ "refresh_token": "def50200a1b2c3d4...",
65
+ "token_type": "bearer",
66
+ "expires_in": 3600
67
+ }
68
+ ```
69
+
70
+ ### Refresh Token
71
+ ```http
72
+ POST /token
73
+ Content-Type: application/x-www-form-urlencoded
74
+
75
+ grant_type=refresh_token&refresh_token=def50200a1b2c3d4...
76
+ ```
77
+
78
+ Response:
79
+ ```json
80
+ {
81
+ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
82
+ "refresh_token": "def50200e5f6g7h8...",
83
+ "token_type": "bearer",
84
+ "expires_in": 3600
85
+ }
86
+ ```
87
+
88
+ ## Token Storage
89
+
90
+ **Currently:** Tokens are stored in memory only (not persisted to disk)
91
+
92
+ **Pros:**
93
+ - More secure (tokens don't persist after CLI exits)
94
+ - No file permission issues
95
+
96
+ **Cons:**
97
+ - Must re-authenticate on every CLI invocation
98
+ - Slightly slower first request
99
+
100
+ ### Future: Token Persistence
101
+
102
+ Could store tokens in `~/.cakemail/credentials.json`:
103
+
104
+ ```json
105
+ {
106
+ "access_token": "...",
107
+ "refresh_token": "...",
108
+ "expires_at": "2025-10-08T20:00:00Z"
109
+ }
110
+ ```
111
+
112
+ This would:
113
+ - Speed up CLI (no re-authentication)
114
+ - Reduce API calls
115
+ - Require secure file permissions (0600)
116
+
117
+ ## Multi-Factor Authentication (MFA)
118
+
119
+ If account has MFA enabled, the `/token` endpoint returns:
120
+
121
+ ```json
122
+ {
123
+ "challenge": "mfa-challenge-id-123"
124
+ }
125
+ ```
126
+
127
+ The CLI would need to:
128
+ 1. Detect the challenge response
129
+ 2. Prompt user for MFA code
130
+ 3. Call `POST /token/challenge` with code
131
+
132
+ **Current Status:** MFA not yet implemented in CLI
133
+
134
+ ## Security Considerations
135
+
136
+ ### ✅ Current Implementation
137
+ - Tokens stored in memory only
138
+ - HTTPS enforced for all requests
139
+ - Automatic token refresh
140
+ - No plaintext tokens in logs
141
+
142
+ ### 🚧 Future Improvements
143
+ - Token persistence with encryption
144
+ - Token expiration checking before requests
145
+ - MFA support
146
+ - Token revocation on logout
147
+ - Secure credential storage (OS keychain)
148
+
149
+ ## Environment Variables
150
+
151
+ ```bash
152
+ # Primary authentication (auto OAuth2)
153
+ CAKEMAIL_EMAIL=your@email.com
154
+ CAKEMAIL_PASSWORD=your_password
155
+
156
+ # Alternative: Use existing token
157
+ CAKEMAIL_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
158
+
159
+ # Optional: Override API base URL
160
+ CAKEMAIL_API_BASE=https://api.cakemail.dev
161
+ ```
162
+
163
+ ## CLI Flags
164
+
165
+ ```bash
166
+ # Override credentials via CLI
167
+ cakemail --email user@example.com --password secret123 campaigns list
168
+
169
+ # Use access token
170
+ cakemail --access-token eyJhbGci... campaigns list
171
+
172
+ # Flags take precedence over environment variables
173
+ ```
174
+
175
+ ## Debugging Authentication
176
+
177
+ Enable verbose logging to see auth flow:
178
+
179
+ ```bash
180
+ # Check if credentials are loaded
181
+ cakemail --email test@example.com --password wrong_password campaigns list
182
+ # Error: Authentication failed: ...
183
+
184
+ # Success
185
+ cakemail --email user@example.com --password correct_password campaigns list
186
+ # (Makes POST /token, then GET /campaigns)
187
+ ```
188
+
189
+ ## Comparison: API Keys vs OAuth2 Tokens
190
+
191
+ | Feature | Traditional API Keys | Cakemail OAuth2 Tokens |
192
+ |---------|---------------------|------------------------|
193
+ | **Format** | Long-lived static key | Short-lived JWT |
194
+ | **Expiration** | Never (or very long) | 1 hour (configurable) |
195
+ | **Refresh** | N/A | Yes, via refresh token |
196
+ | **Scopes** | Often global | user/admin/internal |
197
+ | **Revocation** | Manual | Automatic on refresh |
198
+ | **Security** | Lower (if leaked) | Higher (expires quickly) |
199
+
200
+ ## Summary
201
+
202
+ **There are NO traditional API keys in Cakemail.** The `CAKEMAIL_ACCESS_TOKEN` env var refers to an OAuth2 access token obtained from the `/token` endpoint.
203
+
204
+ For CLI usage, **email + password** is the simplest approach - the CLI handles all token management automatically.
@@ -0,0 +1,227 @@
1
+ # Contributing to Cakemail CLI
2
+
3
+ Thank you for your interest in contributing to the Cakemail CLI! This document provides guidelines and instructions for contributing.
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - Node.js >= 18.0.0
10
+ - npm
11
+ - A Cakemail account for testing
12
+
13
+ ### Development Setup
14
+
15
+ 1. **Clone the repository**
16
+ ```bash
17
+ git clone https://github.com/cakemail/cakemail-cli.git
18
+ cd cli
19
+ ```
20
+
21
+ 2. **Install dependencies**
22
+ ```bash
23
+ npm install
24
+ ```
25
+
26
+ 3. **Set up environment**
27
+ ```bash
28
+ cp .env.example .env
29
+ # Edit .env with your test credentials
30
+ ```
31
+
32
+ 4. **Build the project**
33
+ ```bash
34
+ npm run build
35
+ ```
36
+
37
+ 5. **Test locally**
38
+ ```bash
39
+ npm start -- campaigns list
40
+ # or
41
+ node dist/cli.js campaigns list
42
+ ```
43
+
44
+ ## Development Workflow
45
+
46
+ ### Making Changes
47
+
48
+ 1. **Create a feature branch**
49
+ ```bash
50
+ git checkout -b feature/your-feature-name
51
+ ```
52
+
53
+ 2. **Make your changes**
54
+ - Write clean, readable code
55
+ - Follow existing code style and patterns
56
+ - Add TypeScript types for all new code
57
+
58
+ 3. **Build and test**
59
+ ```bash
60
+ npm run build
61
+ npm start -- <command> <args>
62
+ ```
63
+
64
+ 4. **Commit your changes**
65
+ ```bash
66
+ git add .
67
+ git commit -m "feat: add your feature description"
68
+ ```
69
+
70
+ ### Commit Message Guidelines
71
+
72
+ We follow [Conventional Commits](https://www.conventionalcommits.org/):
73
+
74
+ - `feat:` - New features
75
+ - `fix:` - Bug fixes
76
+ - `docs:` - Documentation changes
77
+ - `chore:` - Maintenance tasks
78
+ - `refactor:` - Code refactoring
79
+ - `test:` - Test additions or changes
80
+
81
+ Examples:
82
+ ```
83
+ feat: add reports command for campaign analytics
84
+ fix: correct sender confirmation flow
85
+ docs: update README with new examples
86
+ chore: update dependencies to latest versions
87
+ ```
88
+
89
+ ## Code Guidelines
90
+
91
+ ### TypeScript
92
+
93
+ - Use TypeScript for all code
94
+ - Provide types for all function parameters and return values
95
+ - Avoid `any` type when possible
96
+
97
+ ### Code Style
98
+
99
+ - Use 2 spaces for indentation
100
+ - Use single quotes for strings
101
+ - Add JSDoc comments for complex functions
102
+ - Keep functions small and focused
103
+
104
+ ### Error Handling
105
+
106
+ - Always handle errors gracefully
107
+ - Provide clear, actionable error messages
108
+ - Exit with appropriate exit codes (1 for errors)
109
+
110
+ ### Output
111
+
112
+ - Use the `OutputFormatter` for all output
113
+ - Support all three output formats: JSON, table, compact
114
+ - Use `ora` spinners for long-running operations
115
+
116
+ ## Adding New Commands
117
+
118
+ To add a new command category:
119
+
120
+ 1. **Create command file**: `src/commands/yourcommand.ts`
121
+
122
+ 2. **Follow the pattern**:
123
+ ```typescript
124
+ import { Command } from 'commander';
125
+ import { CakemailClient } from '../client.js';
126
+ import { OutputFormatter } from '../utils/output.js';
127
+ import ora from 'ora';
128
+
129
+ export function createYourCommand(client: CakemailClient, formatter: OutputFormatter): Command {
130
+ const cmd = new Command('yourcommand')
131
+ .description('Description of your command');
132
+
133
+ cmd
134
+ .command('list')
135
+ .description('List items')
136
+ .action(async (options) => {
137
+ const spinner = ora('Fetching...').start();
138
+ try {
139
+ const data = await client.sdk.yourService.list(options);
140
+ spinner.stop();
141
+ formatter.output(data);
142
+ } catch (error: any) {
143
+ spinner.stop();
144
+ formatter.error(error.message);
145
+ process.exit(1);
146
+ }
147
+ });
148
+
149
+ return cmd;
150
+ }
151
+ ```
152
+
153
+ 3. **Register in CLI**: Add to `src/cli.ts`
154
+ ```typescript
155
+ import { createYourCommand } from './commands/yourcommand.js';
156
+ // ...
157
+ program.addCommand(createYourCommand(client, formatter));
158
+ ```
159
+
160
+ 4. **Update documentation**:
161
+ - Add command to README.md
162
+ - Update API_COVERAGE.md
163
+
164
+ ## SDK Integration
165
+
166
+ The CLI is built on the official [@cakemail-org/cakemail-sdk](https://www.npmjs.com/package/@cakemail-org/cakemail-sdk).
167
+
168
+ - Always use SDK methods: `client.sdk.serviceName.method()`
169
+ - Follow SDK 2.0 object-based API patterns
170
+ - Wrap request bodies in `requestBody` property
171
+ - Handle SDK errors appropriately
172
+
173
+ Example:
174
+ ```typescript
175
+ // SDK 2.0 pattern
176
+ const data = await client.sdk.senderService.createSender({
177
+ requestBody: {
178
+ name: options.name,
179
+ email: options.email
180
+ }
181
+ });
182
+ ```
183
+
184
+ ## Testing
185
+
186
+ Currently, the CLI uses manual testing. Before submitting a PR:
187
+
188
+ 1. Test all affected commands
189
+ 2. Test with different output formats (`-f json`, `-f table`, `-f compact`)
190
+ 3. Test error cases (invalid IDs, missing params, etc.)
191
+ 4. Test with both email/password and access token authentication
192
+
193
+ ## Documentation
194
+
195
+ - Update README.md for user-facing changes
196
+ - Update API_COVERAGE.md for new commands
197
+ - Add JSDoc comments for complex functions
198
+ - Include usage examples in command descriptions
199
+
200
+ ## Pull Request Process
201
+
202
+ 1. **Before submitting**:
203
+ - Ensure code builds: `npm run build`
204
+ - Test thoroughly
205
+ - Update documentation
206
+ - Write clear commit messages
207
+
208
+ 2. **Submit PR**:
209
+ - Provide clear description of changes
210
+ - Reference any related issues
211
+ - List breaking changes (if any)
212
+ - Include testing steps
213
+
214
+ 3. **PR Review**:
215
+ - Address review feedback promptly
216
+ - Keep commits clean and focused
217
+ - Squash commits if requested
218
+
219
+ ## Questions or Issues?
220
+
221
+ - **Bug reports**: Open an issue with reproduction steps
222
+ - **Feature requests**: Open an issue describing the use case
223
+ - **Questions**: Open a discussion or issue
224
+
225
+ ## License
226
+
227
+ By contributing, you agree that your contributions will be licensed under the MIT License.