resend-cli 1.2.1 → 1.3.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 (357) hide show
  1. package/README.md +25 -10
  2. package/dist/cli.cjs +539 -0
  3. package/package.json +31 -13
  4. package/.claude/settings.local.json +0 -5
  5. package/.claude/worktrees/emails-list/.claude/settings.local.json +0 -5
  6. package/.claude/worktrees/emails-list/.github/scripts/pr-title-check.js +0 -34
  7. package/.claude/worktrees/emails-list/.github/workflows/ci.yml +0 -32
  8. package/.claude/worktrees/emails-list/.github/workflows/pr-title-check.yml +0 -13
  9. package/.claude/worktrees/emails-list/.github/workflows/release.yml +0 -93
  10. package/.claude/worktrees/emails-list/CHANGELOG.md +0 -31
  11. package/.claude/worktrees/emails-list/LICENSE +0 -21
  12. package/.claude/worktrees/emails-list/README.md +0 -424
  13. package/.claude/worktrees/emails-list/biome.json +0 -36
  14. package/.claude/worktrees/emails-list/bun.lock +0 -76
  15. package/.claude/worktrees/emails-list/bunfig.toml +0 -2
  16. package/.claude/worktrees/emails-list/install.ps1 +0 -140
  17. package/.claude/worktrees/emails-list/install.sh +0 -301
  18. package/.claude/worktrees/emails-list/package.json +0 -43
  19. package/.claude/worktrees/emails-list/renovate.json +0 -6
  20. package/.claude/worktrees/emails-list/src/cli.ts +0 -74
  21. package/.claude/worktrees/emails-list/src/commands/api-keys/create.ts +0 -114
  22. package/.claude/worktrees/emails-list/src/commands/api-keys/delete.ts +0 -47
  23. package/.claude/worktrees/emails-list/src/commands/api-keys/index.ts +0 -26
  24. package/.claude/worktrees/emails-list/src/commands/api-keys/list.ts +0 -35
  25. package/.claude/worktrees/emails-list/src/commands/api-keys/utils.ts +0 -8
  26. package/.claude/worktrees/emails-list/src/commands/auth/index.ts +0 -20
  27. package/.claude/worktrees/emails-list/src/commands/auth/login.ts +0 -207
  28. package/.claude/worktrees/emails-list/src/commands/auth/logout.ts +0 -105
  29. package/.claude/worktrees/emails-list/src/commands/broadcasts/create.ts +0 -196
  30. package/.claude/worktrees/emails-list/src/commands/broadcasts/delete.ts +0 -46
  31. package/.claude/worktrees/emails-list/src/commands/broadcasts/get.ts +0 -59
  32. package/.claude/worktrees/emails-list/src/commands/broadcasts/index.ts +0 -43
  33. package/.claude/worktrees/emails-list/src/commands/broadcasts/list.ts +0 -60
  34. package/.claude/worktrees/emails-list/src/commands/broadcasts/send.ts +0 -56
  35. package/.claude/worktrees/emails-list/src/commands/broadcasts/update.ts +0 -95
  36. package/.claude/worktrees/emails-list/src/commands/broadcasts/utils.ts +0 -35
  37. package/.claude/worktrees/emails-list/src/commands/contact-properties/create.ts +0 -118
  38. package/.claude/worktrees/emails-list/src/commands/contact-properties/delete.ts +0 -48
  39. package/.claude/worktrees/emails-list/src/commands/contact-properties/get.ts +0 -46
  40. package/.claude/worktrees/emails-list/src/commands/contact-properties/index.ts +0 -48
  41. package/.claude/worktrees/emails-list/src/commands/contact-properties/list.ts +0 -68
  42. package/.claude/worktrees/emails-list/src/commands/contact-properties/update.ts +0 -88
  43. package/.claude/worktrees/emails-list/src/commands/contact-properties/utils.ts +0 -17
  44. package/.claude/worktrees/emails-list/src/commands/contacts/add-segment.ts +0 -78
  45. package/.claude/worktrees/emails-list/src/commands/contacts/create.ts +0 -122
  46. package/.claude/worktrees/emails-list/src/commands/contacts/delete.ts +0 -49
  47. package/.claude/worktrees/emails-list/src/commands/contacts/get.ts +0 -53
  48. package/.claude/worktrees/emails-list/src/commands/contacts/index.ts +0 -58
  49. package/.claude/worktrees/emails-list/src/commands/contacts/list.ts +0 -57
  50. package/.claude/worktrees/emails-list/src/commands/contacts/remove-segment.ts +0 -48
  51. package/.claude/worktrees/emails-list/src/commands/contacts/segments.ts +0 -39
  52. package/.claude/worktrees/emails-list/src/commands/contacts/topics.ts +0 -45
  53. package/.claude/worktrees/emails-list/src/commands/contacts/update-topics.ts +0 -90
  54. package/.claude/worktrees/emails-list/src/commands/contacts/update.ts +0 -77
  55. package/.claude/worktrees/emails-list/src/commands/contacts/utils.ts +0 -119
  56. package/.claude/worktrees/emails-list/src/commands/doctor.ts +0 -298
  57. package/.claude/worktrees/emails-list/src/commands/domains/create.ts +0 -83
  58. package/.claude/worktrees/emails-list/src/commands/domains/delete.ts +0 -42
  59. package/.claude/worktrees/emails-list/src/commands/domains/get.ts +0 -47
  60. package/.claude/worktrees/emails-list/src/commands/domains/index.ts +0 -35
  61. package/.claude/worktrees/emails-list/src/commands/domains/list.ts +0 -53
  62. package/.claude/worktrees/emails-list/src/commands/domains/update.ts +0 -75
  63. package/.claude/worktrees/emails-list/src/commands/domains/utils.ts +0 -44
  64. package/.claude/worktrees/emails-list/src/commands/domains/verify.ts +0 -38
  65. package/.claude/worktrees/emails-list/src/commands/emails/batch.ts +0 -140
  66. package/.claude/worktrees/emails-list/src/commands/emails/index.ts +0 -28
  67. package/.claude/worktrees/emails-list/src/commands/emails/list.ts +0 -73
  68. package/.claude/worktrees/emails-list/src/commands/emails/receiving/attachment.ts +0 -55
  69. package/.claude/worktrees/emails-list/src/commands/emails/receiving/attachments.ts +0 -68
  70. package/.claude/worktrees/emails-list/src/commands/emails/receiving/get.ts +0 -58
  71. package/.claude/worktrees/emails-list/src/commands/emails/receiving/index.ts +0 -28
  72. package/.claude/worktrees/emails-list/src/commands/emails/receiving/list.ts +0 -59
  73. package/.claude/worktrees/emails-list/src/commands/emails/receiving/utils.ts +0 -38
  74. package/.claude/worktrees/emails-list/src/commands/emails/send.ts +0 -189
  75. package/.claude/worktrees/emails-list/src/commands/open.ts +0 -24
  76. package/.claude/worktrees/emails-list/src/commands/segments/create.ts +0 -50
  77. package/.claude/worktrees/emails-list/src/commands/segments/delete.ts +0 -47
  78. package/.claude/worktrees/emails-list/src/commands/segments/get.ts +0 -38
  79. package/.claude/worktrees/emails-list/src/commands/segments/index.ts +0 -36
  80. package/.claude/worktrees/emails-list/src/commands/segments/list.ts +0 -58
  81. package/.claude/worktrees/emails-list/src/commands/segments/utils.ts +0 -7
  82. package/.claude/worktrees/emails-list/src/commands/teams/index.ts +0 -10
  83. package/.claude/worktrees/emails-list/src/commands/teams/list.ts +0 -35
  84. package/.claude/worktrees/emails-list/src/commands/teams/remove.ts +0 -83
  85. package/.claude/worktrees/emails-list/src/commands/teams/switch.ts +0 -73
  86. package/.claude/worktrees/emails-list/src/commands/topics/create.ts +0 -73
  87. package/.claude/worktrees/emails-list/src/commands/topics/delete.ts +0 -47
  88. package/.claude/worktrees/emails-list/src/commands/topics/get.ts +0 -42
  89. package/.claude/worktrees/emails-list/src/commands/topics/index.ts +0 -42
  90. package/.claude/worktrees/emails-list/src/commands/topics/list.ts +0 -34
  91. package/.claude/worktrees/emails-list/src/commands/topics/update.ts +0 -59
  92. package/.claude/worktrees/emails-list/src/commands/topics/utils.ts +0 -16
  93. package/.claude/worktrees/emails-list/src/commands/webhooks/create.ts +0 -128
  94. package/.claude/worktrees/emails-list/src/commands/webhooks/delete.ts +0 -49
  95. package/.claude/worktrees/emails-list/src/commands/webhooks/get.ts +0 -42
  96. package/.claude/worktrees/emails-list/src/commands/webhooks/index.ts +0 -44
  97. package/.claude/worktrees/emails-list/src/commands/webhooks/list.ts +0 -55
  98. package/.claude/worktrees/emails-list/src/commands/webhooks/update.ts +0 -83
  99. package/.claude/worktrees/emails-list/src/commands/webhooks/utils.ts +0 -36
  100. package/.claude/worktrees/emails-list/src/commands/whoami.ts +0 -71
  101. package/.claude/worktrees/emails-list/src/lib/actions.ts +0 -157
  102. package/.claude/worktrees/emails-list/src/lib/client.ts +0 -34
  103. package/.claude/worktrees/emails-list/src/lib/config.ts +0 -211
  104. package/.claude/worktrees/emails-list/src/lib/files.ts +0 -15
  105. package/.claude/worktrees/emails-list/src/lib/help-text.ts +0 -38
  106. package/.claude/worktrees/emails-list/src/lib/output.ts +0 -54
  107. package/.claude/worktrees/emails-list/src/lib/pagination.ts +0 -36
  108. package/.claude/worktrees/emails-list/src/lib/prompts.ts +0 -149
  109. package/.claude/worktrees/emails-list/src/lib/spinner.ts +0 -93
  110. package/.claude/worktrees/emails-list/src/lib/table.ts +0 -57
  111. package/.claude/worktrees/emails-list/src/lib/tty.ts +0 -28
  112. package/.claude/worktrees/emails-list/src/lib/version.ts +0 -4
  113. package/.claude/worktrees/emails-list/tests/commands/api-keys/create.test.ts +0 -195
  114. package/.claude/worktrees/emails-list/tests/commands/api-keys/delete.test.ts +0 -156
  115. package/.claude/worktrees/emails-list/tests/commands/api-keys/list.test.ts +0 -133
  116. package/.claude/worktrees/emails-list/tests/commands/auth/login.test.ts +0 -119
  117. package/.claude/worktrees/emails-list/tests/commands/auth/logout.test.ts +0 -146
  118. package/.claude/worktrees/emails-list/tests/commands/broadcasts/create.test.ts +0 -447
  119. package/.claude/worktrees/emails-list/tests/commands/broadcasts/delete.test.ts +0 -182
  120. package/.claude/worktrees/emails-list/tests/commands/broadcasts/get.test.ts +0 -146
  121. package/.claude/worktrees/emails-list/tests/commands/broadcasts/list.test.ts +0 -196
  122. package/.claude/worktrees/emails-list/tests/commands/broadcasts/send.test.ts +0 -161
  123. package/.claude/worktrees/emails-list/tests/commands/broadcasts/update.test.ts +0 -283
  124. package/.claude/worktrees/emails-list/tests/commands/contact-properties/create.test.ts +0 -250
  125. package/.claude/worktrees/emails-list/tests/commands/contact-properties/delete.test.ts +0 -183
  126. package/.claude/worktrees/emails-list/tests/commands/contact-properties/get.test.ts +0 -144
  127. package/.claude/worktrees/emails-list/tests/commands/contact-properties/list.test.ts +0 -180
  128. package/.claude/worktrees/emails-list/tests/commands/contact-properties/update.test.ts +0 -216
  129. package/.claude/worktrees/emails-list/tests/commands/contacts/add-segment.test.ts +0 -188
  130. package/.claude/worktrees/emails-list/tests/commands/contacts/create.test.ts +0 -270
  131. package/.claude/worktrees/emails-list/tests/commands/contacts/delete.test.ts +0 -192
  132. package/.claude/worktrees/emails-list/tests/commands/contacts/get.test.ts +0 -148
  133. package/.claude/worktrees/emails-list/tests/commands/contacts/list.test.ts +0 -175
  134. package/.claude/worktrees/emails-list/tests/commands/contacts/remove-segment.test.ts +0 -166
  135. package/.claude/worktrees/emails-list/tests/commands/contacts/segments.test.ts +0 -167
  136. package/.claude/worktrees/emails-list/tests/commands/contacts/topics.test.ts +0 -163
  137. package/.claude/worktrees/emails-list/tests/commands/contacts/update-topics.test.ts +0 -247
  138. package/.claude/worktrees/emails-list/tests/commands/contacts/update.test.ts +0 -205
  139. package/.claude/worktrees/emails-list/tests/commands/doctor.test.ts +0 -165
  140. package/.claude/worktrees/emails-list/tests/commands/domains/create.test.ts +0 -192
  141. package/.claude/worktrees/emails-list/tests/commands/domains/delete.test.ts +0 -156
  142. package/.claude/worktrees/emails-list/tests/commands/domains/get.test.ts +0 -137
  143. package/.claude/worktrees/emails-list/tests/commands/domains/list.test.ts +0 -164
  144. package/.claude/worktrees/emails-list/tests/commands/domains/update.test.ts +0 -223
  145. package/.claude/worktrees/emails-list/tests/commands/domains/verify.test.ts +0 -117
  146. package/.claude/worktrees/emails-list/tests/commands/emails/batch.test.ts +0 -313
  147. package/.claude/worktrees/emails-list/tests/commands/emails/list.test.ts +0 -196
  148. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/attachment.test.ts +0 -140
  149. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/attachments.test.ts +0 -168
  150. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/get.test.ts +0 -140
  151. package/.claude/worktrees/emails-list/tests/commands/emails/receiving/list.test.ts +0 -181
  152. package/.claude/worktrees/emails-list/tests/commands/emails/send.test.ts +0 -309
  153. package/.claude/worktrees/emails-list/tests/commands/segments/create.test.ts +0 -163
  154. package/.claude/worktrees/emails-list/tests/commands/segments/delete.test.ts +0 -182
  155. package/.claude/worktrees/emails-list/tests/commands/segments/get.test.ts +0 -137
  156. package/.claude/worktrees/emails-list/tests/commands/segments/list.test.ts +0 -173
  157. package/.claude/worktrees/emails-list/tests/commands/teams/list.test.ts +0 -63
  158. package/.claude/worktrees/emails-list/tests/commands/teams/remove.test.ts +0 -103
  159. package/.claude/worktrees/emails-list/tests/commands/teams/switch.test.ts +0 -96
  160. package/.claude/worktrees/emails-list/tests/commands/topics/create.test.ts +0 -191
  161. package/.claude/worktrees/emails-list/tests/commands/topics/delete.test.ts +0 -156
  162. package/.claude/worktrees/emails-list/tests/commands/topics/get.test.ts +0 -125
  163. package/.claude/worktrees/emails-list/tests/commands/topics/list.test.ts +0 -124
  164. package/.claude/worktrees/emails-list/tests/commands/topics/update.test.ts +0 -177
  165. package/.claude/worktrees/emails-list/tests/commands/webhooks/create.test.ts +0 -224
  166. package/.claude/worktrees/emails-list/tests/commands/webhooks/delete.test.ts +0 -156
  167. package/.claude/worktrees/emails-list/tests/commands/webhooks/get.test.ts +0 -125
  168. package/.claude/worktrees/emails-list/tests/commands/webhooks/list.test.ts +0 -177
  169. package/.claude/worktrees/emails-list/tests/commands/webhooks/update.test.ts +0 -206
  170. package/.claude/worktrees/emails-list/tests/commands/whoami.test.ts +0 -99
  171. package/.claude/worktrees/emails-list/tests/helpers.ts +0 -93
  172. package/.claude/worktrees/emails-list/tests/lib/client.test.ts +0 -71
  173. package/.claude/worktrees/emails-list/tests/lib/config.test.ts +0 -414
  174. package/.claude/worktrees/emails-list/tests/lib/files.test.ts +0 -65
  175. package/.claude/worktrees/emails-list/tests/lib/help-text.test.ts +0 -97
  176. package/.claude/worktrees/emails-list/tests/lib/output.test.ts +0 -127
  177. package/.claude/worktrees/emails-list/tests/lib/prompts.test.ts +0 -178
  178. package/.claude/worktrees/emails-list/tests/lib/spinner.test.ts +0 -146
  179. package/.claude/worktrees/emails-list/tests/lib/table.test.ts +0 -63
  180. package/.claude/worktrees/emails-list/tests/lib/tty.test.ts +0 -85
  181. package/.claude/worktrees/emails-list/tsconfig.json +0 -14
  182. package/.github/scripts/pr-title-check.js +0 -34
  183. package/.github/workflows/ci.yml +0 -32
  184. package/.github/workflows/pr-title-check.yml +0 -13
  185. package/.github/workflows/release.yml +0 -120
  186. package/.github/workflows/test-install-windows.yml +0 -48
  187. package/CHANGELOG.md +0 -31
  188. package/biome.json +0 -36
  189. package/bun.lock +0 -76
  190. package/bunfig.toml +0 -2
  191. package/docs/agent-dx-gaps.md +0 -167
  192. package/docs/missing-commands.md +0 -58
  193. package/docs/production-readiness.md +0 -99
  194. package/docs/secure-key-storage.md +0 -174
  195. package/install.ps1 +0 -141
  196. package/install.sh +0 -301
  197. package/renovate.json +0 -4
  198. package/src/cli.ts +0 -82
  199. package/src/commands/api-keys/create.ts +0 -114
  200. package/src/commands/api-keys/delete.ts +0 -47
  201. package/src/commands/api-keys/index.ts +0 -26
  202. package/src/commands/api-keys/list.ts +0 -35
  203. package/src/commands/api-keys/utils.ts +0 -8
  204. package/src/commands/auth/index.ts +0 -20
  205. package/src/commands/auth/login.ts +0 -207
  206. package/src/commands/auth/logout.ts +0 -105
  207. package/src/commands/broadcasts/create.ts +0 -196
  208. package/src/commands/broadcasts/delete.ts +0 -46
  209. package/src/commands/broadcasts/get.ts +0 -59
  210. package/src/commands/broadcasts/index.ts +0 -43
  211. package/src/commands/broadcasts/list.ts +0 -60
  212. package/src/commands/broadcasts/send.ts +0 -56
  213. package/src/commands/broadcasts/update.ts +0 -95
  214. package/src/commands/broadcasts/utils.ts +0 -35
  215. package/src/commands/contact-properties/create.ts +0 -118
  216. package/src/commands/contact-properties/delete.ts +0 -48
  217. package/src/commands/contact-properties/get.ts +0 -46
  218. package/src/commands/contact-properties/index.ts +0 -48
  219. package/src/commands/contact-properties/list.ts +0 -68
  220. package/src/commands/contact-properties/update.ts +0 -88
  221. package/src/commands/contact-properties/utils.ts +0 -17
  222. package/src/commands/contacts/add-segment.ts +0 -78
  223. package/src/commands/contacts/create.ts +0 -122
  224. package/src/commands/contacts/delete.ts +0 -49
  225. package/src/commands/contacts/get.ts +0 -53
  226. package/src/commands/contacts/index.ts +0 -58
  227. package/src/commands/contacts/list.ts +0 -57
  228. package/src/commands/contacts/remove-segment.ts +0 -48
  229. package/src/commands/contacts/segments.ts +0 -39
  230. package/src/commands/contacts/topics.ts +0 -45
  231. package/src/commands/contacts/update-topics.ts +0 -90
  232. package/src/commands/contacts/update.ts +0 -77
  233. package/src/commands/contacts/utils.ts +0 -119
  234. package/src/commands/doctor.ts +0 -298
  235. package/src/commands/domains/create.ts +0 -83
  236. package/src/commands/domains/delete.ts +0 -42
  237. package/src/commands/domains/get.ts +0 -47
  238. package/src/commands/domains/index.ts +0 -35
  239. package/src/commands/domains/list.ts +0 -53
  240. package/src/commands/domains/update.ts +0 -75
  241. package/src/commands/domains/utils.ts +0 -44
  242. package/src/commands/domains/verify.ts +0 -38
  243. package/src/commands/emails/batch.ts +0 -140
  244. package/src/commands/emails/index.ts +0 -24
  245. package/src/commands/emails/receiving/attachment.ts +0 -55
  246. package/src/commands/emails/receiving/attachments.ts +0 -68
  247. package/src/commands/emails/receiving/get.ts +0 -58
  248. package/src/commands/emails/receiving/index.ts +0 -28
  249. package/src/commands/emails/receiving/list.ts +0 -59
  250. package/src/commands/emails/receiving/utils.ts +0 -38
  251. package/src/commands/emails/send.ts +0 -189
  252. package/src/commands/open.ts +0 -24
  253. package/src/commands/segments/create.ts +0 -50
  254. package/src/commands/segments/delete.ts +0 -47
  255. package/src/commands/segments/get.ts +0 -38
  256. package/src/commands/segments/index.ts +0 -36
  257. package/src/commands/segments/list.ts +0 -58
  258. package/src/commands/segments/utils.ts +0 -7
  259. package/src/commands/teams/index.ts +0 -10
  260. package/src/commands/teams/list.ts +0 -35
  261. package/src/commands/teams/remove.ts +0 -83
  262. package/src/commands/teams/switch.ts +0 -73
  263. package/src/commands/topics/create.ts +0 -73
  264. package/src/commands/topics/delete.ts +0 -47
  265. package/src/commands/topics/get.ts +0 -42
  266. package/src/commands/topics/index.ts +0 -42
  267. package/src/commands/topics/list.ts +0 -34
  268. package/src/commands/topics/update.ts +0 -59
  269. package/src/commands/topics/utils.ts +0 -16
  270. package/src/commands/webhooks/create.ts +0 -128
  271. package/src/commands/webhooks/delete.ts +0 -49
  272. package/src/commands/webhooks/get.ts +0 -42
  273. package/src/commands/webhooks/index.ts +0 -44
  274. package/src/commands/webhooks/list.ts +0 -55
  275. package/src/commands/webhooks/update.ts +0 -83
  276. package/src/commands/webhooks/utils.ts +0 -36
  277. package/src/commands/whoami.ts +0 -71
  278. package/src/lib/actions.ts +0 -157
  279. package/src/lib/client.ts +0 -37
  280. package/src/lib/config.ts +0 -211
  281. package/src/lib/files.ts +0 -15
  282. package/src/lib/help-text.ts +0 -38
  283. package/src/lib/output.ts +0 -54
  284. package/src/lib/pagination.ts +0 -36
  285. package/src/lib/prompts.ts +0 -149
  286. package/src/lib/spinner.ts +0 -93
  287. package/src/lib/table.ts +0 -57
  288. package/src/lib/tty.ts +0 -28
  289. package/src/lib/version.ts +0 -4
  290. package/tests/commands/api-keys/create.test.ts +0 -195
  291. package/tests/commands/api-keys/delete.test.ts +0 -156
  292. package/tests/commands/api-keys/list.test.ts +0 -133
  293. package/tests/commands/auth/login.test.ts +0 -119
  294. package/tests/commands/auth/logout.test.ts +0 -146
  295. package/tests/commands/broadcasts/create.test.ts +0 -447
  296. package/tests/commands/broadcasts/delete.test.ts +0 -182
  297. package/tests/commands/broadcasts/get.test.ts +0 -146
  298. package/tests/commands/broadcasts/list.test.ts +0 -196
  299. package/tests/commands/broadcasts/send.test.ts +0 -161
  300. package/tests/commands/broadcasts/update.test.ts +0 -283
  301. package/tests/commands/contact-properties/create.test.ts +0 -250
  302. package/tests/commands/contact-properties/delete.test.ts +0 -183
  303. package/tests/commands/contact-properties/get.test.ts +0 -144
  304. package/tests/commands/contact-properties/list.test.ts +0 -180
  305. package/tests/commands/contact-properties/update.test.ts +0 -216
  306. package/tests/commands/contacts/add-segment.test.ts +0 -188
  307. package/tests/commands/contacts/create.test.ts +0 -270
  308. package/tests/commands/contacts/delete.test.ts +0 -192
  309. package/tests/commands/contacts/get.test.ts +0 -148
  310. package/tests/commands/contacts/list.test.ts +0 -175
  311. package/tests/commands/contacts/remove-segment.test.ts +0 -166
  312. package/tests/commands/contacts/segments.test.ts +0 -167
  313. package/tests/commands/contacts/topics.test.ts +0 -163
  314. package/tests/commands/contacts/update-topics.test.ts +0 -247
  315. package/tests/commands/contacts/update.test.ts +0 -205
  316. package/tests/commands/doctor.test.ts +0 -165
  317. package/tests/commands/domains/create.test.ts +0 -192
  318. package/tests/commands/domains/delete.test.ts +0 -156
  319. package/tests/commands/domains/get.test.ts +0 -137
  320. package/tests/commands/domains/list.test.ts +0 -164
  321. package/tests/commands/domains/update.test.ts +0 -223
  322. package/tests/commands/domains/verify.test.ts +0 -117
  323. package/tests/commands/emails/batch.test.ts +0 -313
  324. package/tests/commands/emails/receiving/attachment.test.ts +0 -140
  325. package/tests/commands/emails/receiving/attachments.test.ts +0 -168
  326. package/tests/commands/emails/receiving/get.test.ts +0 -140
  327. package/tests/commands/emails/receiving/list.test.ts +0 -181
  328. package/tests/commands/emails/send.test.ts +0 -309
  329. package/tests/commands/segments/create.test.ts +0 -163
  330. package/tests/commands/segments/delete.test.ts +0 -182
  331. package/tests/commands/segments/get.test.ts +0 -137
  332. package/tests/commands/segments/list.test.ts +0 -173
  333. package/tests/commands/teams/list.test.ts +0 -63
  334. package/tests/commands/teams/remove.test.ts +0 -103
  335. package/tests/commands/teams/switch.test.ts +0 -96
  336. package/tests/commands/topics/create.test.ts +0 -191
  337. package/tests/commands/topics/delete.test.ts +0 -156
  338. package/tests/commands/topics/get.test.ts +0 -125
  339. package/tests/commands/topics/list.test.ts +0 -124
  340. package/tests/commands/topics/update.test.ts +0 -177
  341. package/tests/commands/webhooks/create.test.ts +0 -224
  342. package/tests/commands/webhooks/delete.test.ts +0 -156
  343. package/tests/commands/webhooks/get.test.ts +0 -125
  344. package/tests/commands/webhooks/list.test.ts +0 -177
  345. package/tests/commands/webhooks/update.test.ts +0 -206
  346. package/tests/commands/whoami.test.ts +0 -99
  347. package/tests/helpers.ts +0 -93
  348. package/tests/lib/client.test.ts +0 -71
  349. package/tests/lib/config.test.ts +0 -414
  350. package/tests/lib/files.test.ts +0 -65
  351. package/tests/lib/help-text.test.ts +0 -97
  352. package/tests/lib/output.test.ts +0 -127
  353. package/tests/lib/prompts.test.ts +0 -178
  354. package/tests/lib/spinner.test.ts +0 -146
  355. package/tests/lib/table.test.ts +0 -63
  356. package/tests/lib/tty.test.ts +0 -85
  357. package/tsconfig.json +0 -14
