@samva/cli 0.1.2 → 0.2.1

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 (4) hide show
  1. package/AGENTS.md +49 -5
  2. package/README.md +86 -10
  3. package/dist/bin.mjs +53993 -61374
  4. package/package.json +17 -17
package/AGENTS.md CHANGED
@@ -4,13 +4,57 @@ 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 init` creates a project whose `devDependencies` include `@samva/markup`,
8
- `@samva/vite`, and Vite. Run `npm install` in that project before `samva templates push`; the CLI
9
- loads the project's installed authoring toolchain so its compiler and editor versions stay pinned
10
- by the project lockfile. Template authoring commands require Node.js 22 or newer; other CLI commands
11
- remain self-contained.
7
+ `samva templates export --dir <dir> --out <dir>` renders every local template's fixtures to HTML
8
+ and text with the asset manifest, using no Samva credential; `--asset-base <origin>` is for an
9
+ export that will be delivered, which cannot carry a relative reference.
10
+ `samva templates check --watch` is the continuous authoring gate. Human mode prints observations;
11
+ machine watch output uses `--jsonl`. `--json` remains one-shot.
12
+
13
+ `--publication-id` and `--input-contract-id` on `email send`, `scheduled-messages create`, and
14
+ `campaigns create`/`update` choose which publication a template send renders: one exact publication,
15
+ or the newest publication that still validates input identically. They are mutually exclusive and
16
+ each requires `--template-id`, because a reference is a statement about one template's history.
17
+
18
+ `samva templates workspace <open|diff|patch|check|fixture|save|history|publish>` is the
19
+ hosted project workspace over the CLI, for a caller with no clone: an agent in a sandbox, a CI job,
20
+ a script. It reaches the same domain-authorized operations the hosted MCP tools reach, so both
21
+ external transports complete one journey against one substrate. Every subcommand prints its complete
22
+ result as JSON because these outputs — revisions, digests, diagnostics — are inputs to the next
23
+ call. `open` returns the revision every other subcommand is fenced to; a workspace that moved refuses
24
+ them, and reopening is the recovery. A source that does not build is a successful call carrying a
25
+ null declaration and located findings, not a failed one. The Git commands remain the way to author a
26
+ project you have cloned.
27
+
28
+ `samva templates types --out <file>` writes one TypeScript module from the authenticated template
29
+ catalog: the input each published template accepts, and the reference a send carries. The default
30
+ reference is each template's current publication, so a generated file keeps sending the same
31
+ message until it is regenerated; `--reference contract-latest` follows new publications while the
32
+ input contract holds. `--check` writes nothing and exits `1` when the file no longer describes the
33
+ catalog, naming what moved. A schema the generator cannot express as a checking type is refused
34
+ with the template and the JSON pointer rather than generated as `unknown`.
35
+
36
+ `samva templates init --name <name>` creates a starter-backed Artifact project and clones its Git
37
+ repository. `samva templates clone <template-id>` clones an existing project. Both configure a
38
+ repository-local credential helper that exchanges Samva authorization for a one-hour,
39
+ repository-scoped credential; the token is never stored in the remote URL or Git config. Normal
40
+ `git fetch`, `git pull`, `git add`, `git commit`, and `git push` remain the synchronization commands.
41
+ Run `bun install --frozen-lockfile` before `samva templates check` or `samva templates build`, then
42
+ publish a clean, pushed commit with `samva templates publish`. Publish checks that the selected
43
+ commit is an ancestor of the fetched `origin/<default-branch>` and creates an immutable receipt; it
44
+ does not push or rewrite history. The CLI loads the project's installed authoring toolchain so its
45
+ compiler and editor versions stay pinned by the project lockfile.
46
+ Template authoring commands require Node.js 22 or newer; other CLI commands remain self-contained.
12
47
 
13
48
  `@samva/cli` ships the JavaScript implementation and its runtime dependencies. Its launcher prefers
14
49
  the matching platform-specific `@samva/cli-*` executable and falls back to the packaged JavaScript
15
50
  CLI through Bun when npm omits optional dependencies. Depend on `@samva/cli`, never a native
16
51
  artifact directly.
52
+
53
+ ## Command handler tracing
54
+
55
+ Every `Command.withHandler` body uses `Effect.fnUntraced`, and that is the convention for the whole
56
+ command surface rather than an omission at each site. A handler is the process: it runs once, prints,
57
+ and exits, so a span would name the run instead of a step inside it, and the CLI installs no tracer
58
+ to receive one. Reusable work that outlives a single call still carries a name, as
59
+ `src/config/store.ts` does with `Effect.fn("CliConfig.writeConfig")` and
60
+ `Effect.fn("CliConfig.writeCredentials")`.
package/README.md CHANGED
@@ -113,26 +113,102 @@ samva email design pull
113
113
  samva email design push --dry-run
114
114
  ```
115
115
 
116
+ ## DKIM rotation
117
+
118
+ Stage a new selector with an explicit retry key:
119
+
120
+ ```sh
121
+ samva email domains rotate-dkim dom_abc123 --idempotency-key rotation-2026-09 --dry-run
122
+ samva email domains rotate-dkim dom_abc123 --idempotency-key rotation-2026-09 --json
123
+ ```
124
+
125
+ Reuse the same key for retries. Publish the returned `record`, then run
126
+ `samva email domains check dom_abc123` to advance verification and cut over.
127
+ Keep `formerRecord` published. `minimumRetainUntil` is only a minimum retention horizon;
128
+ retirement requires separate approval and verification that at least two actual former-record
129
+ TTLs have elapsed. The command never removes DNS records.
130
+
116
131
  ## Template projects
117
132
 
