Skip to content

Releases: SamvaHQ/samva-cli

v0.29.0

Choose a tag to compare

@aryasaatvik aryasaatvik released this 31 Oct 09:00

@samva/cli@0.29.0

Validate resource names

Create and update requests through the SDK and CLI reject organization, mailbox, mailbox endpoint display, sender, contact, contact group, campaign, newsletter, topic, and OAuth client names longer than 120 characters. Mailbox label display names are limited to 40 characters. Existing longer names remain readable; shorten a name when changing it.

Find a conversation's threads across mailboxes

mailboxes.listOrganizationThreads accepts conversation, a conversation ID, and lists the threads that conversation has in the mailboxes you can read, newest activity first. A conversation holds at most one thread per mailbox, and mailboxes you cannot read never appear. The mailboxes_threads_list MCP tool takes the same filter.

const page = await samva.mailboxes.listOrganizationThreads({ conversation: "conv_...", limit: 1 });

List your drafts across mailboxes

Use mailboxes.listOrganizationDrafts in the Promise or Effect SDK to list your own drafts across the mailboxes you can write to. Each summary carries its mailbox's id, address, and kind. Repeat mailboxId, or filter by kind and threadId, and page with nextCursor. Only the author sees a draft, and a personal mailbox's drafts stay with its owner.

const page = await samva.mailboxes.listOrganizationDrafts({ kind: "shared", limit: 20 });

The mailboxes_drafts_list MCP tool returns the same bounded page.

Organize threads and decisions across mailboxes

Use mailboxes.listOrganizationThreads in the Promise or Effect SDK to read threads across the mailboxes you can access. Filter by mailbox, personal or shared kind, and active or Done state. Done includes your own Done threads and closed shared conversations, each once. mailboxes.getNeedsYou lists held sends you can approve and quarantined messages you can release, with counts across mailboxes.

Thread updates accept done for the current reader and closed for everyone in a shared mailbox. A new live message clears every reader's Done and reopens Close. Personal mailboxes refuse Close; archive their threads instead. Read the resulting state from the thread; Done and Close emit no webhook or event-stream event.

The CLI adds samva mailboxes all-threads and samva mailboxes needs-you. Use samva mailboxes thread-update --data to update Done or Close.

v0.28.0

Choose a tag to compare

@aryasaatvik aryasaatvik released this 28 Oct 21:28

@samva/cli@0.28.0

One Idempotency Option Across the SDK

Breaking: Pass idempotency keys in the second options argument as { idempotencyKey }.
Raw HTTP callers send Idempotency-Key; body and query spellings are removed. Both clients
supply a fresh key for every idempotent operation and reuse it across automatic retries.

The Promise client retries reads and idempotent mutations, accepts client-level and per-call
maxRetries, and adds lazy .pages() and .items() async iterators to cursor lists.
OAuth clients can select an organization with orgSlug.

Breaking: Import mailbox extension helpers from samva/mailbox, samva/mailbox/test, and
samva/mailbox/webhook. Handlers receive the normal client and call
ctx.samva.mailboxes.reply({ id, messageId, text }). Event dispatch preserves deterministic
send keys. The CLI extension scaffold uses these imports and flat calls.

For samva events send, pass --idempotency-key instead of embedding a key in --data.

Templates build with authoring 0.22.0

samva templates commands bundle @samva/markup and @samva/vite 0.22.0. Issue layouts can place the issue's title and date with <IssueTitle /> and <IssueDate />; IssueDate reads an optional date: YYYY-MM-DD frontmatter field. Output for existing templates is unchanged.

Newsletters own issue publishing

Use newsletters for newsletter management, newsletters.issues for issue authoring, and
newsletters.domains for custom domains on the Promise client. Effect callers import
samva/effect/newsletters, samva/effect/newsletter-issues, and samva/effect/newsletter-domains.

