@plitzi/cli 0.37.2 → 0.37.3

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/README.md CHANGED
@@ -3,7 +3,11 @@
3
3
  The command line for Plitzi.
4
4
 
5
5
  ```bash
6
- npx @plitzi/cli create my-site
6
+ npx @plitzi/cli create my-site # a project that renders a space
7
+ npx @plitzi/cli add plugin seat-picker legend # elements of your own, in the project you are in
8
+ npx @plitzi/cli create seat-picker --plugin # a plugin package any space can load
9
+ npx @plitzi/cli pack plugin # a plugin built, and zipped the way the builder takes it
10
+ npx @plitzi/cli upload plugin # that zip, on the space you work in, and installed there
7
11
  ```
8
12
 
9
13
  ## `create`
@@ -12,22 +16,23 @@ Scaffolds a project that renders a Plitzi space, installs it, and leaves it read
12
16
  the package manager, `--mode` and `--source` — and they are the person's to make, so `create` never makes them alone:
13
17
 
14
18
  - **At a terminal**, anything not passed is asked for, with the likely answer offered as the default.
15
- - **With nobody at the terminal** — an agent, CI — it stops before writing anything and prints the flags still
16
- missing, so the agent asks the person rather than guessing. `--yes` takes the defaults (`server`, `local`, the
17
- invoking package manager) for a script that genuinely means them.
19
+ - **With nobody at the terminal** — an agent, CI — it stops before writing anything and prints each missing choice
20
+ as a question for the person, addressed to the agent that ran it: ask the user, wait, run again with their answers.
21
+ It offers no way around them: `--yes` only takes the defaults (`server`, `local`, the invoking package manager) for
22
+ a person at a terminal. A script passes the three flags — which is also what makes it reproducible.
18
23
 
19
- | | `--source local` | `--source cloud` |
20
- |---|---|---|
24
+ | | `--source local` | `--source cloud` |
25
+ | ------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
21
26
  | **`--mode server`** | A page server of your own, rendering a space that lives in the project. No account. | A page server of your own, rendering the live space out of Plitzi. |
22
- | **`--mode client`** | Vite + the SDK in the browser. No server at all, no account. | The SDK fetches the space from Plitzi with the public render key. |
27
+ | **`--mode client`** | Vite + the SDK in the browser. No server at all, no account. | The SDK fetches the space from Plitzi with the public render key. |
23
28
 
24
29
  ```bash
25
30
  plitzi create my-site # asks the three choices
26
31
  plitzi create my-site --package-manager npm --mode server --source local
27
32
  plitzi create my-site --package-manager pnpm --mode client --source local # Vite, hot module replacement
28
33
  plitzi create my-site --package-manager yarn --mode server --source cloud --key … # the live space
29
- plitzi create my-site --yes # server + local + the invoking manager
30
- plitzi create . --force --no-install --yes # into a directory that has work in it
34
+ plitzi create my-site --yes # at a terminal: server + local + the invoking manager
35
+ plitzi create . --force --no-install --package-manager npm --mode server --source local # into a directory that has work in it
31
36
  ```
32
37
 
33
38
  ## The package manager
@@ -35,28 +40,37 @@ plitzi create . --force --no-install --yes # into a d
35
40
  `--package-manager npm|yarn|pnpm` says which one the project is written for: what it installs with, and what
36
41
  every command in its README and its Playwright config names. The one that invoked the CLI is only offered as the
37
42
  default when it is asked for — `yarn dlx` and `pnpm dlx` get their own name suggested — because it is a guess about
38
- the *invocation*: running `npx` once to scaffold a project you then work in with Yarn is exactly the case it gets
43
+ the _invocation_: running `npx` once to scaffold a project you then work in with Yarn is exactly the case it gets
39
44
  wrong.
40
45
 
41
46
  A Yarn project also gets a `.yarnrc.yml` pinning `nodeLinker: node-modules`. Yarn 4 installs Plug'n'Play by
