@samva/cli 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +12 -2
- package/README.md +79 -32
- package/dist/bin.mjs +1024 -361
- package/package.json +8 -9
package/AGENTS.md
CHANGED
|
@@ -4,12 +4,22 @@ Use `samva --help` and `samva <command> --help` as the command contract. For aut
|
|
|
4
4
|
`SAMVA_API_KEY`, `--json` for one bounded result, and `--jsonl` with `--all` for streamed lists.
|
|
5
5
|
Machine-readable results go to stdout; warnings and typed errors go to stderr.
|
|
6
6
|
|
|
7
|
-
`samva templates export --
|
|
7
|
+
`samva templates export --out <dir>` renders every local template's fixtures to HTML
|
|
8
8
|
and text with the asset manifest, needing a Samva credential only to resolve a live `samva:brand`; `--asset-base <origin>` is for an
|
|
9
9
|
export that will be delivered, which cannot carry a relative reference.
|
|
10
10
|
`samva templates check --watch` is the continuous authoring gate. Human mode prints observations;
|
|
11
11
|
machine watch output uses `--jsonl`. `--json` remains one-shot.
|
|
12
12
|
|
|
13
|
+
The developer loop for a template project is `samva templates dev` (the local visual editor, no
|
|
14
|
+
`vite.config.ts`), `check` (type-check, compile, and render every fixture), `render <template>
|
|
15
|
+
--fixture <name>` (subject, preheader, and plain-text body; `--format html`, `--channel sms|whatsapp`),
|
|
16
|
+
and `snapshot <template> --fixture <name>` (desktop and mobile PNGs, light and dark, in
|
|
17
|
+
`.samva/snapshots`, needing `playwright` in the project or a system Chrome). With `--json`, every
|
|
18
|
+
finding carries `code`, `severity`, `message`, `file`, `line`/`column`, `range`, and, where the
|
|
19
|
+
compiler has them, `fix` and a machine-applicable `edit`. Templates live in `templates/` and
|
|
20
|
+
`emails/`; a template is a `.tsx` file that default-exports `defineTemplate`, and the compiler reads
|
|
21
|
+
it without running it.
|
|
22
|
+
|
|
13
23
|
`--publication-id` and `--input-contract-id` on `email send`, `scheduled-messages create`, and
|
|
14
24
|
`campaigns create`/`update` choose which publication a template send renders: one exact publication,
|
|
15
25
|
or the newest publication that still validates input identically. They are mutually exclusive and
|
|
@@ -51,7 +61,7 @@ Install from the project's lockfile (`bun install --frozen-lockfile` or `npm ci`
|
|
|
51
61
|
publish a clean, pushed commit with `samva templates publish`. Publish checks that the selected
|
|
52
62
|
commit is an ancestor of the fetched `origin/<default-branch>` and creates an immutable receipt; it
|
|
53
63
|
does not push or rewrite history. A project holds several emails: `samva templates add
|
|
54
|
-
<
|
|
64
|
+
<templates/x.tsx>` registers another entry under its `defineTemplate` id, `samva templates publish --all`
|
|
55
65
|
publishes every active entry at one commit and exits non-zero if any failed, and `samva templates
|
|
56
66
|
move <old> <new>` follows a `git mv`. The CLI loads the project's installed authoring toolchain so its
|
|
57
67
|
compiler and editor versions stay pinned by the project lockfile.
|
package/README.md
CHANGED
|
@@ -139,19 +139,24 @@ bun run dev
|
|
|
139
139
|
```
|
|
140
140
|
|
|
141
141
|
The starter repository contains `@samva/markup`, `@samva/vite`, Vite, the project theme, and its
|
|
142
|
-
lockfile. The CLI deliberately loads `@samva/vite
|
|
143
|
-
check, and build use the compiler version recorded in that lockfile.
|
|
142
|
+
lockfile. The CLI deliberately loads `@samva/vite` from the current project, so local preview,
|
|
143
|
+
check, render, and build use the compiler version recorded in that lockfile. A project without
|
|
144
|
+
`@samva/markup`, `@samva/vite`, and `vite` fails with the install command
|
|
145
|
+
(`npm install --save-dev @samva/markup @samva/vite vite`). The clone has a normal HTTPS
|
|
144
146
|
`origin`; its repository-local credential helper obtains a one-hour, repository-scoped Artifact
|
|
145
147
|
credential from Samva when Git needs one. The credential is not written to the remote URL or Git
|
|
146
148
|
configuration.
|
|
147
149
|
|
|
148
150
|
```sh
|
|
149
|
-
samva templates
|
|
151
|
+
samva templates dev
|
|
152
|
+
samva templates check
|
|
150
153
|
samva templates check --json
|
|
151
|
-
samva templates
|
|
154
|
+
samva templates render welcome --fixture default
|
|
155
|
+
samva templates snapshot welcome --fixture default
|
|
156
|
+
samva templates build --out dist/templates.json
|
|
152
157
|
samva templates check --watch
|
|
153
158
|
samva templates check --watch --jsonl
|
|
154
|
-
git add
|
|
159
|
+
git add templates theme.css
|
|
155
160
|
git commit -m "feat: update welcome email"
|
|
156
161
|
git push origin main
|
|
157
162
|
samva templates publish --commit HEAD --json
|
|
@@ -161,34 +166,41 @@ A project holds as many emails as you need, sharing its components, theme, and l
|
|
|
161
166
|
another entry, register it, then publish every entry at one commit:
|
|
162
167
|
|
|
163
168
|
```sh
|
|
164
|
-
samva templates add
|
|
165
|
-
git add
|
|
169
|
+
samva templates add templates/reset.tsx
|
|
170
|
+
git add templates && git commit -m "feat: add password reset" && git push origin main
|
|
166
171
|
samva templates publish --all
|
|
167
172
|
```
|
|
168
173
|
|
|
169
|
-
`add` uses the entry's `
|
|
174
|
+
`add` uses the entry's `defineTemplate` id as the template's handle; pass `--slug` and `--name` to
|
|
170
175
|
choose others or to register an entry before the file exists. `publish --all` publishes every
|
|
171
176
|
active template in the project, reports each result, exits non-zero when any entry failed, and
|
|
172
|
-
lists `
|
|
177
|
+
lists `defineTemplate` files under `templates/` or `emails/` that are not registered. Rerunning it after a partial failure is safe.
|
|
173
178
|
After `git mv`, `samva templates move <old-path> <new-path>` points the template at the new file
|
|
174
179
|
and keeps its id, handle, and publications.
|
|
175
180
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
Templates live in `templates/`, and `emails/` is also recognized; every authoring command scans
|
|
182
|
+
whichever exist, and `--dir <dir>` scans only that one. A template is a `.tsx` file that
|
|
183
|
+
default-exports `defineTemplate` with an input schema, declared fixtures, and an `email`, `sms`, or
|
|
184
|
+
`whatsapp` body. The compiler reads the file without running it, so top-level code in a template
|
|
185
|
+
does not execute. `check` type-checks the project, compiles every template, and renders every
|
|
186
|
+
fixture through every channel the template declares; `build` writes those rendered fixtures, each
|
|
187
|
+
template's input schema, and its compiled IR. Modules without a template default export are
|
|
188
|
+
helpers, and every template needs a unique id.
|
|
189
|
+
|
|
190
|
+
The JSON file written by `build` uses `schemaVersion: 3`. Its `result` is the `@samva/vite/build`
|
|
191
|
+
result: `files[]`, one per template entry, each with `ok`, `diagnostics`, and a `template` carrying
|
|
192
|
+
`template` (the id), `channels`, `source`, `inputSchema`, `ir`, `fixtures[]` (each with its `email`
|
|
193
|
+
subject, preheader, HTML and text, its `sms` text, or its `whatsapp` message), and `compatibility`
|
|
194
|
+
findings. The former `preview.kind` `"email"` and `"structured"` shapes no longer exist. The CLI's
|
|
195
|
+
stdout envelope remains version 1.
|
|
185
196
|
|
|
186
197
|
For imported email assets, pass their actual serving base to `check` or `build`, for example
|
|
187
198
|
`samva templates build --out dist/templates.json --asset-base https://cdn.example.com/email`.
|
|
188
199
|
These commands require an HTTPS base for delivery; they do not invent a URL or upload assets.
|
|
189
|
-
`templates export --
|
|
190
|
-
with relative asset URLs
|
|
191
|
-
|
|
200
|
+
`templates export --out dist/email` remains the way to write a local HTML/text export
|
|
201
|
+
with relative asset URLs, plus `<fixture>.sms.txt` and `<fixture>.whatsapp.json` for those channels.
|
|
202
|
+
Like `check` and `build`, it treats the current directory as the project: its `theme.css` themes
|
|
203
|
+
the export and `samva:brand` resolves live or from `.samva/brands`.
|
|
192
204
|
|
|
193
205
|
`git fetch`, `git pull`, `git add`, `git commit`, and `git push` are ordinary Git operations. The
|
|
194
206
|
CLI's `init` and `clone` commands configure the repository-local helper; `publish` does not push
|
|
@@ -202,14 +214,47 @@ Artifact credential. `samva templates credential` is an internal helper command,
|
|
|
202
214
|
credential store. Local OAuth credentials remain in the OS keyring; `SAMVA_API_KEY` remains the
|
|
203
215
|
automation path.
|
|
204
216
|
|
|
217
|
+
`samva templates dev [--dir <dir>] [--port <n>] [--host <name>] [--open]` starts the local visual
|
|
218
|
+
editor from the project's `@samva/vite/dev` under Node.js, with no `vite.config.ts`. It prints the
|
|
219
|
+
editor URL and runs until interrupted; `SIGINT` and `SIGTERM` close the server.
|
|
220
|
+
|
|
205
221
|
`samva templates check` runs the project's TypeScript configuration, then uses the project's
|
|
206
|
-
`@samva/vite/build` to
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
222
|
+
`@samva/vite/build` to compile every template, render every fixture, and report located findings
|
|
223
|
+
plus email-client compatibility findings. It writes no files and exits non-zero on TypeScript,
|
|
224
|
+
compile, fixture, or breaking compatibility errors. `--watch` reuses one compiler session across
|
|
225
|
+
template, dependency, and theme changes. Human mode prints each observation; machine watch mode
|
|
226
|
+
requires `--jsonl`. `--json` remains a bounded one-shot result. `SIGINT` and `SIGTERM` close the
|
|
227
|
+
watcher and keep the CLI's documented interrupt exit codes.
|
|
228
|
+
|
|
229
|
+
Every finding in `check --json` (`problems[]`), `build --json`, `render --json`, and `export --json`
|
|
230
|
+
has the same fields: `code`, `severity`, `message`, `file`, `line` and `column` when located,
|
|
231
|
+
`range` (the located extent), `fix` (what to write instead) when the compiler has one, and `edit`
|
|
232
|
+
(a machine-applicable change) when it offers one; `check` and `build` add `phase`, and a finding
|
|
233
|
+
tied to one fixture names it in `fixture`. Human output prints
|
|
234
|
+
`file:line:column severity code: message` and the fix beneath it. `check --json` also carries
|
|
235
|
+
`warnings[]` for compile warnings and `compatibility` for client findings.
|
|
236
|
+
|
|
237
|
+
`samva templates render <template> --fixture <name>` renders one fixture of a local template
|
|
238
|
+
through the project's `@samva/vite/render`. `<template>` is a template id or its `.tsx` path.
|
|
239
|
+
`--channel email|sms|whatsapp` picks the body (default `email`), `--locale` and `--time-zone`
|
|
240
|
+
set formatter locale and IANA zone, `--asset-base` and `--offline` behave as for `check`, and
|
|
241
|
+
`--dir` narrows discovery. The default output is the subject, preheader, and plain-text body;
|
|
242
|
+
`--format html` prints the HTML and `--format json` (or `--json`) prints
|
|
243
|
+
`{ action: "templates.render", ok, template, fixture, subject, preheader?, html, text, diagnostics }`
|
|
244
|
+
(an SMS render carries `channel` and `text`; a WhatsApp render carries `channel` and `message`).
|
|
245
|
+
`--out <file>` writes the selected format to a file. A template or fixture that does not exist, or
|
|
246
|
+
a template that does not compile, exits `1` with located findings; an unknown name lists the valid
|
|
247
|
+
ones.
|
|
248
|
+
|
|
249
|
+
`samva templates snapshot <template> --fixture <name>` renders the email and screenshots it in a
|
|
250
|
+
headless browser at `desktop` (1280px) and `mobile` (390px) widths, in `light` and `dark` color
|
|
251
|
+
schemes, as full-page PNGs at `<out>/<template>-<fixture>-<viewport>-<scheme>.png` (default
|
|
252
|
+
`--out .samva/snapshots`). `--viewport desktop,mobile` and `--scheme light,dark` narrow the set.
|
|
253
|
+
`--json` prints `{ action: "templates.snapshot", ok, template, fixture, browser, out, files: [{ viewport,
|
|
254
|
+
scheme, width, path }] }`. The browser is the `playwright` (or `playwright-core`) your project
|
|
255
|
+
installs; without it, a system Google Chrome or Chromium, found in the usual locations or at
|
|
256
|
+
`SAMVA_CHROME`. With neither the command fails and names both remedies. Screenshots emulate the
|
|
257
|
+
color scheme; they do not reproduce a particular mail client's rendering.
|
|
213
258
|
|
|
214
259
|
`samva templates build` runs the same compiler gate and writes the complete compiled result as a
|
|
215
260
|
versioned JSON artifact for package and deployment pipelines. Its terminal/JSON result stays
|
|
@@ -357,14 +402,16 @@ samva webhooks test wep_abc123 --data '{"event":"webhook.test"}' --json
|
|
|
357
402
|
samva webhooks test wep_abc123 --data @payload.json --json
|
|
358
403
|
```
|
|
359
404
|
|
|
360
|
-
`samva email doctor` reports resolved profile, API URL, auth source, organization access,
|
|
361
|
-
|
|
362
|
-
|
|
405
|
+
`samva email doctor` reports resolved profile, API URL, auth source, organization access, the send
|
|
406
|
+
review decision, sendable domain and verified sender counts, and domain-verification readback.
|
|
407
|
+
`readyToSend` is true when a production send would be admitted and at least one domain or sender can
|
|
408
|
+
carry it. It is read-only and does not inspect receiving configuration, check DNS itself, send an
|
|
409
|
+
email, or replay fixtures.
|
|
363
410
|
Use `samva email receiving status <domain-id>` to read a domain's receiving prerequisite status.
|
|
364
411
|
`samva email receiving enable <domain-id> ...` acts by default; its `--dry-run` is offline and does
|
|
365
412
|
not require credentials or call the API. Each check is `passed`, `failed`, or
|
|
366
413
|
`unavailable`. A `failed` check carries the underlying error detail; `unavailable`, such as no
|
|
367
|
-
sending domain
|
|
414
|
+
sending domain yet or a review in progress, is informational; a rejected review fails. The command always prints the full report, then
|
|
368
415
|
exits `1` if any check failed and `0` otherwise. The `--json` result's `data` adds an aggregate
|
|
369
416
|
`ok` boolean, and human output marks checks with `✓`, `!`, and `✗` respectively.
|
|
370
417
|
|