@plitzi/cli 0.38.8 → 0.38.10
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 +147 -0
- package/README.md +23 -8
- package/dist/index.js +899 -297
- package/package.json +3 -3
- package/skills/plitzi-cli/SKILL.md +10 -4
- package/skills/plitzi-cli/reference/projects.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,152 @@
|
|
|
1
1
|
# @plitzi/cli
|
|
2
2
|
|
|
3
|
+
## 0.38.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 200da2f: - **`focus-on-field-box`** (`@plitzi/sdk-authoring`): a warning for a `focus` or `focus-visible` state on a text
|
|
8
|
+
field's or a select's `input` slot. That slot is the box the field is drawn in, a `<div>` that never takes focus, so
|
|
9
|
+
the rule was never seen and a keyboard user tabbing to the field found no ring. The fix it names: `'focus-within'` on
|
|
10
|
+
the same class, or the state on the `field` slot.
|
|
11
|
+
- **`modalContainer` says how it is laid out** (`@plitzi/sdk-elements`): its description now names its slots and how
|
|
12
|
+
they sit — the dim layer and the dialog side by side, not one inside the other; the dialog centred by `top`/`left`
|
|
13
|
+
50% and a `translate`. A space styled the dim layer as a flex container to place the dialog, which moved nothing.
|
|
14
|
+
- **A field shows where the keyboard is** (`@plitzi/plitzi-sdk`, `@plitzi/sdk-elements`): a text field's or a select's
|
|
15
|
+
box is ringed (`2px solid currentColor`) while the field inside has keyboard focus, and a textarea while it has. No
|
|
16
|
+
text field or select showed any focus at all: the box had `outline: none`, and the field inherited it. One class of
|
|
17
|
+
specificity, so whatever a space writes about the outline wins; never in the builder's canvas, where the selection is
|
|
18
|
+
the ring. The field no longer inherits the box's outline — the box draws it.
|
|
19
|
+
- **The dim layer of a modal and a dialog is `rgb(0 0 0 / 50%)`** (`@plitzi/plitzi-sdk`, `@plitzi/sdk-elements`), not
|
|
20
|
+
black at `opacity: 0.5`: the default looks the same, and a colour a space gives the layer is drawn as it is — it was
|
|
21
|
+
halved. A space that set its own colour sees it darker: the one it wrote.
|
|
22
|
+
- **`required-message-unused`** (`@plitzi/sdk-authoring`): a warning for a `requiredMessage` on a field nothing requires —
|
|
23
|
+
since 0.38.9 a field is optional unless `required: true`, so the message is never shown and an empty answer is sent.
|
|
24
|
+
The formControl's description, the cheat sheet and the forms recipe say the default.
|
|
25
|
+
- **A page's title can say its record** (`@plitzi/sdk-shared`, `@plitzi/sdk-server`, `@plitzi/sdk-elements`,
|
|
26
|
+
`@plitzi/sdk-authoring`): `seoTitle` and `seoDescription` may be templates over the page's `runtime: 'server'`
|
|
27
|
+
providers (its layouts' too) and `navigation` — `'{{ apiContainer_post.title }} — Blog'`. The server evaluates them
|
|
28
|
+
as it writes the head, from the answers it already has; the browser evaluates the same over `rsc.data`, so the tab
|
|
29
|
+
follows a navigation from record to record. One that reads anything else — a browser provider, `state` — is refused
|
|
30
|
+
(`page-template`): it was written into the head as it was, braces included. A declaration's `serverTemplates` names
|
|
31
|
+
the attributes the page server evaluates against a context of its own (a page's title and description, a provider's
|
|
32
|
+
`notFound`): the element runtime leaves them as written — interpolated where the page renders, a `|default(…)`
|
|
33
|
+
resolved to its fallback before the head could read the providers — and the authoring lint reads the same list.
|
|
34
|
+
- **A page says when its address shows nothing** (`@plitzi/sdk-server`, `@plitzi/sdk-authoring`): `notFound` on the
|
|
35
|
+
page, one expression over the same answers its title reads — `"{{ not (apiContainer_feed.topics|find('slug',
|
|
36
|
+
navigation.routeParams.slug)) }}"` — sends it with status 404, rendered as written. A provider's own `notFound` reads
|
|
37
|
+
only its answer, and one in a layout is every page's: a record read from the layout had no way to say it was not
|
|
38
|
+
there, and the page answered 200.
|
|
39
|
+
- **The Export keeps the flows of a plugin hosted by `custom`** (`@plitzi/sdk-authoring`): `specFromSpace` judged such
|
|
40
|
+
an element by `custom`'s own triggers and callbacks, and dropped a flow on the component's event (`onChange` on an
|
|
41
|
+
editor) as one "a custom never fires" — the space read back was not the space written.
|
|
42
|
+
- **`page check` reads every word on the page, in the colour the browser paints it** (`@plitzi/sdk-authoring`): what a
|
|
43
|
+
plugin draws inside an element of the space is measured too, named by the element and a selector; the measure is
|
|
44
|
+
WCAG's contrast (under 2:1 is unreadable), not "nearly the same colour"; and a colour the browser answers as
|
|
45
|
+
`oklch()`, `oklab()` or `color(srgb …)` — every token and every `color-mix()` — is read as that, where it was read as
|
|
46
|
+
`rgb()` numbers and came out near black. A plugin's dark-on-dark status line passed as "nothing wrong".
|
|
47
|
+
- **`verify` checks every theme the space can be painted in** (`@plitzi/cli`): light and dark, unless the space says
|
|
48
|
+
light only — "48 checks at 1440 and 390 px, light and dark". A page unreadable in the dark theme passed in the light
|
|
49
|
+
one; a failure names the theme it was found in.
|
|
50
|
+
- **`plitzi upgrade` says where fields became optional** (`@plitzi/cli`): for a project last upgraded before 0.38.9,
|
|
51
|
+
each `formControl(…)` with no `required`, at its file and line — said, never written. And a `.gitkeep` is asked for
|
|
52
|
+
only in a folder with nothing else in it: `upgrade` wrote one beside code, and `doctor` called it missing once deleted
|
|
53
|
+
as AGENTS.md asks ("nothing unused") — the three now say the same.
|
|
54
|
+
- **`devMode` and `devReload` are the project's** (`@plitzi/sdk-server`): `src/config/serverOptions.ts` may set them,
|
|
55
|
+
over `NODE_ENV`, which they still follow when left out. A deployment started without `NODE_ENV` (a container's `CMD`)
|
|
56
|
+
says `devMode: false`, and a public action answers with its output alone.
|
|
57
|
+
- **`page shot --from load`** (`@plitzi/cli`): `--frames` start as soon as the page's HTML is in, not once it settles —
|
|
58
|
+
an entrance that plays while the page loads had ended before the first picture.
|
|
59
|
+
- **`heavy-animation` says where each animation is** (`@plitzi/sdk-authoring`): the class and its variant, state or
|
|
60
|
+
slot — or the `customCss` rule — and writes the fix against that selector. It said "in `customCss`" for an animation
|
|
61
|
+
declared on a class's variant, and offered `.glow`, a class no space has.
|
|
62
|
+
- **`page shot --steps`** (`@plitzi/cli`): an interaction played step by step — `click`, `type`, `press`, `wait`,
|
|
63
|
+
`wait-for`, `shot [label]`, `frames <n> [ms]`, separated by `;` or written in a file (`@file`) — each picture labelled
|
|
64
|
+
with its step and the time since the first, and said when nothing changed since the one before. A queue filling, a
|
|
65
|
+
restart, an opening frame by frame took a Playwright script of the project's own. Targets take Playwright's selectors
|
|
66
|
+
too (`text=Saved`).
|
|
67
|
+
- **A space's task may take a `number` param** (`@plitzi/sdk-server`): saved functions refused it ("a type the builder
|
|
68
|
+
cannot draw") while a project's server ran it, so code that worked self-hosted failed on the platform — and the
|
|
69
|
+
builder draws one, a callback's. A step's params now arrive as the types the task declares, on every server: a
|
|
70
|
+
`number` written as text is the number, a `boolean` written `'true'` is `true`, as the browser reads a callback's.
|
|
71
|
+
- **`page shot --as <username>`** (`@plitzi/cli`): signs in first, as `page check --as` does, the password from
|
|
72
|
+
`PLITZI_CHECK_PASSWORD` in `.env`. A page for signed-in visitors was pictured as the sign-in page it sent the browser
|
|
73
|
+
to, without a word; `page shot` now says when the page sent it elsewhere, and that the picture is of that page.
|
|
74
|
+
- **A capture is of the page at rest** (`@plitzi/sdk-mcp`): the local screenshot client takes every picture with
|
|
75
|
+
`prefers-reduced-motion: reduce`, as the browser pod now does — the declared motion and a space's own keyframes that
|
|
76
|
+
honour the query are shown finished. A splash still covering its page, or an arrival caught halfway, was what a
|
|
77
|
+
thumbnail or a `plitzi_look` showed of a page that animates as it loads.
|
|
78
|
+
- **The server renders in the visitor's theme, not only the class** (`@plitzi/sdk-shared`): `ThemeProvider` set the
|
|
79
|
+
starting theme from a layout effect, which never runs on a server, so a page was drawn from the theme store's own
|
|
80
|
+
start — `{{ theme.resolved }}` was `light` under a `<html class="dark">`, and whatever named the scheme (a picture's
|
|
81
|
+
address, a `when` rule) was swapped for the other one as the page hydrated. The theme a host supplies (the cookie) is
|
|
82
|
+
now the server's snapshot of the store, and the hydration's; the shared store is never written on the server.
|
|
83
|
+
- Updated dependencies [200da2f]
|
|
84
|
+
- @plitzi/sdk-authoring@0.38.10
|
|
85
|
+
|
|
86
|
+
## 0.38.9
|
|
87
|
+
|
|
88
|
+
### Patch Changes
|
|
89
|
+
|
|
90
|
+
- 64f4cd6: - **`unusedPort()`** (`@plitzi/sdk-server`): a port the system has just handed out, for a test to listen on. The
|
|
91
|
+
package's own tests and `@plitzi/sdk-mcp`'s listened on fixed ports in the ephemeral range (393xx), which any
|
|
92
|
+
outgoing connection of a test running beside them could take: CI failed with `EADDRINUSE` on runs with nothing
|
|
93
|
+
wrong. Every one now listens on a port the system gives it.
|
|
94
|
+
- **Brotli at quality 5** (`@plitzi/sdk-server`): `compression.brotliQuality`, for a page rendered for one request, is
|
|
95
|
+
5 (was 2). At 2 a 220 KB page came out larger than gzip — 36 KB against 31 — and at 5 it is 29 KB, for the CPU gzip
|
|
96
|
+
spends; on half a core ~0.1 ms a page.
|
|
97
|
+
- **`verify` checks the pages for signed-in visitors** (`@plitzi/cli`): a page that sends the browser to sign in is
|
|
98
|
+
checked again signed in as the account `.env` names — `PLITZI_CHECK_USER`, `PLITZI_CHECK_PASSWORD` (the environment
|
|
99
|
+
wins over `.env`). With none named, `verify` says how. `page check --as` reads the password from `.env` too, and
|
|
100
|
+
`page check` takes several pages, in one browser.
|
|
101
|
+
- **An address that shows nothing answers 404** (`@plitzi/sdk-shared`, `@plitzi/plitzi-sdk`, `@plitzi/sdk-server`):
|
|
102
|
+
one no page answers was sent to the home page with a 302 — every typo read as the home page. A page whose slug is
|
|
103
|
+
`'*'` is now the space's page for it, sent with status 404 (a folder may have its own; the deepest wins), and a page
|
|
104
|
+
gated off by a flag shows it too. Never kept in the page cache: an address asked for at random filled it. Only a slug
|
|
105
|
+
that IS `'*'`: a page answering a subtree by its own (`spaces/:spaceId/update/*`) stays a page like any other.
|
|
106
|
+
- **`authorSpace` gives a space with no `'*'` page a plain one** (`@plitzi/sdk-authoring`), in the home page's layout,
|
|
107
|
+
and says so: suggestion `not-found-page`. The project templates carry their own.
|
|
108
|
+
- **`notFound` on a server provider** (`@plitzi/sdk-elements`, `@plitzi/sdk-server`): an expression against its answer
|
|
109
|
+
(`{{ source.found == false }}`); when it is true the page is sent with status 404, rendered as written. Refused on a
|
|
110
|
+
browser provider (`not-found-in-browser`) and when it is not one expression (`not-found-not-a-template`).
|
|
111
|
+
- **`page check` and `verify` know a page sent with 404** (`@plitzi/cli`): it is said, not failed; the space's `'*'`
|
|
112
|
+
page is checked at an address no page has, and fails if it is not sent with 404.
|
|
113
|
+
- **A form field draws no background of its own** (`@plitzi/sdk-elements`): the `<input>` inside a form control's box
|
|
114
|
+
(`field`) took `background-color: inherit`, and painted a translucent box colour a second time — a darker box inside
|
|
115
|
+
the padding (Tremor's search). It is `transparent`: the box shows through it.
|
|
116
|
+
- **`space lint` offers `quiet` only where there is an element to put it on** (`@plitzi/cli`): a suggestion about what
|
|
117
|
+
the space lacks — `not-found-page` — is answered by writing it.
|
|
118
|
+
- **`feedback --previous`** (`@plitzi/cli`): the brief says what to do when an earlier report's link no longer opens —
|
|
119
|
+
say so, and ask the person for the highest id it had.
|
|
120
|
+
- **`start:prod` runs in production by itself** (`@plitzi/cli`): `NODE_ENV=production node …`. Without the variable a
|
|
121
|
+
deployed project was a development server — dev tools on, and every public action answering its `steps` and `trace`
|
|
122
|
+
(each step's result, what the `output` was meant to leave out). `doctor` says a `start:prod` that does not
|
|
123
|
+
(`start-prod-not-production`); `plitzi upgrade --write` rewrites the script.
|
|
124
|
+
- **A project's `ActionRefusal` reaches the flow** (`@plitzi/sdk-server`): a functions bundle carries its own copy of the
|
|
125
|
+
class, so `instanceof` never knew it and the run lost its reason (`{{ x.error }}` empty). Told apart by name now.
|
|
126
|
+
- **Plugins are not remounted after hydration** (`@plitzi/sdk-elements`): the registry wrapped each plugin again when
|
|
127
|
+
the host handed it over again, a new component type every time — the server's HTML thrown away, entrances replayed,
|
|
128
|
+
effects run twice. Each plugin component is wrapped once.
|
|
129
|
+
- **`start:dev` survives a space that does not author** (`@plitzi/sdk-server`): a restart while the space had an error
|
|
130
|
+
died, and fixing the space woke nothing. It comes up answering every page with what is wrong (503), and loads the
|
|
131
|
+
space the first time a save authors.
|
|
132
|
+
- **`page check` sees what is cut off at the screen's edge** (`@plitzi/sdk-authoring`, `@plitzi/cli`): a link or words an
|
|
133
|
+
ancestor hides past the viewport, which no sideways scroll shows (`cut-off`).
|
|
134
|
+
- **`page shot --click <element...> --sheet`** (`@plitzi/cli`): elements clicked in order — a name or a CSS selector,
|
|
135
|
+
inside a plugin too — pictured after each (`--frames`/`--every`), with how much changed, and every picture on one
|
|
136
|
+
contact sheet. The dev tools' badge is no longer in a picture: its shadow root is marked (`@plitzi/sdk-dev-tools`).
|
|
137
|
+
- **`formControl` is optional unless it says `required: true`** (`@plitzi/sdk-elements`), as an HTML field is. A field
|
|
138
|
+
left without `required` in an older space was required, and is not now.
|
|
139
|
+
- **`text({ decorative })`, `list({ label })`** (`@plitzi/sdk-elements`); **`writing-mode`, `text-orientation`** in the
|
|
140
|
+
CSS vocabulary (`@plitzi/sdk-shared`).
|
|
141
|
+
- **`unused-token` reads the plugins' stylesheets** (`@plitzi/sdk-authoring`): `authorSpace`'s `stylesheets`, which
|
|
142
|
+
`projectAuthoring` fills with every `.css` under `src/plugins/` — a token only a plugin used was said to be unused.
|
|
143
|
+
- **`id-taken` on a provider placed on two pages points at the layout they share** (`@plitzi/sdk-authoring`), not at
|
|
144
|
+
`scope()`, which renamed its source and every template reading it.
|
|
145
|
+
- **The welcome template's tokens keep their names** (`@plitzi/sdk-authoring`): `satisfies`, not an annotation, so
|
|
146
|
+
`tokens(variables).card` typechecks as the cheatsheet teaches.
|
|
147
|
+
- Updated dependencies [64f4cd6]
|
|
148
|
+
- @plitzi/sdk-authoring@0.38.9
|
|
149
|
+
|
|
3
150
|
## 0.38.8
|
|
4
151
|
|
|
5
152
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -183,21 +183,28 @@ with `--source local`.
|
|
|
183
183
|
|
|
184
184
|
```bash
|
|
185
185
|
plitzi page check / --width 1440,390 # is the page whole? in text, per width; --json for a tool
|
|
186
|
+
plitzi page check /about /writers # several pages, in one browser
|
|
186
187
|
plitzi page check /products --state --element catalog-count # and what it holds: state, sources, one element
|
|
187
188
|
plitzi page check / --ssr # and what the server's HTML lacks that the hydrated page has
|
|
188
189
|
plitzi page check /enterprise --click site-footer-top # click one element: what it changed, or that nothing did
|
|
189
190
|
plitzi page check / --click news-send --fill news-email=ana@example.com # a form sent as a visitor fills it
|
|
190
|
-
|
|
191
|
+
plitzi page check /studio --as maya # a page for signed-in visitors, signed in through /auth first
|
|
191
192
|
plitzi page shot /about --width 390 --scheme dark
|
|
192
193
|
plitzi page shot / --frames 4 --every 500 # what moves: a marquee, an autoplay
|
|
194
|
+
plitzi page shot / --viewport --click .knob open-button --frames 4 --every 250 --sheet # an interaction, on one sheet
|
|
193
195
|
plitzi page shot / --compare https://example.com --width 1440 # beside another site: what differs, and how
|
|
196
|
+
plitzi page shot /studio --width 390 --as maya # a page for signed-in visitors: the picture is of it, not of the sign-in
|
|
197
|
+
plitzi page shot / --viewport --frames 6 --every 200 --from load --sheet # what plays as the page arrives
|
|
198
|
+
plitzi page shot / --clip machine --sheet --steps "click .gm__knob; wait 300; frames 6 150; wait-for .gm__capsule; shot opened" # an interaction, step by step
|
|
194
199
|
```
|
|
195
200
|
|
|
196
201
|
Both run on the project's own Playwright against its running server (`npm start`), and refuse a port that answers as
|
|
197
202
|
another project. They wait for the page to settle — loaded, then half a second with nothing asked for — counting no
|
|
198
203
|
stream that stays open, so a page with a realtime `channel` is checked like any other (`openPage` of
|
|
199
204
|
`@plitzi/sdk-authoring`, which the generated `npm run visual` uses too). `page check` reports every element the space owes the page that is missing or hidden (with why), broken
|
|
200
|
-
images, sideways scroll,
|
|
205
|
+
images, sideways scroll, a link or words cut off at the screen's edge (an ancestor hiding them, nothing scrolling to
|
|
206
|
+
them), words that cannot be told from what is behind them (under 2:1 — the space's elements and what a plugin draws
|
|
207
|
+
inside one; `aria-hidden` words are a decoration), console errors, refused requests and failed flows — and the
|
|
201
208
|
page's data: a binding that reads a path its provider's answer lacks (with the keys it has) — none inside an element
|
|
202
209
|
the page is not showing, which is not mounted — a provider that failed, and each list's rows, drawn and in its source
|
|
203
210
|
(`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.
|
|
@@ -317,11 +324,15 @@ An element's own selector and its bindings are named after its place under its n
|
|
|
317
324
|
among its siblings — so a move renames nothing.
|
|
318
325
|
|
|
319
326
|
`verify` runs each check the project has a script for, as its package manager runs one, then opens every page with
|
|
320
|
-
no parameter in its path at 1440 and 390 px
|
|
327
|
+
no parameter in its path at 1440 and 390 px, in every theme the space can be painted in — light and dark, unless
|
|
328
|
+
it says light only — (the server must be up: `npm start`). Only what fails is printed, with the
|
|
321
329
|
last lines it said, and the first failure ends the run — one broken file fails every step after it the same way — the
|
|
322
|
-
rest said as not run until it passes (`--keep-going` runs them anyway)
|
|
323
|
-
|
|
324
|
-
|
|
330
|
+
rest said as not run until it passes (`--keep-going` runs them anyway). A page the browser was sent away from — one
|
|
331
|
+
for signed-in visitors — is checked again signed in as the project's account, when `.env` names one:
|
|
332
|
+
`PLITZI_CHECK_USER` and `PLITZI_CHECK_PASSWORD`, the password `page check --as` and `page shot --as` read too (the environment wins over
|
|
333
|
+
`.env`, as it does for the project's scripts; never on the command line, which a shell keeps). One that even that
|
|
334
|
+
account is sent away from, or with no account named, is said as not checked, never as passing — on its own line, with
|
|
335
|
+
what checks it, without failing the run. Exit 1 when anything failed.
|
|
325
336
|
|
|
326
337
|
## `space lint`
|
|
327
338
|
|
|
@@ -507,7 +518,9 @@ plitzi upgrade --write --take plitzi/author.ts
|
|
|
507
518
|
A project brought up to the CLI it has now, part by part: `files` (the machinery — `author.ts`, `main.ts`, the
|
|
508
519
|
Playwright and lint configs, `AGENTS.md`), `packages` (`package.json` merged, `@plitzi/*` raised to this version, then
|
|
509
520
|
the install), `skills` (`.claude/skills/plitzi-*`, whole, so a reference a skill no longer has goes with it) and
|
|
510
|
-
`renames` (a name a version renamed, at its file and line
|
|
521
|
+
`renames` (a name a version renamed, at its file and line — and, for a project last upgraded before a change it may
|
|
522
|
+
count on, where that change lands: a `formControl` with no `required`, optional since 0.38.9; said, never written). A
|
|
523
|
+
`.gitkeep` is written only in a folder with nothing else in it. A file nobody changed since the CLI wrote it is replaced;
|
|
511
524
|
one the project made its own is a diff, left unless `--take` names it (`all` for every one). The generated
|
|
512
525
|
`.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
|
|
513
526
|
that the machinery reads (`src/config/serverOptions.ts`, `src/actions/index.ts`) is written when the project has none and the
|
|
@@ -773,7 +786,9 @@ for a clone to copy and fill in. A server project's `.env` is read as each scrip
|
|
|
773
786
|
`node --import @plitzi/sdk-server/env` (Node's flag there has its watcher restart on every write in the project) —
|
|
774
787
|
before any of its modules is evaluated, so `src/config/serverOptions.ts` and the actions find their settings in
|
|
775
788
|
`process.env` as they load. A change to it is read on the next start, and a deployment that sets its environment needs
|
|
776
|
-
no file.
|
|
789
|
+
no file. `start:prod` also sets `NODE_ENV=production` itself — without it a deployed server is a development one, its
|
|
790
|
+
dev tools on and every action's trace in what a visitor is answered (`doctor` says a `start:prod` that does not). A
|
|
791
|
+
deployment started some other way says `devMode: false` in `src/config/serverOptions.ts`, which wins over `NODE_ENV`. A browser
|
|
777
792
|
project's is Vite's: only `VITE_*` reaches the page, and ships in it.
|
|
778
793
|
`create` gives each one a signing key there, made for it: `PLITZI_SIGNING_SECRET`, what `ctx.sign` and `ctx.verify`
|
|
779
794
|
sign with — at least 32 characters (`doctor --fix` writes one where it is missing). `PORT` is left commented out: 8080,
|