42
- default and a server-mode project cannot start under it — `node --import tsx` dies resolving its own entry — so
43
- the linker is pinned to the layout npm and pnpm already give it.
47
+ default, and the project runs straight from `node_modules` — its server by Node, its plugins by the page server's
48
+ bundler — so the linker is pinned to the layout npm and pnpm already give it.
49
+
50
+ ## Node runs the TypeScript
51
+
52
+ Every script that runs TypeScript — `start`, `author`, `shot` — is plain `node`: Node 22.18+ strips the types
53
+ itself, so nothing transpiles beside the server. (`tsx` did, and its loader thread cost a page server more memory
54
+ than the server: ~270 MB to start where the same server starts in ~90.) The project's `tsconfig` holds it to what
55
+ that needs — relative imports name their `.ts` file (`allowImportingTsExtensions`), type-only imports say so
56
+ (`verbatimModuleSyntax`), nothing is written that stripping would leave broken (`erasableSyntaxOnly`) — so a
57
+ mistake is a `typecheck` error, not a crash at `npm start`. `engines` says `>=22.18`.
44
58
 
45
59
  Each project also carries what lets its **first install through on release day**, which is the day every
46
60
  `@plitzi/*` package it depends on is new:
47
61
 
48
- | Manager | File | Why |
49
- |---|---|---|
50
- | npm | `allowScripts` in `package.json` | npm 11 lists unreviewed install scripts and will start blocking them: esbuild's is approved, fsevents' (a prebuilt binary beside a `binding.gyp`) refused |
51
- | pnpm | `pnpm-workspace.yaml` | pnpm stops the install over a skipped build (`allowBuilds: esbuild`), and holds back packages under its minimum release age (`minimumReleaseAgeExclude: @plitzi/*`) |
52
- | Yarn | `.yarnrc.yml` | Yarn quarantines packages younger than a day (YN0016): `npmPreapprovedPackages: @plitzi/*` — written only for Yarn ≥ 4.10, since an older Yarn refuses a setting it does not know |
62
+ | Manager | File | Why |
63
+ | ------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | npm | `allowScripts` in `package.json` | npm 11 lists unreviewed install scripts and will start blocking them: esbuild's is approved, fsevents' (a prebuilt binary beside a `binding.gyp`) refused |
65
+ | pnpm | `pnpm-workspace.yaml` | pnpm stops the install over a skipped build (`allowBuilds: esbuild`), and holds back packages under its minimum release age (`minimumReleaseAgeExclude: @plitzi/*`) |
66
+ | Yarn | `.yarnrc.yml` | Yarn quarantines packages younger than a day (YN0016): `npmPreapprovedPackages: @plitzi/*` — written only for Yarn ≥ 4.10, since an older Yarn refuses a setting it does not know |
53
67
 
54
68
  The exemptions cover `@plitzi/*` only. A third-party dependency published in the last day is still held back, and
55
69
  when an install fails the CLI says which setting names it.
56
70
 
57
71
  ## What lands in the project
58
72
 
59
- - **The space, as yours.** A local project gets `src/space.ts` — a *copy* of the space Plitzi gives a new
73
+ - **The space, as yours.** A local project gets `src/space.ts` — a _copy_ of the space Plitzi gives a new
60
74
  account, declared as a tree, some CSS and a palette rather than exported as a document. It is the same
61
75
  declaration the platform authors a new space from, so what you start with and what signing up gives you cannot
62
76
  come apart — and unlike a document, you can read and change it.
@@ -64,17 +78,140 @@ when an install fails the CLI says which setting names it.
64
78
  remounted, so the page updates without reloading. In server mode `--watch` restarts the process and the next
65
79
  request renders the change.
66
80
  - **A plugin of the project's own.** `src/plugins/StatCard` is a React component the space renders through a
67
- `custom` element — the one thing about Plitzi a page of built-in elements cannot show. Its props ARE the
81
+ `custom` element — the one thing about Plitzi a page of built-in elements cannot show. Every folder of
82
+ `src/plugins` is registered by itself, under its name in camelCase, so `plitzi add plugin` is all a new one takes. Its props ARE the
68
83
  element's attributes, so a data source pointed at that element later reaches the component with no plumbing in
69
84
  between. Server-rendered in server mode (`action: 'compile'`), part of the bundle in client mode.
70
85
  - **A visual test.** The `visual` script starts the project, opens the page and asserts that every element the space
71
- *names* is visible — the strongest assertion available about a page nobody hand-wrote, and it needs no upkeep.
86
+ _names_ is visible — the strongest assertion available about a page nobody hand-wrote, and it needs no upkeep.
72
87
  - **Prettier and ESLint**, configured rather than mentioned: type-checked rules, with Prettier owning layout and