The API uses /v1/newsletters/:id/issues/* and /v1/newsletters/:id/domains/*; CLI commands use
samva newsletters. Topic issue routes, SDK namespaces, MCP issues_* tools, and topic archive
fields are removed. Newsletter mutations accept one optional Idempotency-Key header. Consent,
subscriptions, sending defaults, and campaign audiences continue to use topicId.

Discover archive domains with newsletters.domains.list or samva newsletters domains list.
The hostname-ordered response includes verification snapshots and an opaque nextCursor.

v0.27.0

Choose a tag to compare

@aryasaatvik aryasaatvik released this 27 Oct 17:25

@samva/cli@0.27.0

Author newsletter issues and pin saved content to campaigns

The SDK adds topicIssues on the Promise client and TopicIssues at
samva/effect/topic-issues. The CLI adds samva topics issues for creating and editing Markdown
issues, checking and previewing email or web output, and saving commits. Listing issues returns
each draft's title and its latest campaign send, and needs messages read access beside contacts
read access. Issue authoring is Preview and requires access for your organization.

Campaigns accept content.issue: { path, commit } with audience.topicId to select a saved issue.
The saved title and preheader supply the email content, and each run keeps its selected path and
commit. Use the CLI's --issue-path and --issue-commit options to select that content.

Use SML 0.21 for template projects

Update your project's @samva/markup and @samva/vite packages to 0.21.0. Compiled templates use
sml: 2; direct renderer calls select output with { target: "email" } instead of
{ channel: "email" }.

Publish sent newsletter issues on the web

Publication sites are Preview and available to selected organizations. Enable an opt-in topic's
archive with archiveEnabled and choose its <publicationSlug>.samva.app hostname. Sent issues
appear in the archive, RSS feed and sitemap; saving a draft does not publish it.

The SDK adds topicPublicationDomains on the Promise client and TopicPublicationDomains at
samva/effect/publication-domains to add, inspect and remove custom publication domains. The CLI
adds --archive enabled|disabled and --publication-slug <label|none> to topic settings.

Email sent with publication Preview access includes a private view-in-browser link to that
delivery's frozen content. Compiled templates must support SML's web renderer; raw API HTML and
text are also supported.

v0.26.1

Choose a tag to compare

@aryasaatvik aryasaatvik released this 27 Oct 13:13

@samva/cli@0.26.1

Open every package README by saying what Samva is

The samva, @samva/webhooks, @samva/cli, native CLI, and @samva/mailbox READMEs now open
with a one-line description of Samva. @samva/cli describes itself as an email tool and drops the
cpaas and messaging keywords.

v0.26.0

Choose a tag to compare

@aryasaatvik aryasaatvik released this 27 Oct 11:48

@samva/cli@0.26.0

Subscribe contacts to topics

Breaking: Topics replace unsubscribe groups. Use client.topics (Effect: samva/effect/topics),
audience.topicId on campaigns, and topicId when requesting a confirmation email. Set each
contact's subscribed or unsubscribed status per topic and channel with topics.setSubscriptions.
Existing opt-outs carry over, and opt_in topics reach only subscribed contacts.

  • Webhooks: subscription events carry topicId, topicName, and channel instead of group fields.
    Skipped-recipient receipts report topic-unsubscribe with a topicId, in the SDKs and in mailbox
    extensions.
  • CLI: manage topics with samva topics. samva subscriptions subscribe requires --topic-id; the
    contact-group and unsubscribe-group flags are removed.
  • Confirmation: a confirmation request creates the contact only once the recipient confirms.
    Outstanding confirmation links that named no unsubscribe group no longer work.

Handle template build failures as TemplateSourceError

Breaking: When a template's source fails to build, saving, opening, publishing, or restoring a
workspace fails with TemplateSourceError (HTTP 422) instead of ConflictError (409). Catch
TemplateSourceError wherever you caught ConflictError to read build findings. It is a
validation error and not retryable; the Effect client exports it from samva/effect/errors.

Its diagnostics hold the compiler's findings, each with a code, severity, and origins locations;
a failure with no location is a single sml/build-failed finding. If a save pulled in an outside
commit before the build failed, the error includes revision: reload the workspace, fix the
source, and retry. ConflictError now means only a real conflict, such as a moved branch head, a
save already in progress, or a reused idempotency key.

The CLI prints each finding's location and how to fix it. --json and --jsonl include every
finding in details.diagnostics and the next step in next.

Pass query values as numbers and booleans

Breaking: Query parameters take numbers and booleans instead of strings, in both SDKs and
@samva/mailbox: for example limit: 20, urlExpiresIn: 60, isActive: false, sendable: true,
shared: true, and the mailbox unread, starred, and snoozed filters. Replace values such as
limit: "20".

A call whose body has only optional fields no longer needs one. campaigns.scheduleRun({ id })
schedules a run with its defaults, and the Effect Organizations.update() and
Email.updateTrackingDefaults() send {}. CLI flags are unchanged.

Import subscriber lists as a background job

Breaking: contacts.bulkImport is removed. Plan an import with contacts.planImport, start it
with contacts.startImport using the plan's preview hash and an idempotency key, and follow it with
contacts.getImportJob. Imports run as a background job instead of returning per-contact results.
List import is in Preview and must be enabled for your organization.

Import related beehiiv, Substack, Kit, or Mailchimp exports together. When files disagree about a
contact, the most restrictive status wins, and reimports keep existing unsubscribes, suppressions,
and bounces. Contact detail shows which import a contact came from.

In the CLI, preview with samva contacts import --preset --topic --file EVIDENCE=PATH --dry-run,
start with an idempotency key, follow progress with samva contacts import-status, and resume an
eligible failed job with samva contacts import-resume.

Read a campaign run's results

campaigns.getRunReport and samva campaigns report <campaignId> <runId> return a run's delivery
outcomes, replies, topic unsubscribes, and skipped recipients, counted once per recipient. Opens and
clicks are marked directional and leave out those classified as automated.

Download the CLI from GitHub

Each release on SamvaHQ/samva-cli attaches the native
samva executable for macOS and Linux on arm64 and x64, with a SHA256SUMS file, so you can
install without npm. The repository is a read-only mirror of the CLI's source, updated with each
release. The npm repository and bugs links point there; report problems as issues on it.

Every agent draws AI credits

Breaking: Organization usage no longer has a Standard allowance: standardGranted,
standardRemaining, and standardResetsAt are removed, and samva org usage no longer prints
them. Every agent draws the plan's monthly AI credits instead. Show the balance from
includedAiCredits, usedAiCredits, aiPackCredits, and aiResetsAt.

v0.25.0

Choose a tag to compare

@aryasaatvik aryasaatvik released this 27 Oct 08:12

@samva/cli@0.25.0

Set custom headers with samva email send --header

samva email send --header 'Name: Value' (repeatable) sets email.headers. The name is the text
before the first colon and the value is the rest. A pair with no colon, no name, or no value is
rejected before the request. The API rejects reserved names and headers past its limits.