@plitzi/cli 0.38.5 → 0.38.7
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/CHANGELOG.md +216 -0
- package/README.md +86 -26
- package/dist/index.js +16407 -4695
- package/package.json +3 -3
- package/skills/plitzi-cli/SKILL.md +14 -13
- package/skills/plitzi-cli/reference/functions.md +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,221 @@
|
|
|
1
1
|
# @plitzi/cli
|
|
2
2
|
|
|
3
|
+
## 0.38.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c7bbc2b: ## A server project's `src/main.ts` is a few lines
|
|
8
|
+
|
|
9
|
+
- **`serveProject` from `@plitzi/sdk-server/project`**: the generated `src/main.ts` hands the space, its actions and
|
|
10
|
+
its options to the server, and the rest comes with the package — the port, the plugins of `src/plugins` and
|
|
11
|
+
`vendor/plugins`, the functions and runtime, `public/`, `src/data/`, the `kv` in `state/kv.json`, `/health`,
|
|
12
|
+
`tmp/dev-server.json` and the reloads while developing. A fix there arrives with `npm update`, not `plitzi upgrade`.
|
|
13
|
+
- **No more `tmp/space.json` while developing**: a saved space is authored again in its own process and handed to the
|
|
14
|
+
server over IPC (`plitzi/author.ts --ipc`, in place of `--out`); the server swaps it in memory and the open pages
|
|
15
|
+
reload, and a refused space keeps the last one that authored. `plitzi doctor` reports a leftover `tmp/space.json`.
|
|
16
|
+
- **`projectAuthoring()` in `@plitzi/sdk-authoring/node`**: what a project's space is checked against — its plugins'
|
|
17
|
+
declarations, its built plugins, its data files — once, for the server and `npm run author` alike. Neither it nor
|
|
18
|
+
`serveProject` takes a root: it is the working directory, where every script runs (`projectAuthoringAt(root)` for a
|
|
19
|
+
tool working on another folder).
|
|
20
|
+
- **`authorProjectSpace` and `projectSpace()` in `@plitzi/sdk-authoring/node`**: the project's space read from
|
|
21
|
+
`src/space/index.ts` — `dist/space/index.js` when the server runs built — once its root and layout are checked, and
|
|
22
|
+
authored. `src/main.ts` is `serveProject({ space: authorProjectSpace, actions, connectors, serverOptions })`, with no
|
|
23
|
+
import of the space; `plitzi/author.ts`, the visual tests and the CLI's checks read it the same way. A module that
|
|
24
|
+
exports no `space` is refused saying what to export (`ProjectSpaceError`).
|
|
25
|
+
- **`.env` lives at the root and Node reads it** as each script starts (`--env-file-if-exists=.env`; `start:dev`
|
|
26
|
+
preloads `@plitzi/sdk-server/env`, since a watched process would restart on every change beside the file). Settings
|
|
27
|
+
read at the top level of `src/config/serverOptions.ts` or the actions are set. Every project gets `.env` and
|
|
28
|
+
`.env.example`; `plitzi upgrade` removes the old `src/env.ts`.
|
|
29
|
+
- **One check of a project's layout** (`@plitzi/sdk-shared/project/layout`): a plugin folder with no entry, a
|
|
30
|
+
JavaScript entry, `src/plugin/` for `src/plugins/`, a `.env` inside `src/`, a space exported by default, a broken
|
|
31
|
+
`vendor/` plugin… The server refuses to boot listing every error with its fix, `npm run author` and the CLI's checks
|
|
32
|
+
refuse with the same words, `plitzi doctor` lists them under `layout` and `--fix` makes the ones with a single fix,
|
|
33
|
+
and `plitzi lint` points at doctor. A plugin folder added broken while developing is reported in the terminal
|
|
34
|
+
instead of failing in esbuild. Plugins may start at `index.tsx`.
|
|
35
|
+
- **`createJsonAdapters` serves documents held in memory**: `offlineData` may be a function returning them, not only a
|
|
36
|
+
path.
|
|
37
|
+
- **One source for a project's layout**, `@plitzi/sdk-shared/project/paths`; `src/config/serverOptions.ts` is typed
|
|
38
|
+
`ProjectServerOptions`. `plitzi upgrade files --write` brings an existing project's `main.ts` and `author.ts` up.
|
|
39
|
+
- **`npm run build` no longer fails on a plugin's stylesheet**: `tsconfig.build.json` includes `plitzi/assets.d.ts`,
|
|
40
|
+
which a space importing a plugin's declaration reaches through its component.
|
|
41
|
+
|
|
42
|
+
## A write refreshes what shows it
|
|
43
|
+
- **Writes now refresh server-driven providers.** `runServerAction`, `webHook`, `writeRecord` and the
|
|
44
|
+
`invalidateQueries` step reach `runtime: 'server'` api containers by id, by `query` URL, or all of them, just as
|
|
45
|
+
they reach cached browser requests. Before, they reached only the browser's query cache, so a saved write left the
|
|
46
|
+
page showing the old value until a reload. Hidden providers refresh when they are shown.
|
|
47
|
+
- **A refresh because something changed asks around every cache.** `performQuery`, writes and invalidations send
|
|
48
|
+
`Cache-Control: no-cache`; `/_rsc` resolves such a request again instead of serving its cached slice, and keeps the
|
|
49
|
+
new answer. A `refreshSeconds` timer and a "load more" page still go through the caches.
|
|
50
|
+
- **`refreshRsc`'s fourth argument is an options object**, `{ location?, fresh? }`.
|
|
51
|
+
|
|
52
|
+
## A space's functions read its data
|
|
53
|
+
- **`ctx.data('products.json')`** reads one file of the space's data (a project's `src/data/`), parsed and read-only,
|
|
54
|
+
as of the run's version. Plugins' functions are refused it.
|
|
55
|
+
- **Self-hosted servers read `dataDir` through the same lookup as the platform**, so `/data/<file>` providers and
|
|
56
|
+
`ctx.data` read the same files; `plitzi functions dev` reads `src/data`. `/data/../x.json` is now the provider's
|
|
57
|
+
error state instead of falling through to `publicDir`.
|
|
58
|
+
- **Importing a file outside `functions/` names the boundary and the fix**: read the space's data with
|
|
59
|
+
`ctx.data('<file>')`.
|
|
60
|
+
|
|
61
|
+
## Signing in on a self-hosted server
|
|
62
|
+
- **`createServer({ auth })` tells the pages it renders where to sign in** (`server.auth`: provider, endpoints and
|
|
63
|
+
the session hint cookie), so a space signs in with no auth settings declared. Settings a space does declare still
|
|
64
|
+
win, and a space that names another provider ignores the server's description. New `pageAuth` server option, for a
|
|
65
|
+
deployment whose `/auth` flows are served by another host.
|
|
66
|
+
- **A page with no auth provider no longer offers `auth.login` / `auth.logout`**, and a sign-in that cannot work says
|
|
67
|
+
why in the console (`[plitzi] auth.login: …`) instead of failing silently. What a visitor keeps there
|
|
68
|
+
(`keepState`, `paintedState`) is the browser's, as on any space without accounts: what was kept as a guest's on such
|
|
69
|
+
a page before is let go once, on the first visit after the upgrade.
|
|
70
|
+
- **Renewal verifies the refresh token itself.** `findByRefreshToken` no longer has to report `refreshExpiresAt`; when
|
|
71
|
+
it does, it overrides the token's own expiry.
|
|
72
|
+
- **New authoring reference `auth.md`**: providers, `authLogin` and its result, `authLogout`, `{{ auth.* }}`,
|
|
73
|
+
`accessLevel`, visitor roles, action `access` and `ctx.user`.
|
|
74
|
+
|
|
75
|
+
## Flows
|
|
76
|
+
- **Authoring refuses a `when` that asks a step for a key it never publishes** (`condition-field-unpublished`).
|
|
77
|
+
`whenSucceeded` / `whenFailed` after `authLogin` always ran the failure branch: they read a server action's
|
|
78
|
+
`status`. The message names what the step publishes and suggests testing `signedIn.ok` with `when`.
|
|
79
|
+
- **`explain` lists what a step publishes** (`Reads:`) and finds the auth steps by their builders (`authLogin`,
|
|
80
|
+
`authLogout`, `authRefreshDetails`). `authLogin({ username, password })` no longer needs `mode`.
|
|
81
|
+
|
|
82
|
+
## Elements
|
|
83
|
+
- **Images no longer default to a 140×140 square**: they are 140px wide and as tall as their ratio, so `width` or
|
|
84
|
+
`aspect-ratio` on a class just works. `object-fit` shows in the builder too.
|
|
85
|
+
- **`formControl` with `subType: 'switch'` renders an on/off switch** (`role="switch"`) — it rendered only its label.
|
|
86
|
+
Checkboxes and switches show a `true` default or binding as ticked.
|
|
87
|
+
- **The theme toggle drops the native button look**, and the **`current` style state covers the chosen item of any
|
|
88
|
+
set**: the link to the page shown, a pressed toggle, a selected tab. The exported `CURRENT_PAGE_SELECTOR` is now
|
|
89
|
+
`CURRENT_SELECTOR`.
|
|
90
|
+
- **Element defaults in the style inspector and the MCP catalogue match what the SDK renders**, held by a test. The
|
|
91
|
+
dialog's `bodyContainer` and `headerCloseButton` slots now reach the page; pagination lays out as declared.
|
|
92
|
+
- **Markdown takes a class for each part of the document** through its own slot (`heading`, `paragraph`, `link`,
|
|
93
|
+
`list`, `listItem`, `quote`, `code`, `codeBlock`, `image`, `table`, `anchor`), and `headingLinks: false` drops the
|
|
94
|
+
link each heading offers to itself while keeping its id, so `/page#anchor` links still work. Its description spells
|
|
95
|
+
out the HTML it outputs.
|
|
96
|
+
- **Tabs show every trigger.** The SDK hid every inactive tab item, the header's included, so a set of tabs showed
|
|
97
|
+
one tab and no way to the others; only the body's panels take turns now.
|
|
98
|
+
- **A link that names a query is current only on that query**: of `/?window=6h` and `/?window=24h`, the one shown
|
|
99
|
+
carries `aria-current` — with the path alone, every one of them did. A link with no query is still current on its
|
|
100
|
+
page whatever the query.
|
|
101
|
+
|
|
102
|
+
## The style language says what `customCss` used to
|
|
103
|
+
- **Pseudo-elements on a class**: `pseudos: { after: { css: { content: '"→"' }, states: { hover: { … } } } }` —
|
|
104
|
+
`before`, `after`, `marker`, `placeholder`, `first-letter`, `first-line`, `selection`, each in the class's states and
|
|
105
|
+
variants. Authoring refuses what draws nothing: a `before`/`after` with no `content`, a `content` without its quotes,
|
|
106
|
+
a property the browser drops on that pseudo-element.
|
|
107
|
+
- **Conditions on a class**: `conditions: { 'motion-reduce': { … }, 'container card (max-width: 30rem)': { … } }` —
|
|
108
|
+
reduced or allowed motion, and container widths, each with its states and pseudo-elements.
|
|
109
|
+
- **The space's `keyframes`**, validated and written at the top of `customCss`; an `animation-name` no keyframes declare
|
|
110
|
+
is warned (`animation-name-unknown`).
|
|
111
|
+
- **New states**: `expanded` (`aria-expanded`), `first`, `last`, `odd`, `even`; the tab panel on show is `current`, and
|
|
112
|
+
the theme toggle's icon of the scheme in use is `current` on its `icon` slot.
|
|
113
|
+
- **`ancestors['>']`** is the parent, whatever it wears — a closed component's part reacting to the element around it.
|
|
114
|
+
- The builder's style inspector, the MCP's definition ops (`pseudos`, `conditions`, and variants with their states) and
|
|
115
|
+
the export to code read and write all of it; an MCP `patchDefinition` no longer drops what it did not name. Rules in
|
|
116
|
+
`customCss` a class can hold now — `.link::after`, one under `@media (prefers-reduced-motion: reduce)`, `.row:first-child`,
|
|
117
|
+
`.row:nth-child(even)`, `.toggle[aria-expanded='true']` — are folded into the class on export and suggested by
|
|
118
|
+
`custom-css-class`.
|
|
119
|
+
|
|
120
|
+
## Elements take a class for each part
|
|
121
|
+
- **`formControl`**: `field` (the `<input>` itself), `icon` (the show-password button) and `requiredMark` slots; a switch's
|
|
122
|
+
knob reads in dark mode and takes `--plitzi-switch-thumb`, `--plitzi-switch-thumb-checked`, `--plitzi-switch-thumb-shadow`.
|
|
123
|
+
- **`pagination`**: `previous`, `page` (the one shown is its `current` state), `next`, `loadMore`.
|
|
124
|
+
- **`richText`** and **`markdown`**: a slot per part — `heading` and `heading1`…`heading6`, `strong`, `emphasis`,
|
|
125
|
+
`divider`, `tableHead`, `tableRow`, `tableHeaderCell`, `tableCell`, and the code block's frame, header, language and
|
|
126
|
+
copy button. Both heading slots dress one `<h3>`, so `heading-level-overridden` warns when they set the same property
|
|
127
|
+
and the stylesheet's order makes the general one win. A document is drawn by the SDK's own renderer
|
|
128
|
+
(`MarkdownDocument` in `@plitzi/sdk-elements`) — plitzi-ui's `Markdown` keeps GitHub's stylesheet for a library's
|
|
129
|
+
consumers — and reads as a document unstyled: headings, lists, code, tables and quotes get their type from the SDK's
|
|
130
|
+
base layer, at no weight (`:where()`), so a class on a part's slot replaces what it sets property by property. A
|
|
131
|
+
`richText` body reads the same.
|
|
132
|
+
- `custom-css-slot` suggests the slot for a `customCss` rule on a part's SDK class — only where a class on the slot can
|
|
133
|
+
say the rest of the selector (a state, a pseudo-element); `element-slot-unknown` warns of a slot an element does not
|
|
134
|
+
have.
|
|
135
|
+
|
|
136
|
+
## Links, refreshes and toasts
|
|
137
|
+
- **`current: 'section'` on a link** keeps it current on its page and every page under its path (`aria-current="true"`
|
|
138
|
+
there), styled by the `current` state — no `activeOn` binding for a section.
|
|
139
|
+
- **A refresh asks only about elements the page shown holds**: a provider on the page being left no longer sends a
|
|
140
|
+
`/_rsc` about the new address.
|
|
141
|
+
- **The toasts' parts are `notifications` fields**: `minHeight`, `fontWeight`, `lineHeight`, `iconSize`, `iconGap`,
|
|
142
|
+
`closeColor`, `closeOpacity`, `progressHeight`.
|
|
143
|
+
- **A page asked for with its space's token hydrates its own space.** On a host serving many spaces
|
|
144
|
+
(`?access-token=`), the space document fetched beside the page went without the token, so the host's own space
|
|
145
|
+
answered it and the browser hydrated another space's document over the page — a hydration error, and its tree
|
|
146
|
+
rebuilt. The document's address now carries the token the page was asked for with.
|
|
147
|
+
- **The SDK's stylesheet carries the space's variables from the server's HTML.** It read them from what a provider
|
|
148
|
+
below it publishes while the page renders, which the server had not done yet when it wrote the sheet; it now
|
|
149
|
+
resolves them from the document itself (`useResolvedVariables` of `@plitzi/sdk-shared/dataSource/hooks`), the same
|
|
150
|
+
on both sides.
|
|
151
|
+
- **A realtime message the pub/sub cannot deliver is answered, not fatal.** A publish that Redis refuses — a timeout under
|
|
152
|
+
load — is answered `503` with `reason: 'unavailable'`, by the `POST` and in the WebSocket's `ack` alike; a connect,
|
|
153
|
+
a disconnect or a revoke that fails is logged, on either transport. Each used to reject with nobody waiting, and the server's `unhandledRejection` handler
|
|
154
|
+
shut the whole process down.
|
|
155
|
+
|
|
156
|
+
## Reporting to Plitzi
|
|
157
|
+
- **`plitzi feedback`** starts a report of what broke, misled or cost time: it writes the page the report is laid out
|
|
158
|
+
in (`tmp/feedback/`) with the installed versions, the project and what `doctor` finds already in it, and tells the
|
|
159
|
+
agent how to fill it — each finding reproduced first, with evidence, impact, workaround and fix, no secrets — and to
|
|
160
|
+
publish it as an artifact whose link the developer sends. `--previous <url>` continues an earlier report.
|
|
161
|
+
|
|
162
|
+
## Pages that load on every browser
|
|
163
|
+
- **The import map comes before anything that loads a module**, in the page server's HTML, a published site's
|
|
164
|
+
(`index.hbs` on the platform), the SDK's and the builder's. React's `modulepreload` links came first, and a browser
|
|
165
|
+
that had fetched a module already — Chrome before 133 — ignored the map: every bare `import "react"` failed
|
|
166
|
+
("Failed to resolve module specifier") and the page never hydrated.
|
|
167
|
+
|
|
168
|
+
## The dev tools
|
|
169
|
+
- **A page loads the React its dev tools need.** The development build only while the visitor has the dev tools on
|
|
170
|
+
(shift+F12, within what the deployment allows); turned off, the next load is a production page, React included. It
|
|
171
|
+
followed the authorization alone, so a space that allowed debugging always shipped development React.
|
|
172
|
+
|
|
173
|
+
## check and lint
|
|
174
|
+
- **`plitzi check`, `push`, `lint` and `fix` hold the space to what `npm run author` and the server do**: its data
|
|
175
|
+
files too, so `push` no longer sends a space whose browser provider reads `src/data/` (`server-data-in-browser`).
|
|
176
|
+
- **`plitzi check` lists each list's rows as drawn and as held in its source** (`feed 4 of 8 rows`,
|
|
177
|
+
`hits not rendered (16 in its source)`). In `--json`, `lists` is now `{ id: { rendered, source } }`.
|
|
178
|
+
- **`plitzi check` no longer reports bindings inside a container the page isn't showing**, nor text "in the colour
|
|
179
|
+
behind it" because of a bar painted over it or a pane that clips it.
|
|
180
|
+
- **`window.__plitzi.sources()` no longer turns a shared array into `'[…]'`**, and a list row no longer replaces its
|
|
181
|
+
list's `items`.
|
|
182
|
+
- **`plitzi lint` says authoring suggestions are quieted with `quiet` on the element**, and reports a
|
|
183
|
+
`plitzi-lint-disable` comment that names one (`disable-names-suggestion`).
|
|
184
|
+
- **`plitzi check` says when a page sent the browser elsewhere** (a page for signed-in visitors, to the sign-in) instead
|
|
185
|
+
of reporting every element missing, and `--as <username>` signs in first through the server's `/auth` routes, the
|
|
186
|
+
password from `PLITZI_CHECK_PASSWORD`.
|
|
187
|
+
- **`plitzi upgrade` never replaces @plitzi packages installed locally** — a tarball, a link, a portal, an override: it
|
|
188
|
+
leaves them and the install, and says which and the command that would install the registry's.
|
|
189
|
+
- **`plitzi explain` covers every code**: authoring's, `plitzi lint`'s and the project layout's.
|
|
190
|
+
- **Authoring reads the global sources' fields**: `auth.authenticated` in a condition is refused with "did you mean
|
|
191
|
+
`isAuthenticated`?" (`global-field-unknown`), and `invalidateElements` must name providers that exist
|
|
192
|
+
(`element-ids-target`). A template's reads of `computed`, `flags` and the global sources come off the parsed
|
|
193
|
+
template: a string inside it (`'https://auth.acme.com'`) is no longer read as `auth.acme`.
|
|
194
|
+
- **`custom-css-notifications` no longer reads the rules `notifications` itself writes** as toasts dressed by hand.
|
|
195
|
+
- **A refused space or layout is a report, not a stack**: the server's entry point imports the space once the layout is
|
|
196
|
+
checked, and `npm start` and `npm run author` print every problem and exit with 1.
|
|
197
|
+
- **New authoring suggestion `class-overrides-class`**: one class's shorthand (`padding`) silently erases a longhand
|
|
198
|
+
(`padding-top`) another class on the same element writes out.
|
|
199
|
+
|
|
200
|
+
- Updated dependencies [c7bbc2b]
|
|
201
|
+
- @plitzi/sdk-authoring@0.38.7
|
|
202
|
+
|
|
203
|
+
## 0.38.6
|
|
204
|
+
|
|
205
|
+
### Patch Changes
|
|
206
|
+
|
|
207
|
+
- 3bce653: ## Fixes
|
|
208
|
+
|
|
209
|
+
- **The dev tools draw their icons again.** The panel lives in a shadow root of its own, which the page's stylesheets
|
|
210
|
+
never reach, and Font Awesome moved to a sheet of its own in 0.38.5 (`plitzi-sdk-icons.css`): the badge and every tab
|
|
211
|
+
lost their icons. The panel now links that sheet inside its root, beside its own. Where it is served is the SDK's
|
|
212
|
+
new `sdkIconsStylePath` — the page server sends `/sdk-assets/plitzi-sdk-icons.css`, the same sheet the document
|
|
213
|
+
links — which the `iframe` and `shadow` render modes read too: they had `/plitzi-sdk-icons.css` hard-coded, a path a
|
|
214
|
+
page server does not serve.
|
|
215
|
+
|
|
216
|
+
- Updated dependencies [3bce653]
|
|
217
|
+
- @plitzi/sdk-authoring@0.38.6
|
|
218
|
+
|
|
3
219
|
## 0.38.5
|
|
4
220
|
|
|
5
221
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -109,8 +109,9 @@ when an install fails the CLI says which setting names it.
|
|
|
109
109
|
from, so what you start with and what signing up gives you cannot come apart — and unlike a document, you can read
|
|
110
110
|
and change it.
|
|
111
111
|
- **A live loop.** In client mode a save is a hot module replacement: the space module is swapped and the tree
|
|
112
|
-
remounted, so the page updates without reloading. In server mode `start:dev`
|
|
113
|
-
|
|
112
|
+
remounted, so the page updates without reloading. In server mode `start:dev` authors a saved space again — in a
|
|
113
|
+
process of its own, handing the documents to the server, which serves them from memory — and the open page loads
|
|
114
|
+
again; it swaps a saved plugin where it is drawn, and restarts only for the server's own code.
|
|
114
115
|
- **A plugin of the project's own.** `src/plugins/StatCard` is a React component the space renders through a
|
|
115
116
|
`custom` element — the one thing about Plitzi a page of built-in elements cannot show. Every folder of
|
|
116
117
|
`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
|
|
@@ -141,20 +142,28 @@ when an install fails the CLI says which setting names it.
|
|
|
141
142
|
| `src/data/` | Server mode: the project's own data — JSON its server reads for a provider (`query: '/data/<file>'`, `runtime: 'server'`) and never serves (`dataDir`). What a provider reads is in the page it renders: data a page must not carry is a server action's to read | yes |
|
|
142
143
|
| `src/functions/` | Server mode: the project's own server code — tasks and `/fn/` routes (`defineFunctions`), built at boot | yes |
|
|
143
144
|
| `vendor/plugins/` | The plugins the project runs as they were built, with no source (a project made from a space gets them), each folder with its `plugin-manifest.json`. The server runs them, and `author`, `check`, `fix` and `push` know every element type each provides | yes |
|
|
144
|
-
| `tmp/` | What the project writes for itself while it runs: the plugins the server builds (`tmp/.sdk-plugins`), resized pictures, the port it took (`tmp/dev-server.json`),
|
|
145
|
+
| `tmp/` | What the project writes for itself while it runs: the plugins the server builds (`tmp/.sdk-plugins`), resized pictures, the port it took (`tmp/dev-server.json`), screenshots and test output. Rebuilt when missing | no |
|
|
145
146
|
| `state/` | Server mode: what the server keeps for the space — its `kv` in `state/kv.json` (`createFileKv`): saved layouts, counters, cached answers. The deployment's state: kept across restarts, never rebuilt. `action.kv` in `src/config/serverOptions.ts` keeps it elsewhere (`createSqliteKv` for several processes, or a database) | no |
|
|
146
147
|
| `.plitzi/` | What the CLI records about the project: the space it came from (`space.json`), the functions' working copy, the files `create` wrote — what `pull`, `push` and `upgrade` stand on | yes |
|
|
147
148
|
|
|
148
149
|
**`plitzi/` is the CLI's; `src/` is yours — but `src/main.ts`.** `plitzi/` holds `author.ts`, the types plugins import
|
|
149
150
|
(`assets.d.ts`, server mode) or the page's base styles (`preflight.css`, client mode), and a `README.md` saying what
|
|
150
151
|
each folder of `src/` is. `src/main.ts`, the entry point, is the CLI's too, kept in `src/` where an entry point is
|
|
151
|
-
looked for; `upgrade` keeps all of them current, and the build compiles `src/` into `dist/main.js`.
|
|
152
|
+
looked for; `upgrade` keeps all of them current, and the build compiles `src/` into `dist/main.js`. In server mode it is a few lines: it authors the space
|
|
153
|
+
(`authorProjectSpace` from `@plitzi/sdk-authoring/node`, which reads `src/space/` as `author` reads it) and hands
|
|
154
|
+
it, the actions and the options to `serveProject` from `@plitzi/sdk-server/project`, which wires the rest from where the
|
|
155
|
+
project keeps it — so a fix to the server arrives with `npm update`, not as a file to upgrade. Neither is told where the
|
|
156
|
+
project is: it is the folder every script runs in, and both refuse to start anywhere else, naming what is missing
|
|
157
|
+
(`package.json`, `src/`) — run them from the project's root. Nor do they start on a part where nothing reads it — a
|
|
158
|
+
plugin folder with no `index.ts`, code in `src/plugin/`, `.env` in `src/` — naming every one at once (`doctor` says each
|
|
159
|
+
with its fix). A plugin is declared by its folder: the server, `author` and `check` find every
|
|
152
160
|
`src/plugins/<Name>/declaration.ts` (`pluginDeclarations` from `@plitzi/sdk-authoring/node`). What the server does
|
|
153
|
-
besides serving the space is the project's own, in files it reads: `src/config/serverOptions.ts` (handed to `
|
|
161
|
+
besides serving the space is the project's own, in files it reads: `src/config/serverOptions.ts` (handed to `serveProject` —
|
|
154
162
|
`images`, `action.limits`, `action.kv`, `rsc`) and, with `--source local`, `src/actions/index.ts` (the space's server
|
|
155
163
|
actions, one `defineAction` each, a file each as they grow).
|
|
156
|
-
What `
|
|
157
|
-
actions' lookups — is left out of `serverOptions`' type, and comes after it, so an option
|
|
164
|
+
What `serveProject` wires itself — where the space comes from, the plugins, `public/`, `src/data/`, `src/functions/`,
|
|
165
|
+
the actions' lookups — is left out of `serverOptions`' type (`ProjectServerOptions`), and comes after it, so an option
|
|
166
|
+
there can never unwire it.
|
|
158
167
|
`src/functions/` holds the project's own server code; `start:dev` restarts on a change to any of them. A plugin is not
|
|
159
168
|
server code to restart for: a save to one is built again and swapped in the open pages where it is drawn — the rest of
|
|
160
169
|
the page, its state included, stays — its server half (`src/plugins/<Name>/functions/`) is loaded again in place, and a
|
|
@@ -176,6 +185,7 @@ with `--source local`.
|
|
|
176
185
|
plitzi check / --width 1440,390 # is the page whole? in text, per width; --json for a tool
|
|
177
186
|
plitzi check /products --state --element catalog-count # and what it holds: state, sources, one element
|
|
178
187
|
plitzi check / --ssr # and what the server's HTML lacks that the hydrated page has
|
|
188
|
+
PLITZI_CHECK_PASSWORD=… plitzi check /studio --as maya # a page for signed-in visitors, signed in through /auth first
|
|
179
189
|
plitzi shot /about --width 390 --scheme dark
|
|
180
190
|
plitzi shot / --frames 4 --every 500 # what moves: a marquee, an autoplay
|
|
181
191
|
plitzi shot / --compare https://example.com --width 1440 # beside another site: what differs, and how
|
|
@@ -186,8 +196,9 @@ another project. They wait for the page to settle — loaded, then half a second
|
|
|
186
196
|
stream that stays open, so a page with a realtime `channel` is checked like any other (`openPage` of
|
|
187
197
|
`@plitzi/sdk-authoring`, which the generated `npm run visual` uses too). `check` reports every element the space owes the page that is missing or hidden (with why), broken
|
|
188
198
|
images, sideways scroll, text in the colour behind it, console errors, refused requests and failed flows — and the
|
|
189
|
-
page's data: a binding that reads a path its provider's answer lacks (with the keys it has)
|
|
190
|
-
the
|
|
199
|
+
page's data: a binding that reads a path its provider's answer lacks (with the keys it has) — none inside an element
|
|
200
|
+
the page is not showing, which is not mounted — a provider that failed, and each list's rows, drawn and in its source
|
|
201
|
+
(`feed 4 of 8 rows`, `hits not rendered (16 in its source)`; `--json`: `lists: { id: { rendered, source } }`). A page's state in a few hundred tokens, where a screenshot costs thousands.
|
|
191
202
|
|
|
192
203
|
`--scheme` is the space's own theme, set as a visitor's toggle sets it (the `theme` cookie); left out, the space's
|
|
193
204
|
default, and `shot` names the file by the theme it was painted in. The dev tools' badge is hidden from both. A
|
|
@@ -236,13 +247,16 @@ has it as `npm run lint:space`.
|
|
|
236
247
|
| `special-case-in-map` | a `map` that singles out a row by its `id`, `key`, `slug`, `name`, `title` or `label`: the difference belongs in the row's data |
|
|
237
248
|
| `colour-not-token` | a hex, `rgb()`/`hsl()`/`oklch()`… or a named colour where a colour is all a property takes — outside the declared tokens (`variables`, `light`/`dark`), anchors, masks, markup and URLs |
|
|
238
249
|
| `positional-id` | an id minted for an element nobody named — `container-45`, `heading-a7k2` |
|
|
250
|
+
| `disable-names-suggestion` | a `plitzi-lint-disable` comment naming a suggestion of authoring's, which a comment does not silence: `quiet: ['<code>']` on its element |
|
|
239
251
|
| `space-does-not-author` | error: the space does not author, so authoring's suggestions could not be read — `npm run author` says why |
|
|
252
|
+
| `project-layout` | error: the project is laid out where its server and `npm run author` refuse to start — one line, each error `doctor`'s to say; authoring's suggestions are read once they are fixed |
|
|
240
253
|
| `source-unreadable` | error: the source could not be read (no TypeScript installed, a rule that could not finish) |
|
|
241
254
|
|
|
242
255
|
Beside them, every suggestion authoring makes about the space it authors to (`authorSpace(…).suggestions`) — whatever
|
|
243
256
|
its code, the day authoring adds it — as a warning at the line that wrote its element; `plitzi explain <code>` says what
|
|
244
|
-
each means. They are quieted on the element (`quiet: ['repeated-shape']`), where the builder and the MCP read it too
|
|
245
|
-
A practice the source departs from on purpose is said where it is, eslint's way
|
|
257
|
+
each means. They are quieted on the element (`quiet: ['repeated-shape']`), where the builder and the MCP read it too —
|
|
258
|
+
the report says so under them. A practice the source departs from on purpose is said where it is, eslint's way, for
|
|
259
|
+
lint's own codes:
|
|
246
260
|
`// plitzi-lint-disable-next-line colour-not-token -- the partner's own red`, `-line` for its own line, and
|
|
247
261
|
`// plitzi-lint-disable <codes>` for the whole file.
|
|
248
262
|
|
|
@@ -283,7 +297,7 @@ did not write again.
|
|
|
283
297
|
|
|
284
298
|
```bash
|
|
285
299
|
plitzi explain container # an element: its attributes and their values, what it fires and answers, its slots
|
|
286
|
-
plitzi explain navigate # a step: its params and the function that writes it
|
|
300
|
+
plitzi explain navigate # a step: its params, what it publishes, and the function that writes it
|
|
287
301
|
plitzi explain onScroll # a trigger: what it hands its flow, and what fires it
|
|
288
302
|
plitzi explain class-and-css # a problem's code: what was wrong, what to write instead
|
|
289
303
|
plitzi explain content-attribute # a suggestion's code: what is written the long way, and the short one
|
|
@@ -315,25 +329,43 @@ commands (`plitzi upgrade --write`, an install, `doctor --fix`) that clear most
|
|
|
315
329
|
|
|
316
330
|
**`--fix`** makes only what is simple and safe, then examines the project again: a layout an older CLI left, moved (every
|
|
317
331
|
import, `new URL(…, import.meta.url)` and script naming a moved file follows, and what the CLI recorded of its files
|
|
318
|
-
follows them);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
332
|
+
follows them); a part out of place with one reading of where it goes, moved the same way — `src/plugin/` into
|
|
333
|
+
`src/plugins/`, an `index.js` to `index.ts`, `src/.env` to the root when it has none, a name that differs only in case
|
|
334
|
+
renamed through one of its own; `.env.example` written from `.env` with no value kept, `.env` copied from
|
|
335
|
+
`.env.example`; an older CLI's dead files and caches deleted; `.gitignore` lines added or taken out; `"type": "module"`
|
|
336
|
+
and `engines`; a folder `start:dev` watches; a `PLITZI_SIGNING_SECRET` where there is none (or one too short). A move
|
|
337
|
+
that would write over a file is said and left. What replaces a file of the project's, installs, or touches git is
|
|
338
|
+
recommended, never done — `upgrade --write` and the install are a step of their own.
|
|
322
339
|
|
|
323
340
|
**A project an older CLI made** is the usual patient, and its own installed CLI may predate `doctor`: run the latest one
|
|
324
341
|
from it — `npx @plitzi/cli@latest doctor --fix`, then what it recommends. While its layout is an older one (the space in
|
|
325
342
|
`src/space.ts`, `author` in `src/`, `functions/` at the root), nothing else is checked — read against it, every other
|
|
326
343
|
area would only say what the move fixes — and `upgrade` writes no file until it is moved.
|
|
327
344
|
|
|
345
|
+
**Where each part lives** is one check (`checkProjectLayout`, `@plitzi/sdk-shared/project/layout`) said by three: the
|
|
346
|
+
server refuses to start on its errors, listing every one (and prints its warnings while developing — a plugin folder
|
|
347
|
+
added broken while `start:dev` runs is said there, and the server goes on), `npm run author` and the CLI's checks
|
|
348
|
+
(`check`, `push`, `fix`) refuse to author, and `doctor` says each with its fix under `layout`. `lint` says in one line
|
|
349
|
+
that there are some. Its codes, each with what it means, are `PROJECT_LAYOUT_CODES`: errors — a plugin folder with no
|
|
350
|
+
`index.ts` (or `index.tsx`), or both; a JavaScript entry; a folder name that is no element type (`story-editor` →
|
|
351
|
+
`StoryEditor`), two folders of one type, a plugin also built in `vendor/plugins/`; a plugin's `functions/`,
|
|
352
|
+
`src/functions/` or `src/runtime/` with code and no `index.ts`; a local space with no `src/space/index.ts`, or one
|
|
353
|
+
exported by default; a built plugin whose manifest is missing, unreadable, or names no script there; `.env` inside
|
|
354
|
+
`src/`; code in a folder named like one the server reads (`src/plugin/`, `plugins/` at the root). Warnings — the same
|
|
355
|
+
folder with nothing it would read (`src/Data/`, `src/runtimes/`, `src/public/`); a plugin with no `declaration.ts`; a
|
|
356
|
+
file loose in `src/plugins/`; a file of `src/data/` that is not JSON; no `.env` or no `.env.example`; JSON in
|
|
357
|
+
`public/data/` of a project with a server, and a file in `public/` named like a secret. A near name is asked about —
|
|
358
|
+
did you mean `index.ts`, `src/plugins/`? — and one that differs only in case says it works on macOS and not on Linux.
|
|
359
|
+
|
|
328
360
|
| Area | What is held |
|
|
329
361
|
|---|---|
|
|
330
|
-
| `layout` | where an older CLI kept what this one reads elsewhere (`src/space.ts`, `src/site/`, `src/actions.ts`, `src/author.ts`, `functions/`) and what it left behind (`src/plugins/declarations.ts`, `.sdk-plugins/`, `.plitzi/dev-server.json`) |
|
|
331
|
-
| `packages` | `"type": "module"`, the Node version; every package the project and its scripts need, declared and installed at a version its range allows; the SDK's packages at one version, no older than the CLI; one copy of the SDK and of React (none installed inside another); the scripts — gone, behind the CLI, or the project's own — the file each Node script starts
|
|
332
|
-
| `machinery` | the CLI's files (`MACHINERY`), as `upgrade` sees them: gone, behind, or the project's own (said, never failed); the scaffold record |
|
|
362
|
+
| `layout` | where an older CLI kept what this one reads elsewhere (`src/space.ts`, `src/site/`, `src/actions.ts`, `src/author.ts`, `functions/`) and what it left behind (`src/plugins/declarations.ts`, `.sdk-plugins/`, `.plitzi/dev-server.json`, the `tmp/space.json` an older `src/main.ts` re-read the space from); every part where the server, `npm run author` and the CLI's checks read it (`PROJECT_LAYOUT_CODES`, above) |
|
|
363
|
+
| `packages` | `"type": "module"`, the Node version; every package the project and its scripts need, declared and installed at a version its range allows; the SDK's packages at one version, no older than the CLI; one copy of the SDK and of React (none installed inside another); the scripts — gone, behind the CLI, or the project's own — the file each Node script starts, every folder `start:dev` watches, and a server's scripts reading `.env` (`--env-file-if-exists`; a watched one by the preload, never Node's flag); one lockfile |
|
|
364
|
+
| `machinery` | the CLI's files (`MACHINERY`), as `upgrade` sees them: gone, behind, or the project's own (said, never failed); one it no longer writes, left over (`src/env.ts`); the scaffold record |
|
|
333
365
|
| `config` | `tsconfig.json` reads `src/` and `plitzi/` and sets what Node's type stripping needs; `tsconfig.build.json` writes the file `start:prod` runs; `.gitignore` keeps `.env` out (and `node_modules`, `tmp`, `dist`, `state`) and `.plitzi/` in; `.env` not in git; the signing secret, as long as the project's own server wants it; a cloud project's key |
|
|
334
366
|
| `sources` | what Node runs as written — `src/main.ts`, `src/config/`, `src/actions/`, `src/space/`, `src/runtime/`, `plitzi/author.ts`, the plugins' declarations, and all they import: every relative import a file that is there, with its extension; JSON imported `with { type: 'json' }`; no JSX; every package declared (a devDependency, in what production runs, is said); what the server loads by name exported (`space`, `actions`, the runtime's default) |
|
|
335
|
-
| `plugins` | each folder of `src/plugins
|
|
336
|
-
| `data` | every file of `src/data/` and `public/data/`
|
|
367
|
+
| `plugins` | each folder of `src/plugins/` the server can build: its entry builds and exports its component, its packages declared; its `declaration.ts` loads and its `type` is the folder's (`StatCard` → `statCard`) |
|
|
368
|
+
| `data` | every JSON file of `src/data/` and `public/data/` parses — what the server answers with and `push` sends |
|
|
337
369
|
| `functions` | `src/functions/` built by the project's own `@plitzi/sdk-server` (`buildFunctions`), as every runner builds them |
|
|
338
370
|
| `records` | `.plitzi/space.json`, `scaffold.json` and `functions.json` readable, and of the same space |
|
|
339
371
|
| `skills` | `.claude/skills/plitzi-*` as the packages installed write them |
|
|
@@ -342,6 +374,24 @@ It loads the plugins' declarations and the project's own `@plitzi/sdk-server` to
|
|
|
342
374
|
never starts the server or the runtime. A check that cannot finish is said as an error
|
|
343
375
|
of its area, never a crash.
|
|
344
376
|
|
|
377
|
+
## `feedback`
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
npx @plitzi/cli feedback # a report to Plitzi, started
|
|
381
|
+
npx @plitzi/cli feedback --previous https://claude.ai/artifact/… # continuing an earlier one
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
A report of what broke, misled or cost time, for a developer to send to Plitzi as a link. The CLI reads what a report
|
|
385
|
+
must not get wrong — every `@plitzi` package installed and its version, Node and the machine, the project's mode and
|
|
386
|
+
source, what `plitzi doctor` finds — and writes the page the report is laid out in, `tmp/feedback/report-<date>.html`:
|
|
387
|
+
a tally by severity, what was built, what changed since the earlier reports, where to start, the findings filtered by
|
|
388
|
+
severity and area and each copied as an issue, and what worked — in light and dark, on a phone. It prints how to fill
|
|
389
|
+
it for the agent the developer works with: one `REPORT` object, each finding reproduced on the installed versions
|
|
390
|
+
before it is written, with what happens, the evidence, the impact, the workaround and a fix; no secret, token or
|
|
391
|
+
customer's data. The agent then publishes it as a private artifact and gives the developer its URL. `--previous` hands
|
|
392
|
+
it the earlier reports: their numbering goes on, and what changed of each finding is said. `--json`: `{ file, facts,
|
|
393
|
+
brief }`.
|
|
394
|
+
|
|
345
395
|
## `upgrade`
|
|
346
396
|
|
|
347
397
|
```bash
|
|
@@ -358,10 +408,12 @@ one the project made its own is a diff, left unless `--take` names it (`all` for
|
|
|
358
408
|
`.prettierignore` names them, so the project's `format` never turns one into a file `upgrade` believes was changed. A file of the project's own
|
|
359
409
|
that the machinery reads (`src/config/serverOptions.ts`, `src/actions/index.ts`) is written when the project has none and the
|
|
360
410
|
`main.ts` reading it is the CLI's, and never replaced. A script is the same: one the CLI wrote and nobody changed takes
|
|
361
|
-
today's command, one the project changed is left and said
|
|
411
|
+
today's command, one the project changed is left and said. A file the CLI no longer writes — `src/env.ts`, now that
|
|
412
|
+
Node reads `.env` — is removed the same way once the `main.ts` that read it is the CLI's; one the project changed is
|
|
413
|
+
said and left, unless `--take` names it (`.plitzi/scaffold.json` records the files and the scripts, and the package
|
|
362
414
|
manager the files were written for — what a project not installed yet has no lockfile to say). In a project made from
|
|
363
415
|
a space, a file the space gave over one of the CLI's would be the space's, and `upgrade` would leave it to `plitzi pull` —
|
|
364
|
-
none does: `
|
|
416
|
+
none does: `serveProject` runs whatever the space brought, from where it lands. `update` is the same
|
|
365
417
|
command, and `plitzi skills update` is `upgrade skills --write`. `npm run author` says when the authoring skill is
|
|
366
418
|
older than the `@plitzi/sdk-authoring` installed.
|
|
367
419
|
|
|
@@ -428,8 +480,9 @@ said before anything is sent, with what to do: a provider reading a file `src/da
|
|
|
428
480
|
Adds elements of your own to the project you are in — one, several at once (`add plugin seat-picker legend`), or one at
|
|
429
481
|
a time as the need comes. Each is a folder, written the way Plitzi's own elements are (`@plitzi/sdk-elements`): the
|
|
430
482
|
component, its `declaration.ts` (its `type`, the events it fires, the actions it answers to, and the element the builder
|
|
431
|
-
adds), its `Settings.tsx` panel for the builder, and the `index.ts` that puts them together
|
|
432
|
-
|
|
483
|
+
adds), its `Settings.tsx` panel for the builder, and the `index.ts` that puts them together — what the folder is built
|
|
484
|
+
from: `index.ts`, or `index.tsx` for one that writes its JSX there, never both. It asks what to call each, what the
|
|
485
|
+
builder shows, and what it is for, and checks every folder is free before writing any.
|
|
433
486
|
|
|
434
487
|
- **In a project `plitzi create` wrote**, it goes in `src/plugins`, where the project already looks: nothing to
|
|
435
488
|
register, and a running `start:dev` picks it up without a restart. Host it with `custom({ renderType: 'seatPicker' })` in `src/space/`
|
|
@@ -608,7 +661,14 @@ throws it away) and `push` refuses when the space moved on since. A problem come
|
|
|
608
661
|
names them differently on purpose: a server gets the secret self-hosting key, a browser gets the public render key,
|
|
609
662
|
whose protection is the origin it is presenting from.
|
|
610
663
|
|
|
611
|
-
Every
|
|
664
|
+
Every project has a `.env`, never committed, and a `.env.example`, committed: the same settings with no secret in them,
|
|
665
|
+
for a clone to copy and fill in. A server project's `.env` is read as each script starts —
|
|
666
|
+
`node --env-file-if-exists=.env` in `start`, `start:prod` and `author`, and in `start:dev`, which Node watches,
|
|
667
|
+
`node --import @plitzi/sdk-server/env` (Node's flag there has its watcher restart on every write in the project) —
|
|
668
|
+
before any of its modules is evaluated, so `src/config/serverOptions.ts` and the actions find their settings in
|
|
669
|
+
`process.env` as they load. A change to it is read on the next start, and a deployment that sets its environment needs
|
|
670
|
+
no file. A browser
|
|
671
|
+
project's is Vite's: only `VITE_*` reaches the page, and ships in it.
|
|
612
672
|
`create` gives each one a signing key there, made for it: `PLITZI_SIGNING_SECRET`, what `ctx.sign` and `ctx.verify`
|
|
613
673
|
sign with — at least 32 characters (`doctor --fix` writes one where it is missing). `PORT` is left commented out: 8080,
|
|
614
674
|
or the next free port while developing.
|