73
88
  `eslint-config-prettier` keeping the two from arguing on save. `lint` and `format` are scripts from the first
74
89
  commit, which is the only moment a repository's style is cheap to decide.
75
90
  - **The authoring skill**, in `.claude/skills/`, so an agent working in the project knows how a space is put
76
91
  together before it touches one.
77
92
 
93
+ ## `add plugin`
94
+
95
+ Adds elements of your own to the project you are in — one, several at once (`add plugin seat-picker legend`), or one at
96
+ a time as the need comes. Each is a folder, written the way Plitzi's own elements are (`@plitzi/sdk-elements`): the
97
+ component, its `declaration.ts` (its `type`, the events it fires, the actions it answers to, and the element the builder
98
+ adds), its `Settings.tsx` panel for the builder, and the `index.ts` that puts them together. It asks what to call each,
99
+ what the builder shows, and what it is for, and checks every folder is free before writing any.
100
+
101
+ - **In a project `plitzi create` wrote**, it goes in `src/plugins`, where the project already looks: nothing to
102
+ register, and `start:dev` restarts onto it. Host it with `custom({ renderType: 'seatPicker' })` in `src/space.ts`
103
+ — or, when the space lives in Plitzi, with a Custom element in the builder.
104
+ - **In a project written before plugins were found by folder**, it goes in `src/plugins` too, and prints the line to
105
+ add to the `plugins` list in `src/main.ts`.
106
+ - **In a plugin package**, it goes in `src/`, and is added to `src/elements.ts` and `src/declarations.ts`, from which
107
+ the package publishes it.
108
+ - **In any other project**, it asks which folder holds the project's components (`--dir` answers it) and prints how
109
+ to register the element — for `render()`, for `<PlitziSdk>` in a React application, and for a page server.
110
+
111
+ A name that would make a built-in element's type (`button`, `form`) is refused: a space could not tell the two apart.
112
+
113
+ ## `create --plugin`
114
+
115
+ A plugin package: elements any space can load, with a Vite preview to write them in. It builds nothing itself —
116
+ `pack plugin` does, for every plugin — so it carries no bundler config and no build dependency.
117
+
118
+ ```bash
119
+ plitzi create seat-picker --plugin # asks the name, what the builder shows, what it is for, who publishes it
120
+ plitzi create packages/seat-picker --plugin --name @acme/plitzi-plugin-seat-picker --package-manager yarn
121
+ plitzi create seat-picker --plugin --elements legend,price-tag # a package of three elements
122
+ ```
123
+
124
+ Without a directory, inside a repository, it offers the folders that repository keeps its packages in (its workspace
125
+ globs, and `plugins/`); inside one it installs with the repository's own package manager and leaves its install
126
+ settings alone.
127
+
128
+ Its scripts: `start` (every element inside a space, rendered by the SDK in the browser, with hot module
129
+ replacement), `visual` (a browser checks each element renders, answers a click, and leaves the page whole),
130
+ `typecheck`, `lint` and `format`.
131
+
132
+ ## `pack plugin`
133
+
134
+ The one place a plugin is built — from a plugin package, or from element folders of any project:
135
+
136
+ ```bash
137
+ plitzi pack plugin # in a plugin package: every element it holds
138
+ plitzi pack plugin src/plugins/SeatPicker # an element of a self-hosted project
139
+ plitzi pack plugin src/plugins/SeatPicker src/plugins/Legend # several in one plugin, the first its main
140
+ ```
141
+
142
+ It writes one ES module (esbuild; React and the SDK kept out — the page provides them; images and fonts inside, since
143
+ a page imports the module from a blob URL), `plugin-manifest.json` written from the elements' declarations with each
144
+ file's integrity hash, and the zip the builder takes: upload it under Resources, as a plugin. A package also gets its
145
+ type declarations, written with its own TypeScript. Or serve the build at a versioned address with CORS open, and list
146
+ it in a space's plugins as `{ type, resource }`.
147
+
148
+ Without folders, outside a package, it offers the elements in `src/plugins` — the folders with a declaration, which is
149
+ what a manifest is written from. `--out` moves the build, `--no-zip` leaves the zip out, and `--plugin-version` sets the
150
+ version the manifest carries (the project's own by default).
151
+
152
+ ## `login`, `space` and `upload plugin`
153
+
154
+ ```bash
155
+ plitzi login # sign in, in your browser
156
+ plitzi space # choose the space to work in, in your browser
157
+ plitzi whoami # who you are signed in as, and the space
158
+ plitzi upload plugin # the zip pack plugin left, on that space
159
+ plitzi logout # the session revoked on the platform, and forgotten here
160
+ ```
161
+
162
+ Signing in happens in the browser, on the platform's own sign-in — the CLI never asks for a password, and MFA or a
163
+ social sign-in work without it knowing. What it keeps is the session and a way to renew it, in
164
+ `~/.config/plitzi/connection.json` (`%APPDATA%\plitzi` on Windows), readable by you alone. It is renewed on its own,
165
+ and it shows among your account's devices, where it can be ended like any other.
166
+
167
+ **One space at a time.** The space is chosen on the same grant screen an AI connector's is, and the CLI works in that
168
+ one until `plitzi space` chooses another — which replaces the connection, and revokes the one before. No command takes a
169
+ space of its own: an upload goes to the space `plitzi whoami` names, so a plugin meant for a staging space cannot end
170
+ up in the live one because of a flag.
171
+
172
+ `upload plugin` takes the zip named, or the one `pack plugin` left in the project (the newest, when there are several —
173
+ asked at a terminal). It is checked for its `plugin-manifest.json` before anything is sent. Without a connection, or
174
+ without a space, the browser opens for what is missing, so the first upload is one command too. It goes on one of the
175
+ space's CDNs — `--cdn <identifier>`, or asked when there are several — and is installed, as the builder does when a
176
+ zip is dropped under Resources: added, or the plugin already there moved to the new version with its settings kept.
177
+
178
+ `--api` (or `PLITZI_API_URL`) points it at another platform, a self-hosted or local one; the CLI trusts the
179
+ certificate authorities the system trusts, as the browser beside it does.
180
+
181
+ ## `runtime`
182
+
183
+ ```bash
184
+ plitzi runtime push # pack src/runtime.ts and keep it as the space's draft runtime
185
+ plitzi runtime status # how each environment's runtime is, and its variables' names
186
+ printf %s "$URL" | plitzi runtime vars set REDIS_URL # a value from stdin stays out of the shell history
187
+ plitzi runtime vars unset REDIS_URL
188
+ plitzi runtime size medium # the size the draft runs at (--environment for a published one)
189
+ plitzi runtime stop # stopped, and kept stopped until started
190
+ plitzi runtime start # started again — stopped by hand, or for going unused
191
+ ```
192
+
193
+ A space's runtime is its own server code, run beside it on the platform — for what its functions cannot be: a
194
+ connection kept open, memory that outlives a request, Node and its packages (`docs/en/runtimes.md`).
195
+
196
+ **Its code lives in a project of yours** — a folder, usually a repository — and nowhere else: the builder shows how a
197
+ runtime runs and sets its variables, but it does not hold its code and cannot change it. The project has
198
+ `src/runtime.ts` (or `--entry`), whose default export is `defineRuntime(…)`, and `@plitzi/sdk-server` installed: a
199
+ project from `plitzi create` in server mode has it; `examples/self-hosting/10-runtime` is the smallest one to start
200
+ from, and it runs as a server of its own too.
201
+
202
+ `push` packs the module with the project's own `@plitzi/sdk-server` — the module and every package it imports, bar
203
+ `@plitzi/*` and React, which the platform provides — and sends it to the space `plitzi whoami` names. It becomes the
204
+ draft's runtime, which starts on it; **publishing the space** from the builder takes it to the published site. A
205
+ runtime is part of the plans that carry it; on another, the push is refused and says so.
206
+
207
+ **It runs at a size** — small (0.25 CPU, 256 MB), medium (0.5 CPU, 512 MB) or large (1 CPU, 1 GB) — chosen per
208
+ environment among the sizes the space's plan includes. `status` says what each environment runs at and which sizes the
209
+ plan includes; `size` chooses another, and that runtime starts again at it.
210
+
211
+ **An unused runtime stops by itself** — nothing sent to its endpoints and no task run on it for a week, on the platform — so it spends
212
+ nothing idle, and stays stopped until `start`, the builder, a push or a publish starts it again. `status` says when a
213
+ running one would stop, and why a stopped one is.
214
+
78
215
  ## Credentials
79
216
 
80
217
  `create` never mints one. A cloud project's key comes from Credentials in the builder, is written to `.env`, and