Skip to content

feat: rename notifications command to emails (re-point to POST /api/emails)#24

Merged
sweetmantech merged 2 commits into
mainfrom
feat/notifications-to-emails
Jun 25, 2026
Merged

feat: rename notifications command to emails (re-point to POST /api/emails)#24
sweetmantech merged 2 commits into
mainfrom
feat/notifications-to-emails

Conversation

@sweetmantech

@sweetmantech sweetmantech commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Re-points the CLI notifications command from the soon-to-be-removed POST /api/notifications to POST /api/emails, as part of the chat#1815 cleanup.

Why

POST /api/notifications is being deleted (api#711 / docs#253). With to now optional on POST /api/emails — defaulting to the account's own email when omitted (api#710 / docs#252) — the notifications command keeps its exact self-send behavior by posting to /api/emails with no to.

What changed (src/commands/notifications.ts)

  • post("/api/notifications", body)post("/api/emails", body).
  • --room-id flag → --chat-id; body key room_idchat_id (matches the /api/emails contract).
  • No --to flag — omitting to triggers the account-own-email default, preserving "send to the account owner".

The command name (notifications) and all other flags (--subject, --text, --html, --cc, --account, --json) are unchanged.

Tests (TDD, RED→GREEN)

Updated __tests__/commands/notifications.test.ts to expect /api/emails + chat_id. pnpm test74 passed (12 files); pnpm build (tsup) succeeds; grep for room_id/api/notifications in src is clean.

Sequencing

Requires api#710 (to-optional) live, and should merge before/with api#711 (the /api/notifications deletion) so the command never breaks.

🤖 Generated with Claude Code


Summary by cubic

Renames the CLI command to emails and switches it from POST /api/notifications to POST /api/emails to keep self-send behavior. Also renames --room-id to --chat-id and makes --subject optional to match the emails API.

  • Migration
    • Use recoup emails instead of recoup notifications (no alias).
    • Replace --room-id with --chat-id in any scripts.
    • Requires the API change where POST /api/emails supports optional to.

Written for commit e086785. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added an emails CLI command for sending emails.
    • Supports optional subject lines, HTML/text content, CC recipients, chat linking, and account selection.
    • Default success message now says “Email sent.”
  • Bug Fixes

    • Updated request handling so email-specific fields are only included when provided.
    • Switched command output and error handling to match the new email workflow.
  • Tests

    • Updated automated coverage to reflect the new emails command and its request behavior.

POST /api/notifications is being removed (chat#1815); /api/emails now
defaults `to` to the account's own email when omitted (api#710), so the
notifications command keeps its self-send behavior by posting to
/api/emails with no `to`.

Renames the --room-id flag to --chat-id and sends `chat_id` to match the
/api/emails contract (docs#252). Requires api#710 to be live.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR replaces the notifications CLI command with an emails command, updates its options and request payload, changes the API endpoint and success message, registers the new command in the CLI entrypoint, and updates the command tests to match the new behavior.

Changes

Emails command switch

Layer / File(s) Summary
Command and coverage
src/commands/emails.ts, src/bin.ts, __tests__/commands/emails.test.ts
The command name, endpoint, option contract, request body, default success message, CLI registration, and test expectations are switched from notifications to emails.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • recoupable/cli#8: Adds the notifications command that this PR replaces with the emails command and matching tests.

Poem

A rabbit hops, “Hooray, new mail!” 🐰
Notifications took a little trail.
Emails now hop to the right route,
With chat IDs and accounts in boot.
Soft whiskers twitch: “Email sent!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: renaming the command and repointing it to POST /api/emails.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/notifications-to-emails

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

Per review on the docs/api alignment (chat#1815): the command now matches the
renamed docs (`recoup emails`) and the shipped /api/emails contract.

- Rename `notifications` command → `emails` (src/commands/emails.ts,
  emailsCommand, Command("emails"), bin.ts registration, test file). No alias.
- `--subject` is now optional (.option, not .requiredOption) — api#710 made it
  optional (defaults from the body); only set it in the body when provided.
- Endpoint already re-pointed to /api/emails; --chat-id already maps to chat_id.

75 tests green (incl. a new subject-omitted case); build succeeds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sweetmantech sweetmantech changed the title feat: re-point notifications command to POST /api/emails feat: rename notifications command to emails (re-point to POST /api/emails) Jun 25, 2026
@sweetmantech

Copy link
Copy Markdown
Contributor Author

Pushed e086785renamed the command notificationsemails (no alias) and made --subject optional, to match the renamed docs (recoup emails, docs#253) and the shipped /api/emails contract.

  • src/commands/notifications.tssrc/commands/emails.ts (git mv); notificationsCommandemailsCommand; new Command("emails"); bin.ts registration updated; test file renamed.
  • --subject is now .option (was .requiredOption) — api#710 made subject optional (server defaults it from the body); the body only includes subject when provided.
  • Endpoint was already re-pointed to /api/emails; --chat-id already maps to chat_id (api#708 field rename).

75 tests green (incl. a new "subject omitted" case); pnpm build succeeds; recoup emails --help confirms the command, no notifications left.

⚠️ Ship order: this needs to merge and a new CLI version be published before api#711 is promoted to prod (#715) — otherwise the currently-published CLI's notifications command 404s once /api/notifications is removed from prod.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/commands/emails.ts (1)

5-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Export a command factory instead of a singleton Command.

This file now exports a configured Command instance. Prefer exporting something like createEmailsCommand() and constructing the command inside it so the file matches the repo contract for src/**/*.ts.

Suggested refactor
-export const emailsCommand = new Command("emails")
-  .description("Send an email to the account owner. The recipient is automatically resolved from your API key — no --to flag needed. --subject is optional (defaults from the body).")
-  .option("--subject <text>", "Email subject line (optional; defaults from the body)")
-  .option("--text <body>", "Plain text or Markdown body")
-  .option("--html <body>", "Raw HTML body (takes precedence over --text)")
-  .option("--cc <email>", "CC recipient (repeatable)", (val: string, prev: string[]) => prev.concat(val), [] as string[])
-  .option("--chat-id <id>", "Chat ID for chat link in footer")
-  .option("--account <accountId>", "Send to a specific account (org keys only)")
-  .option("--json", "Output as JSON")
-  .action(async (opts) => {
-    try {
-      const body: Record<string, unknown> = {};
-      if (opts.subject) body.subject = opts.subject;
-      if (opts.text) body.text = opts.text;
-      if (opts.html) body.html = opts.html;
-      if (opts.cc && opts.cc.length > 0) body.cc = opts.cc;
-      if (opts.chatId) body.chat_id = opts.chatId;
-      if (opts.account) body.account_id = opts.account;
-
-      const data = await post("/api/emails", body);
-
-      if (opts.json) {
-        printJson(data);
-      } else {
-        console.log(data.message || "Email sent.");
-      }
-    } catch (err) {
-      printError((err as Error).message);
-    }
-  });
+export function createEmailsCommand(): Command {
+  return new Command("emails")
+    .description("Send an email to the account owner. The recipient is automatically resolved from your API key — no --to flag needed. --subject is optional (defaults from the body).")
+    .option("--subject <text>", "Email subject line (optional; defaults from the body)")
+    .option("--text <body>", "Plain text or Markdown body")
+    .option("--html <body>", "Raw HTML body (takes precedence over --text)")
+    .option("--cc <email>", "CC recipient (repeatable)", (val: string, prev: string[]) => prev.concat(val), [] as string[])
+    .option("--chat-id <id>", "Chat ID for chat link in footer")
+    .option("--account <accountId>", "Send to a specific account (org keys only)")
+    .option("--json", "Output as JSON")
+    .action(async (opts) => {
+      try {
+        const body: Record<string, unknown> = {};
+        if (opts.subject) body.subject = opts.subject;
+        if (opts.text) body.text = opts.text;
+        if (opts.html) body.html = opts.html;
+        if (opts.cc && opts.cc.length > 0) body.cc = opts.cc;
+        if (opts.chatId) body.chat_id = opts.chatId;
+        if (opts.account) body.account_id = opts.account;
+
+        const data = await post("/api/emails", body);
+
+        if (opts.json) {
+          printJson(data);
+        } else {
+          console.log(data.message || "Email sent.");
+        }
+      } catch (err) {
+        printError((err as Error).message);
+      }
+    });
+}
-import { emailsCommand } from "./commands/emails.js";
+import { createEmailsCommand } from "./commands/emails.js";
 
-program.addCommand(emailsCommand);
+program.addCommand(createEmailsCommand());

As per coding guidelines, src/**/*.ts: Follow Single Responsibility Principle with one exported function per file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/emails.ts` around lines 5 - 29, The module currently exports a
prebuilt emailsCommand singleton, but the repo expects one exported factory
function per src/**/*.ts file. Refactor this file to export a
createEmailsCommand() function that constructs and configures the Command inside
the function, and update the existing command setup and .action handler to live
within that factory while preserving the current emails behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/commands/emails.ts`:
- Around line 5-29: The module currently exports a prebuilt emailsCommand
singleton, but the repo expects one exported factory function per src/**/*.ts
file. Refactor this file to export a createEmailsCommand() function that
constructs and configures the Command inside the function, and update the
existing command setup and .action handler to live within that factory while
preserving the current emails behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e92f4b4f-0bf5-42fe-a8c3-64e51ec8eceb

📥 Commits

Reviewing files that changed from the base of the PR and between f736a24 and e086785.

📒 Files selected for processing (3)
  • __tests__/commands/emails.test.ts
  • src/bin.ts
  • src/commands/emails.ts

@sweetmantech sweetmantech merged commit 9d1e919 into main Jun 25, 2026
3 checks passed

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/bin.ts">

<violation number="1" location="src/bin.ts:28">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**

PR description claims the `notifications` command name is unchanged, but the code actually renames it to `emails`, contradicting the documented behavior and breaking existing users of `recoup notifications`.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/bin.ts
program.addCommand(chatsCommand);
program.addCommand(songsCommand);
program.addCommand(notificationsCommand);
program.addCommand(emailsCommand);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Custom agent: Flag AI Slop and Fabricated Changes

PR description claims the notifications command name is unchanged, but the code actually renames it to emails, contradicting the documented behavior and breaking existing users of recoup notifications.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/bin.ts, line 28:

<comment>PR description claims the `notifications` command name is unchanged, but the code actually renames it to `emails`, contradicting the documented behavior and breaking existing users of `recoup notifications`.</comment>

<file context>
@@ -25,7 +25,7 @@ program.addCommand(whoamiCommand);
 program.addCommand(chatsCommand);
 program.addCommand(songsCommand);
-program.addCommand(notificationsCommand);
+program.addCommand(emailsCommand);
 program.addCommand(sandboxesCommand);
 program.addCommand(orgsCommand);
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant