@samva/cli 0.1.1 → 0.2.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 +49 -5
- package/README.md +80 -11
- package/dist/bin.mjs +53555 -4596
- package/package.json +16 -19
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
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
@@ -73,7 +73,7 @@ samva --profile local email doctor
|
|
|
73
73
|
|
|
74
74
|
The profile resolves as `--profile`, then `SAMVA_PROFILE`, then the active profile, then `default`.
|
|
75
75
|
The API URL resolves as `--api-url`, then `SAMVA_API_URL`, then the profile target. `local` targets
|
|
76
|
-
`
|
|
76
|
+
the Portless API origin `https://api.samva.localhost`. `production` targets `https://api.samva.dev`.
|
|
77
77
|
|
|
78
78
|
## Common operations
|
|
79
79
|
|
|
@@ -103,28 +103,97 @@ samva messages events <message-id> --json
|
|
|
103
103
|
|
|
104
104
|
# Inspect configuration and remote email state without mutating it.
|
|
105
105
|
samva email doctor --json
|
|
106
|
+
|
|
107
|
+
# Read and set organization open/click tracking defaults.
|
|
108
|
+
samva email tracking defaults get
|
|
109
|
+
samva email tracking defaults set --opens on --clicks off
|
|
110
|
+
|
|
111
|
+
# Pull and push the organization email design kit as Tailwind `@theme` CSS.
|
|
112
|
+
samva email design pull
|
|
113
|
+
samva email design push --dry-run
|
|
106
114
|
```
|
|
107
115
|
|
|
108
116
|
## Template projects
|
|
109
117
|
|
|
110
|
-
|
|
118
|
+
Create a starter-backed project, or clone an existing template project. Samva creates the project
|
|
119
|
+
identity and Artifact repository; Git owns the local checkout and synchronization:
|
|
111
120
|
|
|
112
121
|
```sh
|
|
113
|
-
|
|
114
|
-
samva templates
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
samva templates init --name "Welcome email" --dir welcome-email
|
|
123
|
+
# samva templates clone tmpl_abc123 --dir welcome-email
|
|
124
|
+
cd welcome-email
|
|
125
|
+
bun install --frozen-lockfile
|
|
126
|
+
bun run dev
|
|
117
127
|
```
|
|
118
128
|
|
|
119
|
-
The
|
|
120
|
-
|
|
121
|
-
|
|
129
|
+
The starter repository contains `@samva/markup`, `@samva/vite`, Vite, the project theme, and its
|
|
130
|
+
lockfile. The CLI deliberately loads `@samva/vite/build` from the current project, so local preview,
|
|
131
|
+
check, and build use the compiler version recorded in that lockfile. The clone has a normal HTTPS
|
|
132
|
+
`origin`; its repository-local credential helper obtains a one-hour, repository-scoped Artifact
|
|
133
|
+
credential from Samva when Git needs one. The credential is not written to the remote URL or Git
|
|
134
|
+
configuration.
|
|
122
135
|
|
|
123
136
|
```sh
|
|
124
|
-
samva templates
|
|
125
|
-
samva templates
|
|
137
|
+
samva templates check --dir emails
|
|
138
|
+
samva templates check --json
|
|
139
|
+
samva templates build --dir emails --out dist/templates.json
|
|
140
|
+
samva templates check --watch
|
|
141
|
+
samva templates check --watch --jsonl
|
|
142
|
+
git add emails theme.css
|
|
143
|
+
git commit -m "feat: update welcome email"
|
|
144
|
+
git push origin main
|
|
145
|
+
samva templates publish --commit HEAD --json
|
|
126
146
|
```
|
|
127
147
|
|
|
148
|
+
Email entries default-export `defineEmail` with an input schema and declared fixtures. `check`
|
|
149
|
+
typechecks the project and renders every fixture; `build` writes those rendered fixtures, the input
|
|
150
|
+
schema, and the compiled executable module graph. Helper modules without a default export are not
|
|
151
|
+
templates, and every email definition must have a unique id. SMS and WhatsApp retain their
|
|
152
|
+
structured-channel compiler.
|
|
153
|
+
|
|
154
|
+
The JSON file written by `build` uses `schemaVersion: 2`: email previews have `kind: "email"` and
|
|
155
|
+
contain actual fixture outputs; structured previews have `kind: "structured"`. Email source in the
|
|
156
|
+
artifact is authored TSX. The CLI's stdout envelope remains version 1.
|
|
157
|
+
|
|
158
|
+
For imported email assets, pass their actual serving base to `check` or `build`, for example
|
|
159
|
+
`samva templates build --out dist/templates.json --asset-base https://cdn.example.com/email`.
|
|
160
|
+
These commands require an HTTPS base for delivery; they do not invent a URL or upload assets.
|
|
161
|
+
`templates export --dir emails --out dist/email` remains the way to write a local HTML/text export
|
|
162
|
+
with relative asset URLs.
|
|
163
|
+
|
|
164
|
+
`git fetch`, `git pull`, `git add`, `git commit`, and `git push` are ordinary Git operations. The
|
|
165
|
+
CLI's `init` and `clone` commands configure the repository-local helper; `publish` does not push
|
|
166
|
+
for you. It accepts a clean commit that is reachable from the fetched `origin/<default-branch>`
|
|
167
|
+
and publishes that exact commit and entry path. Use `--template-id` and `--entry` when publishing
|
|
168
|
+
from a checkout that was not created by `samva templates init` or `clone`.
|
|
169
|
+
|
|
170
|
+
The helper is invoked by Git using its credential protocol. It accepts only an HTTPS host and path
|
|
171
|
+
matching the project's repository, then exchanges the current Samva credential for a read or write
|
|
172
|
+
Artifact credential. `samva templates credential` is an internal helper command, not a general
|
|
173
|
+
credential store. Local OAuth credentials remain in the OS keyring; `SAMVA_API_KEY` remains the
|
|
174
|
+
automation path.
|
|
175
|
+
|
|
176
|
+
`samva templates check` runs the project's TypeScript configuration, then uses the project's
|
|
177
|
+
`@samva/vite/build` to evaluate default exports, emit SML, compile channel artifacts, and report
|
|
178
|
+
phase/provenance diagnostics plus email-client compatibility findings. It writes no files and exits
|
|
179
|
+
non-zero on TypeScript, discovery, module, theme, emit, compile, or breaking compatibility errors.
|
|
180
|
+
`--watch` reuses one Vite evaluator across template, dependency, discovery, and theme changes.
|
|
181
|
+
Human mode prints each observation; machine watch mode requires `--jsonl`. `--json` remains a
|
|
182
|
+
bounded one-shot result. `SIGINT` and `SIGTERM` close the watcher and keep the CLI's documented
|
|
183
|
+
interrupt exit codes.
|
|
184
|
+
|
|
185
|
+
`samva templates build` runs the same compiler gate and writes the complete compiled result as a
|
|
186
|
+
versioned JSON artifact for package and deployment pipelines. Its terminal/JSON result stays
|
|
187
|
+
bounded and reports only the destination, compiler version, and file count.
|
|
188
|
+
|
|
189
|
+
`samva templates publish` resolves the requested revision to an exact commit, verifies the working
|
|
190
|
+
tree is clean and the commit is an ancestor of the fetched `origin` default branch, then creates an
|
|
191
|
+
immutable publication receipt for the project's configured TSX entry. It does not rewrite Git
|
|
192
|
+
history or alter the working tree.
|
|
193
|
+
|
|
194
|
+
`templates list`, `get`, `create`, `update`, and `remove` operate on template metadata. They do not
|
|
195
|
+
replace the project repository, workspace, or native Git history.
|
|
196
|
+
|
|
128
197
|
Inline email requires `--subject` and exactly one body source: `--html` or `--text`. Pass `-` as
|
|
129
198
|
the value to read that body from stdin: `--text -` reads a plain-text body and `--html -` reads an
|
|
130
199
|
HTML body. Only one body may come from stdin, so passing both `--text -` and `--html -` is rejected.
|