118
- Scaffold a project with the Samva TSX runtime, visual editor, and pinned authoring dependencies:
133
+ Create a starter-backed project, or clone an existing template project. Samva creates the project
134
+ identity and Artifact repository; Git owns the local checkout and synchronization:
119
135
 
120
136
  ```sh
121
- mkdir transactional-email && cd transactional-email
122
- samva templates init
123
- npm install
124
- npm run samva:dev
137
+ samva templates init --name "Welcome email" --dir welcome-email
138
+ # samva templates clone tmpl_abc123 --dir welcome-email
139
+ cd welcome-email
140
+ bun install --frozen-lockfile
141
+ bun run dev
125
142
  ```
126
143
 
127
- The generated project lists `@samva/markup` and `@samva/vite` as development dependencies and Vite
128
- as the editor peer. The compiled CLI deliberately loads `@samva/vite/build` from the current
129
- project, so preview and push use the compiler version recorded in that project's lockfile.
144
+ The starter repository contains `@samva/markup`, `@samva/vite`, Vite, the project theme, and its
145
+ lockfile. The CLI deliberately loads `@samva/vite/build` from the current project, so local preview,
146
+ check, and build use the compiler version recorded in that lockfile. The clone has a normal HTTPS
147
+ `origin`; its repository-local credential helper obtains a one-hour, repository-scoped Artifact
148
+ credential from Samva when Git needs one. The credential is not written to the remote URL or Git
149
+ configuration.
130
150
 
131
151
  ```sh
132
- samva templates push --dir emails --dry-run
133
- samva templates push --dir emails
152
+ samva templates check --dir emails
153
+ samva templates check --json
154
+ samva templates build --dir emails --out dist/templates.json
155
+ samva templates check --watch
156
+ samva templates check --watch --jsonl
157
+ git add emails theme.css
158
+ git commit -m "feat: update welcome email"
159
+ git push origin main
160
+ samva templates publish --commit HEAD --json
134
161
  ```
135
162
 
163
+ Email entries default-export `defineEmail` with an input schema and declared fixtures. `check`
164
+ typechecks the project and renders every fixture; `build` writes those rendered fixtures, the input
165
+ schema, and the compiled executable module graph. Helper modules without a default export are not
166
+ templates, and every email definition must have a unique id. SMS and WhatsApp retain their
167
+ structured-channel compiler.
168
+
169
+ The JSON file written by `build` uses `schemaVersion: 2`: email previews have `kind: "email"` and
170
+ contain actual fixture outputs; structured previews have `kind: "structured"`. Email source in the
171
+ artifact is authored TSX. The CLI's stdout envelope remains version 1.
172
+
173
+ For imported email assets, pass their actual serving base to `check` or `build`, for example
174
+ `samva templates build --out dist/templates.json --asset-base https://cdn.example.com/email`.
175
+ These commands require an HTTPS base for delivery; they do not invent a URL or upload assets.
176
+ `templates export --dir emails --out dist/email` remains the way to write a local HTML/text export
177
+ with relative asset URLs.
178
+
179
+ `git fetch`, `git pull`, `git add`, `git commit`, and `git push` are ordinary Git operations. The
180
+ CLI's `init` and `clone` commands configure the repository-local helper; `publish` does not push
181
+ for you. It accepts a clean commit that is reachable from the fetched `origin/<default-branch>`
182
+ and publishes that exact commit and entry path. Use `--template-id` and `--entry` when publishing
183
+ from a checkout that was not created by `samva templates init` or `clone`.
184
+
185
+ The helper is invoked by Git using its credential protocol. It accepts only an HTTPS host and path
186
+ matching the project's repository, then exchanges the current Samva credential for a read or write
187
+ Artifact credential. `samva templates credential` is an internal helper command, not a general
188
+ credential store. Local OAuth credentials remain in the OS keyring; `SAMVA_API_KEY` remains the
189
+ automation path.
190
+
191
+ `samva templates check` runs the project's TypeScript configuration, then uses the project's
192
+ `@samva/vite/build` to evaluate default exports, emit SML, compile channel artifacts, and report
193
+ phase/provenance diagnostics plus email-client compatibility findings. It writes no files and exits
194
+ non-zero on TypeScript, discovery, module, theme, emit, compile, or breaking compatibility errors.
195
+ `--watch` reuses one Vite evaluator across template, dependency, discovery, and theme changes.
196
+ Human mode prints each observation; machine watch mode requires `--jsonl`. `--json` remains a
197
+ bounded one-shot result. `SIGINT` and `SIGTERM` close the watcher and keep the CLI's documented
198
+ interrupt exit codes.
199
+
200
+ `samva templates build` runs the same compiler gate and writes the complete compiled result as a
201
+ versioned JSON artifact for package and deployment pipelines. Its terminal/JSON result stays
202
+ bounded and reports only the destination, compiler version, and file count.
203
+
204
+ `samva templates publish` resolves the requested revision to an exact commit, verifies the working
205
+ tree is clean and the commit is an ancestor of the fetched `origin` default branch, then creates an
206
+ immutable publication receipt for the project's configured TSX entry. It does not rewrite Git
207
+ history or alter the working tree.
208
+
209
+ `templates list`, `get`, `create`, `update`, and `remove` operate on template metadata. They do not
210
+ replace the project repository, workspace, or native Git history.
211
+
136
212
  Inline email requires `--subject` and exactly one body source: `--html` or `--text`. Pass `-` as
137
213
  the value to read that body from stdin: `--text -` reads a plain-text body and `--html -` reads an
138
214
  HTML body. Only one body may come from stdin, so passing both `--text -` and `--html -` is rejected.