@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.
Files changed (4) hide show
  1. package/AGENTS.md +49 -5
  2. package/README.md +80 -11
  3. package/dist/bin.mjs +53555 -4596
  4. 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 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
@@ -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
- `http://127.0.0.1:8787`; `production` targets `https://api.samva.dev`.
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
- Scaffold a project with the Samva TSX runtime, visual editor, and pinned authoring dependencies:
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
- mkdir transactional-email && cd transactional-email
114
- samva templates init
115
- npm install
116
- npm run samva:dev
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 generated project lists `@samva/markup` and `@samva/vite` as development dependencies and Vite
120
- as the editor peer. The compiled CLI deliberately loads `@samva/vite/build` from the current
121
- project, so preview and push use the compiler version recorded in that project's lockfile.
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 push --dir emails --dry-run
125
- samva templates push --dir emails
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.