@@ -1,48 +0,0 @@
1
- name: Test Windows Installer
2
-
3
- on:
4
- pull_request:
5
- paths:
6
- - install.ps1
7
- workflow_dispatch:
8
-
9
- jobs:
10
- test:
11
- runs-on: windows-latest
12
- steps:
13
- - uses: actions/checkout@v6
14
-
15
- - name: Run install.ps1 from repo
16
- shell: pwsh
17
- run: .\install.ps1
18
-
19
- - name: Verify binary exists
20
- shell: pwsh
21
- run: |
22
- $exe = "$env:USERPROFILE\.resend\bin\resend.exe"
23
- if (-not (Test-Path $exe)) {
24
- Write-Error "Binary not found at $exe"
25
- exit 1
26
- }
27
- Write-Host "Found binary at $exe"
28
-
29
- - name: Verify binary runs
30
- shell: pwsh
31
- run: |
32
- $exe = "$env:USERPROFILE\.resend\bin\resend.exe"
33
- & $exe --version
34
- if ($LASTEXITCODE -ne 0) {
35
- Write-Error "resend --version failed"
36
- exit 1
37
- }
38
-
39
- - name: Verify PATH was updated
40
- shell: pwsh
41
- run: |
42
- $binDir = "$env:USERPROFILE\.resend\bin"
43
- $path = [Environment]::GetEnvironmentVariable("PATH", "User")
44
- if ($path -notlike "*$binDir*") {
45
- Write-Error "$binDir was not added to PATH"
46
- exit 1
47
- }
48
- Write-Host "PATH correctly updated"
package/CHANGELOG.md DELETED
@@ -1,31 +0,0 @@
1
- # Changelog
2
-
3
- ## [0.2.0] - 2026-02-18
4
-
5
- ### Added
6
-
7
- - `resend domains` — create, verify, get, list, update, delete sending domains
8
- - `resend api-keys` — create, list, delete API keys
9
- - `resend broadcasts` — full broadcast lifecycle (create, send, get, list, update, delete)
10
- - `resend contacts` — manage contacts, segments, and topics across all CRUD operations
11
- - `resend emails batch` — send up to 100 emails in a single request from a JSON file
12
- - Shared pagination (`--limit`, `--after`, `--before`) on all list commands
13
- - `--html-file` flag on `emails send` and `broadcasts create` to read body from a file
14
-
15
- ### Fixed
16
-
17
- - `isInteractive()` now checks both `stdin` and `stdout` TTY — CI environments are correctly detected as non-interactive
18
- - `domains delete` now returns a consistent `{ id, deleted: true }` object instead of an empty `{}`
19
-
20
- ### Changed
21
-
22
- - All delete commands return a uniform `{ object, id, deleted: true }` response
23
- - `--help` improved across all commands with output shape, error codes, and usage examples
24
-
25
- ---
26
-
27
- ## [0.1.0] - 2026-02-18
28
-
29
- - Initial release: `auth login`, `emails send`, `doctor`
30
- - Auto JSON output when stdout is not a TTY (`--json`)
31
- - Cross-platform binaries for macOS, Linux, and Windows via GitHub Actions
package/biome.json DELETED
@@ -1,36 +0,0 @@
1
- {
2
- "$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
3
- "assist": {
4
- "actions": {
5
- "source": {
6
- "organizeImports": "on"
7
- }
8
- }
9
- },
10
- "formatter": {
11
- "indentStyle": "space",
12
- "indentWidth": 2,
13
- "lineWidth": 80
14
- },
15
- "javascript": {
16
- "formatter": {
17
- "quoteStyle": "single"
18
- }
19
- },
20
- "linter": {
21
- "enabled": true,
22
- "rules": {
23
- "recommended": true,
24
- "correctness": {
25
- "noUnusedImports": "error",
26
- "noUnusedVariables": "error"
27
- },
28
- "style": {
29
- "useBlockStatements": "error"
30
- }
31
- }
32
- },
33
- "files": {
34
- "includes": ["**", "!**/dist", "!**/bun.lock"]
35
- }
36
- }
package/bun.lock DELETED
@@ -1,76 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "configVersion": 0,
4
- "workspaces": {
5
- "": {
6
- "name": "resend-cli",
7
- "dependencies": {
8
- "@clack/prompts": "1.1.0",
9
- "@commander-js/extra-typings": "14.0.0",
10
- "commander": "14.0.3",
11
- "resend": "6.9.3",
12
- "unicode-animations": "1.0.3",
13
- },
14
- "devDependencies": {
15
- "@biomejs/biome": "2.4.6",
16
- "@types/bun": "1.3.10",
17
- "typescript": "5.9.3",
18
- },
19
- },
20
- },
21
- "packages": {
22
- "@biomejs/biome": ["@biomejs/biome@2.4.6", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.6", "@biomejs/cli-darwin-x64": "2.4.6", "@biomejs/cli-linux-arm64": "2.4.6", "@biomejs/cli-linux-arm64-musl": "2.4.6", "@biomejs/cli-linux-x64": "2.4.6", "@biomejs/cli-linux-x64-musl": "2.4.6", "@biomejs/cli-win32-arm64": "2.4.6", "@biomejs/cli-win32-x64": "2.4.6" }, "bin": { "biome": "bin/biome" } }, "sha512-QnHe81PMslpy3mnpL8DnO2M4S4ZnYPkjlGCLWBZT/3R9M6b5daArWMMtEfP52/n174RKnwRIf3oT8+wc9ihSfQ=="],
23
-
24
- "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-NW18GSyxr+8sJIqgoGwVp5Zqm4SALH4b4gftIA0n62PTuBs6G2tHlwNAOj0Vq0KKSs7Sf88VjjmHh0O36EnzrQ=="],
25
-
26
- "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-4uiE/9tuI7cnjtY9b07RgS7gGyYOAfIAGeVJWEfeCnAarOAS7qVmuRyX6d7JTKw28/mt+rUzMasYeZ+0R/U1Mw=="],
27
-
28
- "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-kMLaI7OF5GN1Q8Doymjro1P8rVEoy7BKQALNz6fiR8IC1WKduoNyteBtJlHT7ASIL0Cx2jR6VUOBIbcB1B8pew=="],
29
-
30
- "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-F/JdB7eN22txiTqHM5KhIVt0jVkzZwVYrdTR1O3Y4auBOQcXxHK4dxULf4z43QyZI5tsnQJrRBHZy7wwtL+B3A=="],
31
-
32
- "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.6", "", { "os": "linux", "cpu": "x64" }, "sha512-oHXmUFEoH8Lql1xfc3QkFLiC1hGR7qedv5eKNlC185or+o4/4HiaU7vYODAH3peRCfsuLr1g6v2fK9dFFOYdyw=="],
33
-
34
- "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.6", "", { "os": "linux", "cpu": "x64" }, "sha512-C9s98IPDu7DYarjlZNuzJKTjVHN03RUnmHV5htvqsx6vEUXCDSJ59DNwjKVD5XYoSS4N+BYhq3RTBAL8X6svEg=="],
35
-
36
- "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-xzThn87Pf3YrOGTEODFGONmqXpTwUNxovQb72iaUOdcw8sBSY3+3WD8Hm9IhMYLnPi0n32s3L3NWU6+eSjfqFg=="],
37
-
38
- "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.6", "", { "os": "win32", "cpu": "x64" }, "sha512-7++XhnsPlr1HDbor5amovPjOH6vsrFOCdp93iKXhFn6bcMUI6soodj3WWKfgEO6JosKU1W5n3uky3WW9RlRjTg=="],
39
-
40
- "@clack/core": ["@clack/core@1.1.0", "", { "dependencies": { "sisteransi": "^1.0.5" } }, "sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA=="],
41
-
42
- "@clack/prompts": ["@clack/prompts@1.1.0", "", { "dependencies": { "@clack/core": "1.1.0", "sisteransi": "^1.0.5" } }, "sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g=="],
43
-
44
- "@commander-js/extra-typings": ["@commander-js/extra-typings@14.0.0", "", { "peerDependencies": { "commander": "~14.0.0" } }, "sha512-hIn0ncNaJRLkZrxBIp5AsW/eXEHNKYQBh0aPdoUqNgD+Io3NIykQqpKFyKcuasZhicGaEZJX/JBSIkZ4e5x8Dg=="],
45
-
46
- "@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="],
47
-
48
- "@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
49
-
50
- "@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="],
51
-
52
- "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="],
53
-
54
- "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
55
-
56
- "fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="],
57
-
58
- "postal-mime": ["postal-mime@2.7.3", "", {}, "sha512-MjhXadAJaWgYzevi46+3kLak8y6gbg0ku14O1gO/LNOuay8dO+1PtcSGvAdgDR0DoIsSaiIA8y/Ddw6MnrO0Tw=="],
59
-
60
- "resend": ["resend@6.9.3", "", { "dependencies": { "postal-mime": "2.7.3", "svix": "1.84.1" }, "peerDependencies": { "@react-email/render": "*" }, "optionalPeers": ["@react-email/render"] }, "sha512-GRXjH9XZBJA+daH7bBVDuTShr22iWCxXA8P7t495G4dM/RC+d+3gHBK/6bz9K6Vpcq11zRQKmD+B+jECwQlyGQ=="],
61
-
62
- "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
63
-
64
- "standardwebhooks": ["standardwebhooks@1.0.0", "", { "dependencies": { "@stablelib/base64": "^1.0.0", "fast-sha256": "^1.3.0" } }, "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg=="],
65
-
66
- "svix": ["svix@1.84.1", "", { "dependencies": { "standardwebhooks": "1.0.0", "uuid": "^10.0.0" } }, "sha512-K8DPPSZaW/XqXiz1kEyzSHYgmGLnhB43nQCMeKjWGCUpLIpAMMM8kx3rVVOSm6Bo6EHyK1RQLPT4R06skM/MlQ=="],
67
-
68
- "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
69
-
70
- "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
71
-
72
- "unicode-animations": ["unicode-animations@1.0.3", "", { "dependencies": { "unicode-animations": "^1.0.1" }, "bin": { "unicode-animations": "scripts/demo.cjs" } }, "sha512-+klB2oWwcYZjYWhwP4Pr8UZffWDFVx6jKeIahE6z0QYyM2dwDeDPyn5nevCYbyotxvtT9lh21cVURO1RX0+YMg=="],
73
-
74
- "uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
75
- }
76
- }
package/bunfig.toml DELETED
@@ -1,2 +0,0 @@
1
- [install]
2
- peer = false
@@ -1,167 +0,0 @@
1
- # Agent DX Gap Analysis
2
-
3
- Gap analysis of the Resend CLI against the 7 dimensions from
4
- ["You Need to Rewrite Your CLI for AI Agents"](https://justinpoehnelt.com/rewrite-your-cli-for-agents/)
5
- by Justin Poehnelt (Google).
6
-
7
- ---
8
-
9
- ## 1. Structured Output
10
-
11
- > Agents need machine-readable output — JSON by default when piped.
12
-
13
- ### Strengths
14
-
15
- - **Auto-JSON when piped.** `shouldOutputJson()` returns `true` when `!process.stdout.isTTY` (`src/lib/output.ts:14`). Every command goes through `outputResult` / `outputError`, so piped output is always JSON with zero flags required.
16
- - **Consistent error envelope.** `outputError` emits `{"error":{"message":"…","code":"…"}}` with exit code 1 (`src/lib/output.ts:35-54`).
17
- - **Help text documents the JSON shape.** `buildHelpText` includes an `output` section and `errorCodes` list (`src/lib/help-text.ts:1-34`).
18
-
19
- ### Gaps
20
-
21
- | Gap | Details | Recommendation |
22
- |-----|---------|----------------|
23
- | No `--output` format flag | Only `--json` exists. No `--output=yaml`, `--output=csv`, or `--output=table`. | Low priority — JSON is sufficient for agents. Consider adding `--output` only if human table formatting is needed. |
24
- | No JSON-Lines streaming | List endpoints return a single JSON blob. For large result sets an agent can't stream-process rows. | Add optional `--jsonl` or newline-delimited mode to `runList`. |
25
-
26
- ---
27
-
28
- ## 2. Deterministic, Non-Interactive Behavior
29
-
30
- > When piped, CLIs must never prompt — they should fail fast with an actionable error.
31
-
32
- ### Strengths
33
-
34
- - **TTY detection is solid.** `isInteractive()` checks `stdin.isTTY`, `stdout.isTTY`, `CI`, `GITHUB_ACTIONS`, and `TERM=dumb` (`src/lib/tty.ts:1-15`).
35
- - **Missing flags → structured error.** `promptForMissing` exits with `missing_flags` code and lists which flags are needed (`src/lib/prompts.ts:55-61`).
36
- - **Delete confirmation → structured error.** `confirmDelete` exits with `confirmation_required` and tells the agent to pass `--yes` (`src/lib/prompts.ts:28-36`).
37
- - **Spinner is a no-op.** `createSpinner` returns stub methods in non-interactive mode (`src/lib/spinner.ts:48-55`).
38
-
39
- ### Gaps
40
-
41
- | Gap | Details | Recommendation |
42
- |-----|---------|----------------|
43
- | `setup` command has no non-interactive default | Bare `resend setup` errors with `missing_target` when piped — the agent must already know the valid targets (`src/commands/setup/index.ts:70-79`). | Consider an `--all` flag or `resend setup --target cursor,vscode` to let agents configure multiple targets in one call. |
44
- | `skills install` shells out to `npx skills` in TTY | Interactive path delegates to an external process (`src/commands/skills/install.ts:231-246`). If TTY detection is wrong, the agent gets an interactive subprocess. | The non-interactive path already exists and works — just ensure the interactive branch can never trigger when `--json` is passed (currently it can't, but worth a guard). |
45
-
46
- ---
47
-
48
- ## 3. Meaningful Exit Codes
49
-
50
- > Agents rely on exit codes to branch logic. 0 = success, non-zero = specific failure category.
51
-
52
- ### Strengths
53
-
54
- - **Errors exit 1.** `outputError` defaults to exit code 1 (`src/lib/output.ts:39`).
55
- - **Error codes in JSON.** The `code` field (`missing_flags`, `auth_error`, `fetch_error`, etc.) lets agents distinguish failure types without parsing messages.
56
-
57
- ### Gaps
58
-
59
- | Gap | Details | Recommendation |
60
- |-----|---------|----------------|
61
- | Single exit code for all errors | Everything exits 1. Auth failures, validation errors, network errors, and 404s are indistinguishable by exit code alone. | Define a small set of exit codes: `1` = general, `2` = usage/validation, `3` = auth, `4` = network/API, `78` = config. Map `outputError` codes to exit codes. |
62
- | `process.exit(0)` on cancel | `cancelAndExit` exits 0 (`src/lib/prompts.ts:14-17`). A cancelled operation should exit non-zero so agents don't interpret it as success. | Exit 130 (standard SIGINT convention) or a dedicated code on cancellation. |
63
-
64
- ---
65
-
66
- ## 4. Stderr vs Stdout Separation
67
-
68
- > Machines read stdout. Humans read stderr. Progress, spinners, and status go to stderr.
69
-
70
- ### Strengths
71
-
72
- - **Spinners write to stderr.** All spinner output uses `process.stderr.write` (`src/lib/spinner.ts:62-80`).
73
- - **Error JSON goes to stderr.** `outputError` uses `console.error` for JSON errors (`src/lib/output.ts:42`).
74
-
75
- ### Gaps
76
-
77
- | Gap | Details | Recommendation |
78
- |-----|---------|----------------|
79
- | Interactive success messages go to stdout | `console.log(config.successMsg)` in `runDelete`, `runWrite`, and setup commands writes human text to stdout (`src/lib/actions.ts:67,124`). If an agent accidentally gets the interactive branch, it mixes human text with machine output. | Route all non-JSON human messages through `console.error` (stderr) so stdout is always machine-parseable. |
80
- | `skills install` interactive output on stdout | `console.log(' ✔ ...')` in `installSkills` goes to stdout (`src/commands/skills/install.ts:173-178`). | Move to stderr. |
81
-
82
- ---
83
-
84
- ## 5. Discoverability & Self-Documentation
85
-
86
- > Agents need to understand what a CLI can do from the CLI itself — not from docs websites.
87
-
88
- ### Strengths
89
-
90
- - **Rich help text.** `buildHelpText` adds output shape, error codes, and examples to every command (`src/lib/help-text.ts`).
91
- - **Examples are runnable.** Help text examples use real `$ resend ...` invocations.
92
- - **MCP setup exists.** `resend setup` configures the CLI as an MCP server for 5 agents (`src/commands/setup/index.ts`).
93
-
94
- ### Gaps
95
-
96
- | Gap | Details | Recommendation |
97
- |-----|---------|----------------|
98
- | No machine-readable command tree | `--help` outputs human-formatted text. There's no `resend --help --json` or `resend commands --json` that returns a structured list of all commands, flags, and types. | Add a hidden `resend commands` (or `--help --json`) that outputs the full command tree as JSON — subcommands, flags, types, defaults, required/optional. This is the single highest-impact improvement for agent discoverability. |
99
- | No schema per command | Agents guess at flag types and constraints. | Emit JSON Schema for each command's input (flags + args) and output shape. Could be auto-generated from Commander metadata. |
100
- | No version/capability negotiation | No `resend capabilities` or feature flags. An agent can't check if a subcommand exists without running it. | Add `resend capabilities --json` returning supported commands and API version. |
101
-
102
- ---
103
-
104
- ## 6. Auth & Configuration
105
-
106
- > Agents need non-interactive auth: env vars, config files, or flags — never browser OAuth flows.
107
-
108
- ### Strengths
109
-
110
- - **Three-tier key resolution.** `resolveApiKey` checks `--api-key` flag → `RESEND_API_KEY` env → `~/.config/resend/credentials.json` (`src/lib/config.ts:24-45`). All three work without interaction.
111
- - **Config file is secure.** Written with `0o600` permissions (`src/lib/config.ts:52-59`).
112
- - **XDG-compliant.** Respects `XDG_CONFIG_HOME` and `APPDATA` (`src/lib/config.ts:14-22`).
113
-
114
- ### Gaps
115
-
116
- | Gap | Details | Recommendation |
117
- |-----|---------|----------------|
118
- | No auth status command | There's no way to verify auth works without making an API call. | Add `resend auth status --json` → `{"authenticated":true,"source":"env","key_prefix":"re_..."}`. Useful for agents to pre-flight check credentials. |
119
- | No key scoping info | The CLI doesn't surface whether the key is a full-access or sending-only key. | Return key metadata (permissions, team) from a status endpoint if the API supports it. |
120
- | `resend login` is interactive-only | If `resend login` exists and requires TTY input, agents can't use it. | Ensure `resend login --api-key <key>` works non-interactively (just stores the key). |
121
-
122
- ---
123
-
124
- ## 7. Idempotency & Safety
125
-
126
- > Agent retries are inevitable. Commands should be safe to re-run.
127
-
128
- ### Strengths
129
-
130
- - **Setup commands are idempotent.** `mergeJsonConfig` reads existing config and merges — running twice produces the same result (`src/commands/setup/utils.ts:14-33`). Help text documents this.
131
- - **Skills install is idempotent.** Files are overwritten with the same content.
132
- - **Delete requires `--yes`.** Prevents accidental destructive actions in non-interactive mode (`src/lib/prompts.ts:28-36`).
133
-
134
- ### Gaps
135
-
136
- | Gap | Details | Recommendation |
137
- |-----|---------|----------------|
138
- | No idempotency keys for create operations | `resend emails send` or `resend domains create` with the same args may create duplicates. | Support `--idempotency-key <key>` passed through to the API's `Idempotency-Key` header. Critical for agent retry loops. |
139
- | No dry-run mode | No `--dry-run` flag to preview what a command would do. | Add `--dry-run` that validates inputs, resolves auth, and returns the request that *would* be made — without executing it. |
140
- | File reads have no path validation | `readFile` in `src/lib/files.ts` reads any path the process can access. An agent could be tricked into reading sensitive files. | Validate paths against an allowlist or working-directory scope. Low priority if the CLI is always invoked by a trusted agent. |
141
-
142
- ---
143
-
144
- ## Implementation Priority
145
-
146
- Ordered by impact on agent usability:
147
-
148
- | # | Item | Dimension | Effort |
149
- |---|------|-----------|--------|
150
- | 1 | `resend commands --json` — machine-readable command tree | Discoverability | Medium |
151
- | 2 | Differentiated exit codes (2/3/4 by error category) | Exit Codes | Small |
152
- | 3 | Route all human messages to stderr | Stderr/Stdout | Small |
153
- | 4 | `resend auth status --json` | Auth | Small |
154
- | 5 | `--idempotency-key` flag for create/send commands | Idempotency | Small |
155
- | 6 | `--dry-run` flag | Idempotency | Medium |
156
- | 7 | JSON Schema per command (input + output) | Discoverability | Large |
157
- | 8 | `resend capabilities --json` | Discoverability | Medium |
158
- | 9 | Cancel exits non-zero (130) | Exit Codes | Tiny |
159
- | 10 | `--jsonl` streaming for list commands | Structured Output | Medium |
160
-
161
- ---
162
-
163
- ## Summary
164
-
165
- The Resend CLI already handles the two most common agent pitfalls well: **structured output is automatic when piped**, and **interactive prompts fail fast with actionable errors**. The spinner, auth, and setup systems are agent-friendly out of the box.
166
-
167
- The biggest gaps are in **discoverability** (no way for an agent to introspect available commands as JSON) and **exit code granularity** (everything is exit 1). Fixing items 1-4 above would cover ~80% of the agent DX surface with relatively small changes.
@@ -1,58 +0,0 @@
1
- # Missing CLI Commands
2
-
3
- Commands supported by the SDK (`resend` npm package) that have no CLI equivalent yet.
4
-
5
- Source comparison: `resend-node/src/` resource classes vs `resend-cli/src/commands/`.
6
-
7
- ## Templates (7 commands)
8
-
9
- The entire `templates` namespace is missing from the CLI.
10
-
11
- | Command | SDK method | Notes |
12
- |---|---|---|
13
- | `resend templates create` | `templates.create(payload)` | `--name`, `--subject`, `--html`, `--text` |
14
- | `resend templates list` | `templates.list(opts)` | Pagination support |
15
- | `resend templates get <id>` | `templates.get(id)` | Also supports alias lookup |
16
- | `resend templates update <id>` | `templates.update(id, payload)` | `--name`, `--subject`, `--html`, `--text` |
17
- | `resend templates delete <id>` | `templates.remove(id)` | Confirmation prompt |
18
- | `resend templates duplicate <id>` | `templates.duplicate(id)` | |
19
- | `resend templates publish <id>` | `templates.publish(id)` | |
20
-
21
- ## Sent Emails (4 commands)
22
-
23
- The `emails` namespace only has `send` and `batch`. These read/manage operations are missing:
24
-
25
- | Command | SDK method | Notes |
26
- |---|---|---|
27
- | `resend emails list` | `emails.list(opts)` | Pagination support |
28
- | `resend emails get <id>` | `emails.get(id)` | Retrieve a sent email by ID |
29
- | `resend emails update <id>` | `emails.update(payload)` | Reschedule a scheduled email (`--scheduled-at`) |
30
- | `resend emails cancel <id>` | `emails.cancel(id)` | Cancel a scheduled email |
31
-
32
- ## Not planned
33
-
34
- These SDK methods don't map cleanly to CLI commands:
35
-
36
- | SDK method | Reason |
37
- |---|---|
38
- | `emails.receiving.forward(opts)` | Convenience wrapper that calls `emails.send` internally, not a distinct API endpoint |
39
- | `webhooks.verify(payload)` | Signature verification utility using Svix. Used in server-side webhook handlers, not useful as a CLI command |
40
-
41
- ## Coverage summary
42
-
43
- | Namespace | SDK methods | CLI commands | Coverage |
44
- |---|---|---|---|
45
- | emails (send/batch) | 6 | 2 | 33% |
46
- | emails.receiving | 5 | 4 | 80% |
47
- | domains | 6 | 6 | 100% |
48
- | api-keys | 3 | 3 | 100% |
49
- | contacts | 5 | 5 | 100% |
50
- | contacts.segments | 3 | 3 | 100% |
51
- | contacts.topics | 2 | 2 | 100% |
52
- | broadcasts | 6 | 6 | 100% |
53
- | contact-properties | 5 | 5 | 100% |
54
- | segments | 4 | 4 | 100% |
55
- | topics | 5 | 5 | 100% |
56
- | templates | 7 | 0 | 0% |
57
- | webhooks | 5 | 5 | 100% |
58
- | **Total** | **62** | **51** | **82%** |
@@ -1,99 +0,0 @@
1
- # Production Readiness Gaps
2
-
3
- Tracked gaps identified during full CLI review. Items are ordered by severity.
4
-
5
- ---
6
-
7
- ## Blockers
8
-
9
- ### `removeApiKey()` crashes when no credentials file exists
10
-
11
- `src/lib/config.ts` — `unlinkSync()` called without try-catch. Running `resend auth logout` when not logged in throws an unhandled exception instead of a graceful error.
12
-
13
- ### `emails send` missing attachment support
14
-
15
- The Resend API supports `attachments` on send but the CLI does not expose an `--attach <path>` flag. This is a core email feature users will expect before adopting the CLI.
16
-
17
- ### `emails send` missing `--scheduled-at`
18
-
19
- The API supports scheduled sending and broadcasts already expose `--scheduled-at`, but single email send does not.
20
-
21
- ### Distribution: Homebrew tap and additional package managers
22
-
23
- The release pipeline builds binaries and publishes GitHub Releases, but there is no official Homebrew tap under the `resend` org. The previous reference to a personal tap (`rafa-thayto/homebrew-tap`) was removed. Before launch, set up:
24
-
25
- - **Homebrew** — Create `resend/homebrew-tap` with a formula that downloads the correct binary from GitHub Releases. Wire the release workflow to auto-update the formula on new tags.
26
- - **npm** — The package defines a `bin` entry but is not currently published to npm. `npm install -g @resend/cli` would be the expected install path for Node.js users.
27
- - **AUR / Scoop / winget** — Consider community packages for Linux and Windows users who don't use the shell installer.
28
-
29
- ---
30
-
31
- ## High Priority
32
-
33
- ### No shell completions
34
-
35
- No bash, zsh, or fish completion support exists. With 50+ commands and deeply nested subcommands, tab completion is essential for discoverability and usability.
36
-
37
- ### Inconsistent pagination on list commands
38
-
39
- `api-keys list` and `topics list` lack the `--limit`, `--after`, and `--before` options that every other list command provides. This creates an inconsistent scripting surface.
40
-
41
- **Files:** `src/commands/api-keys/list.ts`, `src/commands/topics/list.ts`
42
-
43
- ### No tests for `actions.ts` and `pagination.ts`
44
-
45
- These are core shared modules (reusable action builders and pagination logic) used by nearly every command, yet they have zero test coverage.
46
-
47
- **Files:** `src/lib/actions.ts`, `src/lib/pagination.ts`
48
-
49
- ### Batch >100 emails warns but does not error in non-interactive mode
50
-
51
- `src/commands/emails/batch.ts` uses `console.warn()` when the batch exceeds 100 emails but continues execution. In CI or scripted mode this should hard-error since the API will reject the request.
52
-
53
- ---
54
-
55
- ## Medium Priority
56
-
57
- ### No output format options beyond JSON and table
58
-
59
- List commands support `--json` or interactive tables only. Missing `--format csv` and `--format tsv` for data export workflows.
60
-
61
- ### No filter or search on list commands
62
-
63
- No ability to filter results server-side (e.g. `--status verified` on domains, `--segment-id` on contacts). Users must fetch all pages and filter locally.
64
-
65
- ### No `resend update` or auto-update mechanism
66
-
67
- Version check exists in `resend doctor` but there is no way to update the CLI from within it. Users must re-run the install script manually.
68
-
69
- ### `setup --uninstall` and `setup --dry-run` missing
70
-
71
- The setup command can configure AI agent integrations but cannot undo or preview changes before applying them.
72
-
73
- ### No CLI-level retry logic for transient failures
74
-
75
- The CLI relies entirely on the SDK's internal retries which are opaque. For batch and bulk operations, CLI-level retry with exponential backoff would be more robust and give users visibility into retries.
76
-
77
- ---
78
-
79
- ## Low Priority
80
-
81
- ### Table rendering does not truncate long values
82
-
83
- Very long emails, domain names, or property values can break table alignment in narrow terminals.
84
-
85
- ### No `--silent` or `--quiet` flag
86
-
87
- No way to suppress all non-essential output (spinners, hints, pagination messages) for scripting use cases.
88
-
89
- ### Contact email-vs-ID detection is fragile
90
-
91
- `src/commands/contacts/utils.ts` uses `includes('@')` to decide whether a string is an email address or a contact ID. Edge cases could cause misidentification.
92
-
93
- ### No client-side input validation for domains and emails
94
-
95
- Domain names and email addresses are accepted as-is and forwarded to the API. Client-side validation would provide faster, clearer error messages.
96
-
97
- ### Hardcoded API URLs prevent staging usage
98
-
99
- No `--base-url` flag or `RESEND_BASE_URL` environment variable for pointing the CLI at non-production environments.