@plitzi/cli 0.38.10 → 0.38.12
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 +285 -0
- package/README.md +21 -12
- package/dist/index.js +3484 -4031
- package/package.json +3 -3
- package/skills/plitzi-cli/reference/functions.md +11 -2
- package/skills/plitzi-cli/reference/plugins.md +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,290 @@
|
|
|
1
1
|
# @plitzi/cli
|
|
2
2
|
|
|
3
|
+
## 0.38.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1301338: ## Builder
|
|
8
|
+
|
|
9
|
+
- **Icons in the canvas again** (`@plitzi/plitzi-builder`): the canvas inlined the SDK's Font Awesome sheet into its
|
|
10
|
+
`<style>`, where the sheet's `url(webfonts/…)` resolved against the editor's URL — a `srcdoc` frame takes it as its
|
|
11
|
+
base — so every icon was a 404 under `/spaces/<space>/webfonts/` and drew as an empty box. Only the Vite dev server,
|
|
12
|
+
which rewrites the URL, hid it. The canvas and the element preview now link the sheet from where the host serves it:
|
|
13
|
+
a new prop, `sdkIconsStylePath`, the one the host already gives the pages it renders
|
|
14
|
+
(`/sdk-assets/plitzi-sdk-icons.css` for sdk-server). Absent, the canvas links no icon sheet.
|
|
15
|
+
|
|
16
|
+
## Plugins
|
|
17
|
+
- **A plugin's other elements, hosted by `custom`** (`@plitzi/sdk-elements`): `custom({ renderType: 'jamDisc' })` on a
|
|
18
|
+
space with a plugin installed whose main element is another (`plitzi plugin pack` of several folders: the first is the
|
|
19
|
+
plugin, the rest go in it) rendered "Custom Component jamDisc Not Found" — the page registers only the plugin's main
|
|
20
|
+
element, and a `custom` host looked nowhere else. It now loads the type from the installed plugin that packs it, as
|
|
21
|
+
an element of the type itself always did, so the two ways the docs give to place a plugin's element are the same
|
|
22
|
+
everywhere: in a project `plitzi create` wrote, and once the project is on Plitzi.
|
|
23
|
+
- **One way to place a plugin's element** (`@plitzi/sdk-authoring`, `@plitzi/cli`, docs): from its declaration,
|
|
24
|
+
`const seatPicker = defineElement(declaration)` then `seatPicker({ id, … })` — typed by what it
|
|
25
|
+
declares, and the element the builder adds when somebody drops it. The welcome space `plitzi create` writes, the
|
|
26
|
+
plugin package's preview, `plitzi plugin add` and `plitzi explain` all write it so (the template's
|
|
27
|
+
`PluginHostOptions` now takes the plugin's `type` and `declaration: { from, attributes? }`; `custom`/`element` hosting
|
|
28
|
+
is gone). `pluginFolders(folder)` (`@plitzi/sdk-authoring/node`) reads each plugin with the folder it is in;
|
|
29
|
+
`pluginDeclarations` is built on it. A `custom({ renderType })` naming a plugin the space was handed the declaration
|
|
30
|
+
of is offered the declaration instead — suggestion `plugin-custom-host`. `custom` stays for a component registered
|
|
31
|
+
by name with no declaration. The skills, the CLI README, the MCP guide, `docs/en` and the website say the same.
|
|
32
|
+
- **`definePlugin`** (`@plitzi/sdk-authoring/plugin`, a new entry of 3 KB with nothing else in it): a plugin's
|
|
33
|
+
declaration written from what only it can say —
|
|
34
|
+
`definePlugin<SeatPickerAttributes>()({ type, label, attributes, triggers, callbacks })` — and every other field
|
|
35
|
+
at the default all plugins share (the builder's gestures, the catalogue entry, each attribute bindable, an empty
|
|
36
|
+
style). It answers the whole declaration, branded with its attributes, so `defineElement(declaration)` is typed
|
|
37
|
+
without a generic. `plitzi plugin add` and `create --plugin` write declarations with it (about a third of the lines).
|
|
38
|
+
- **`usePluginTrigger(declaration)`** (`@plitzi/plitzi-sdk`): fires a plugin's declared event on its element — the
|
|
39
|
+
event name and what each hands a flow typed off the declaration's `preview` — on a live page only. The hook every
|
|
40
|
+
plugin wrote for itself (and `plugin add` generated as `use<Name>Events`) is gone from the scaffold.
|
|
41
|
+
- **Attributes as the types their defaults are** (`@plitzi/sdk-elements`): a plugin's attribute bound from text — a
|
|
42
|
+
state, a row, a channel message — reaches its component as the number or the flag its declared default is (`'112'`
|
|
43
|
+
as 112, `'true'` as true). A plugin no longer types its props `number | string` and parses them.
|
|
44
|
+
|
|
45
|
+
## Server actions and functions
|
|
46
|
+
- **Task params with rules** (`@plitzi/sdk-server`, `@plitzi/sdk-shared`): a task declares `required`, a text's
|
|
47
|
+
`maxLength` and a number's `min`/`max`, and the runner refuses a call that breaks any of them — every rule broken at
|
|
48
|
+
once, in the words the page shows (`Title is required; Seconds is at most 300`) — before the code runs. A `text` param
|
|
49
|
+
bound to a number arrives as its digits. The manifest keeps the rules, so the platform's sandbox checks the same.
|
|
50
|
+
- **`taskAction(task, { trigger })`** (`@plitzi/sdk-authoring`): the action that runs one of the space's tasks and
|
|
51
|
+
answers its result, derived from the task — its id (`<namespace>-<action>`), name, description and input (the task's
|
|
52
|
+
params, once). An action of more than one step is still `defineAction`.
|
|
53
|
+
- **`ctx.rateLimit(bucket, { …, refuse })`**: past the limit the call is refused with those words instead of answering
|
|
54
|
+
`allowed: false` for the code to check — natively and in the sandbox.
|
|
55
|
+
|
|
56
|
+
## Authoring
|
|
57
|
+
- **`runServerActionOrNotify(id, params, fallback)`**: a server action run and the notice the visitor reads when it
|
|
58
|
+
fails — the action's own refusal, or the fallback — as two steps to spread into a flow.
|
|
59
|
+
- **`repeated-shape` reads what copies bind**: copies whose bindings read their data in different forms (a count, a
|
|
60
|
+
total of a quota) and copies holding a provider resolved on the server (found by its own id) are no longer offered
|
|
61
|
+
as one component.
|
|
62
|
+
- **`element-color-inherited`** (suggestion): `elements` giving a heading, a text, a link… `color: inherit` or the
|
|
63
|
+
page's own colour. **A link inherits the page's colour** (`@plitzi/plitzi-sdk`, `@plitzi/sdk-elements`) rather than
|
|
64
|
+
holding the SDK's grey — the same by default, and the space's palette inside a card that is a link. The template
|
|
65
|
+
every space starts from writes its colours once, on the page.
|
|
66
|
+
|
|
67
|
+
## Fixes
|
|
68
|
+
- **A dialog opened with an id** (`@plitzi/sdk-elements`): `openDialog('dialog', '{{ row.id }}')` reads the id as its
|
|
69
|
+
`content`, as `openModal` already did — a numeric id parsed as the number and the dialog's bindings read nothing.
|
|
70
|
+
- **A select's chevron** (`@plitzi/plitzi-sdk`): a drawn chevron in the field's own colour, sized by its type, in place
|
|
71
|
+
of the `▼` glyph — and laid out in the box, so it ends where the box's padding begins whatever that padding is, and
|
|
72
|
+
the chosen option stops short of it instead of running under it. A disabled select's is faded.
|
|
73
|
+
- **Every element has its settings** (`@plitzi/plitzi-builder`, `@plitzi/sdk-elements`): the builder found none for
|
|
74
|
+
`tabContainerHeader` (registered under a misspelt type), `themeToggle`, `dropdownPopup`, `loading` and `notFound`.
|
|
75
|
+
The theme toggle's panel sets its mode, its labels and whether it offers "System"; the registry is typed by element
|
|
76
|
+
type and must hold one for each.
|
|
77
|
+
- **A plugin's panel** (`@plitzi/cli`): `plitzi doctor` warns of a plugin with no `Settings.tsx`, or one its entry never
|
|
78
|
+
passes as `pluginSettings` (`plugin-settings-missing`); the example `create` writes has its panel, as every element
|
|
79
|
+
`plugin add` writes does, and the panels it generates are laid out as the project's Prettier lays them out.
|
|
80
|
+
- **A refused or failed run reaches `onFlowError` in every mode** (`@plitzi/sdk-interactions`): an awaited server
|
|
81
|
+
action the server refused fired no `onFlowError` on the element that started it, as `detached` and `stream` ones do
|
|
82
|
+
— a board rolling its edits back on a refusal never did; and a run answered `status: 'failed'` fired `onFlowEnd`
|
|
83
|
+
(detached) or nothing (awaited) rather than `onFlowError`.
|
|
84
|
+
- **A source renamed** (`@plitzi/sdk-shared`): the binding picker lists a provider, a form or a modal by the name its
|
|
85
|
+
element has now, not the one it had when it mounted.
|
|
86
|
+
- **A text's words in the builder** (`@plitzi/sdk-elements`): a `paragraph`, `text` or `heading` whose `content` is
|
|
87
|
+
`0` shows `0` while editing too, not its placeholder; one bound to nothing shows nothing rather than `null`.
|
|
88
|
+
- **Built-in declarations** (`@plitzi/sdk-shared`): `elementDeclaration` fills in what every element shares — the
|
|
89
|
+
builder's gestures, Plitzi's catalogue entry, a visible element with no bindings, its style named by its label —
|
|
90
|
+
from the defaults `definePlugin` uses; each element's declaration says only what is its own (a third of the lines).
|
|
91
|
+
|
|
92
|
+
## Typed for plugins and hosts
|
|
93
|
+
- **`usePlitzi()` and `PlitziProvider`** (`@plitzi/sdk-shared/hooks/usePlitzi`, `@plitzi/plitzi-sdk`): what were
|
|
94
|
+
`usePlitziServiceContext()` and `PlitziServiceProvider` (and `PlitziServiceContextValue`, now `PlitziContextValue`),
|
|
95
|
+
holding only what the host rendering a space knows — `settings`, `root`, `utils`. Its `contexts` and
|
|
96
|
+
`customContexts` are gone: every context it carried is a shared one already, imported from its own module
|
|
97
|
+
(`@plitzi/sdk-interactions/InteractionsContext`, `@plitzi/sdk-shared/network/NetworkContext`…), and
|
|
98
|
+
`PluginsContext` moves to `@plitzi/sdk-shared/plugins/PluginsContext` beside the others.
|
|
99
|
+
- **`InteractionsManagerApi`** (`@plitzi/sdk-shared`): the interactions manager as everything outside
|
|
100
|
+
`@plitzi/sdk-interactions` reaches it, declared where every package can name it and implemented by
|
|
101
|
+
`InteractionsManager`, so `use(InteractionsContext)` is typed — `interactionTrigger`, `createChildManager`… — where it
|
|
102
|
+
was `any`.
|
|
103
|
+
- **`getPathsFromObject`** (`@plitzi/sdk-shared/helpers/utils`), spelt right; `getPathsFromObeject` is gone.
|
|
104
|
+
- **`ElementWords` places itself** (`@plitzi/sdk-elements`): `contentPlacement` and the element's children, so a button
|
|
105
|
+
and a link write their words once.
|
|
106
|
+
|
|
107
|
+
- Updated dependencies [1301338]
|
|
108
|
+
- @plitzi/sdk-authoring@0.38.12
|
|
109
|
+
|
|
110
|
+
## 0.38.11
|
|
111
|
+
|
|
112
|
+
### Patch Changes
|
|
113
|
+
|
|
114
|
+
- cadf70a: - **`server.cache.invalidate` drops what a page is rendered from** (`@plitzi/sdk-server`): the pages, the RSC answers
|
|
115
|
+
and the schema data they are rendered from go together. It dropped the pages alone, and the next request rendered
|
|
116
|
+
the same page again from the schema still cached under the same key — a publish that invalidated the space changed
|
|
117
|
+
nothing until the schema's TTL ran out. `clear()` and `size` cover the three. A filter on `hostname` drops the schema
|
|
118
|
+
data too, which belongs to no one host. `server.cache` is `null` only when nothing is cached (`cacheTtlMs: 0` and
|
|
119
|
+
`rsc.cacheTtlMs: 0`).
|
|
120
|
+
|
|
121
|
+
## Style inspector
|
|
122
|
+
- **Finds a property** (`@plitzi/sdk-style`): a search above the categories narrows them to the ones that edit what was
|
|
123
|
+
typed — a CSS name in any order of its words (`border radius` finds the four corners), a category's title, or a
|
|
124
|
+
common word for it (`bg`, `rounded`) — opens them, and shows the advanced rows when the match lives there. Escape
|
|
125
|
+
clears it. The categories' properties live in one list (`categoryKeys.ts`) that the dots, the advanced hint and the
|
|
126
|
+
search all read.
|
|
127
|
+
- **Rows that fit**: a section with more than two controls puts its label above them and lays them out in as many
|
|
128
|
+
columns as the panel is wide, instead of one row where every label was cut (`Appearan…`, `Cell Spaci…`, the five
|
|
129
|
+
scroll-snap controls). A row's label column is 80px.
|
|
130
|
+
- **Where a value comes from, said quietly**: the label's tint keeps its four meanings — set here, from a token, bound
|
|
131
|
+
to data, inherited — without the solid blocks of colour; hovering says which (an inherited one names its selector and
|
|
132
|
+
breakpoint) and that a click resets it, the click shows it by striking the label through. The footer's info icon
|
|
133
|
+
holds the legend, and its arrow folds every category.
|
|
134
|
+
- **What is being edited**: an "Editing … › Hover" line under the pickers whenever the rules being written are not the
|
|
135
|
+
selector's plain ones, with a button back to them. Ancestor, pseudo-element and condition fold behind a toggle —
|
|
136
|
+
never while one is in use.
|
|
137
|
+
- The class being edited is the panel's one strong mark (violet), the element's type defaults a softer one; the tools'
|
|
138
|
+
tabs fit the panel and are reachable from the keyboard.
|
|
139
|
+
|
|
140
|
+
- **Lists edited in a popover, all alike**: box and text shadows, transforms, transitions and filters share one row
|
|
141
|
+
(the CSS it writes, a swatch, a remove button) and one popover (a title, a close button, Escape, the focus moved
|
|
142
|
+
into it). What none of them could read is now kept and edited as text instead of being replaced with a default — a
|
|
143
|
+
token for the whole value, `drop-shadow(…)`, `url(#…)`.
|
|
144
|
+
- **Values read the way CSS writes them**: a shadow with two, three or four lengths and its color on either end;
|
|
145
|
+
`rgba(…)` inside text shadows and filters no longer split; negative shadow offsets accepted; a transition with any
|
|
146
|
+
of its parts left out; brightness, contrast and saturation past 1. Transition presets are written as CSS — the
|
|
147
|
+
preset names (`easeInQuad`) made the browser drop the whole declaration — the curve can be dragged into one of your
|
|
148
|
+
own, and the preview stops with the editor. `font-color` (not CSS) became `color`.
|
|
149
|
+
- **Background layers keep what they hold**: a repeating gradient (now a switch), a radial gradient's explicit size, a
|
|
150
|
+
token or `image-set()` as a layer (a "Custom (CSS)" layer), a one-value position read as CSS reads it (`20%` is
|
|
151
|
+
`20% center`), lists shorter than the layers repeated as CSS repeats them, an unset repeat read as tiling, two-position
|
|
152
|
+
stops, negative angles — every one of them was rewritten on the next edit of any layer. Defaults are no longer
|
|
153
|
+
written back, and "Token values" no longer bakes resolved tokens into the layers.
|
|
154
|
+
- **A layer's editor in two halves** — what it draws, then where it goes (size, position, tile, attachment, clip,
|
|
155
|
+
which now offers `text`). The gradient's stops sit on one bar, each a handle that drags or moves with the arrow keys;
|
|
156
|
+
the stop's color and position below it. Previews and swatches resolve the space's tokens.
|
|
157
|
+
- Spacing tells margin (dashed, outside) from padding; Border's sides are labelled and readable in the dark theme; a
|
|
158
|
+
class's menu says what each action does to whom; the Style Manager opens at a size that holds both columns.
|
|
159
|
+
|
|
160
|
+
## Builder
|
|
161
|
+
- **Shortcuts**: `?` shows every shortcut the builder answers to — the same list the "Nothing selected" card teaches
|
|
162
|
+
from — and ⌘\ / Ctrl+\ hides both side panels for the canvas alone and brings back the ones that were open. Both
|
|
163
|
+
work with the canvas focused.
|
|
164
|
+
- **Panels keep their width**: each side panel opens at the width it was left at; the right one starts at 380px.
|
|
165
|
+
- **Text no smaller than 11px** across the builder's panels (it went down to 10px in fifty places).
|
|
166
|
+
|
|
167
|
+
## Realtime
|
|
168
|
+
- **A page hears what it sent when it asks to** (`@plitzi/sdk-shared`, `@plitzi/sdk-server`, `@plitzi/sdk-elements`):
|
|
169
|
+
`publishOn('room', 'react', data, { echo: true })`, `useChannel().publish(type, data, { echo: true })` and the
|
|
170
|
+
channel's `publish` callback (`echo`) hand the message back to the page that sent it too, once the server took it —
|
|
171
|
+
stamped like everyone's, with `echo: true`, its `from` the channel's `me`. Without it a page still never hears its
|
|
172
|
+
own messages, and the docs said "every page on its topic hears it": they now say every OTHER page. Presence never
|
|
173
|
+
echoes.
|
|
174
|
+
- **A topic is opened only once it names one** (`@plitzi/sdk-elements`): `useChannel` — and so the `channel` element —
|
|
175
|
+
opens a topic only when a channel of the space covers it, by the same `matchChannel` the server decides by. A topic
|
|
176
|
+
written from data that has not arrived (`room:` while its provider loads, or its template still as text) asked the
|
|
177
|
+
server for both, was refused with a 403 and a console error on every load, and is now waited for.
|
|
178
|
+
- **Pages that watch** (`@plitzi/sdk-server`, `@plitzi/cli`): a connection whose page carries the `plitzi-observer`
|
|
179
|
+
cookie hears its topics and says nothing on them — no `$join`, no presence, its publishes taken and dropped.
|
|
180
|
+
`page check`, `page shot` and `verify` load pages that way, so checking a live site is no longer a visitor walking
|
|
181
|
+
into a room (`X walked in`, a member more in every picture). `--presence` takes part as a visitor does.
|
|
182
|
+
|
|
183
|
+
## Authoring
|
|
184
|
+
- **`template-in-value`** (refused): a `{{ }}` inside an attribute that is an object or a list — a provider's
|
|
185
|
+
`input`, a list's `items`, a plugin's settings — is never evaluated: only an attribute that is text is interpolated,
|
|
186
|
+
and the page server reads attributes as saved. A provider's `input` also replaced the route param of the same name
|
|
187
|
+
the action was already given, so `input: { room: '{{ navigation.routeParams.room }}' }` reached the task as `""` and
|
|
188
|
+
the page answered 404; its refusal says the action is handed the page's route and query params already. Anything
|
|
189
|
+
else is a binding on the attribute. `mockData`, a sample, is not held to it.
|
|
190
|
+
- **Rules on top of a class need no `id`** (`class: [card, { gap: '6px' }]`): they are named after the id the element
|
|
191
|
+
is given, written or not. `modifier-without-id` is gone; a one-off tweak no longer needs a name nothing reads.
|
|
192
|
+
- **Typed list rows have `inTemplate`**, as untyped ones do, and `bindTemplate`, `visibleWhen`, `hiddenWhen` and
|
|
193
|
+
`variantFrom` take a typed source's path as well as a name: turning a list typed broke every template of its rows.
|
|
194
|
+
- **`when({ field, operator: 'empty' })`** takes no `value` (nor `notEmpty`), as flows.md recommends; it did not
|
|
195
|
+
type-check.
|
|
196
|
+
- **Data-driven colours**: a style binding on a custom property (`{ to: '--who', category: 'style' }`) is written as
|
|
197
|
+
named — it was camel-cased into `who` — so a class reads `var(--who, var(--muted))`. A style binding's value carrying
|
|
198
|
+
`;` or braces is not written: the page server writes inline styles as text, and such a value added declarations of
|
|
199
|
+
its own. `binding-target-unknown` on `style` or a CSS property says to bind it in the `style` category.
|
|
200
|
+
- `unknown-attribute` for `decorative` on an `svg` or a `fontAwesome` says what it means: without a `label` it is
|
|
201
|
+
already hidden from screen readers.
|
|
202
|
+
|
|
203
|
+
- **A folder nobody declared says where to declare it**: `folder-undeclared` (a page, a layout, a folder's parent)
|
|
204
|
+
ends with `pageFolders: [{ id, name }]` on the space, and with the line of the `pageFamily` that wrote the page. A
|
|
205
|
+
folder starts its pages' addresses (`/docs/quickstart`), so a misspelt one is never declared on the author's behalf.
|
|
206
|
+
The skill's `pageFamily` example declares its folder.
|
|
207
|
+
- **A tag is an element**: a `subType` this element has not but another has — `container({ subType: 'ol' })` — names
|
|
208
|
+
that element (`list({ subType: 'ol' })`) instead of the value two letters away (`dl`). Read off the elements'
|
|
209
|
+
declarations, for every element and tag.
|
|
210
|
+
- **A `pageFamily`'s body is written once**: `repeated-shape` and `repeated-on-pages` no longer count the same part of
|
|
211
|
+
each page of one family as copies — they were offering a component for exactly what the docs recommend. Copies within
|
|
212
|
+
one page, or across pages written one by one, are still offered.
|
|
213
|
+
- **Colour emoji are not text to `page check`**: a character painted in its own colours (🎲, `❤️`, a keycap, a ZWJ
|
|
214
|
+
sequence) is left out of the contrast measure, which compared `color` with the tile behind it and failed `verify`
|
|
215
|
+
in the theme whose text colour was close to the tile. A symbol drawn as text (✓, ★) is still measured.
|
|
216
|
+
|
|
217
|
+
- **`declared-callback-target`** (refused): a value beside `on` in `declaredCallback(…, { on, date })` — written as
|
|
218
|
+
`openModal`'s target reads — was read nowhere, and the step ran without it. Refused, with the `params` it goes in
|
|
219
|
+
(`{ on: 'calendar', params: { date } }`) and whether it is one of the callback's declared params.
|
|
220
|
+
- The skill's list rows show the typed form beside the untyped one: with `items` typed by a sample, `r.item` is a path
|
|
221
|
+
(`from: r.item.title`), not text to put in a template string.
|
|
222
|
+
- **`slot-not-class`** (refused): rules written in place in a slot — `slots: { error: [fieldError, { color }] }`, past
|
|
223
|
+
the type in JavaScript or a spec rebuilt from JSON — were taken for a declaration with no rules, and `authorSpace`
|
|
224
|
+
failed later with `Cannot read properties of undefined (reading 'desktop')`, naming nothing. Refused where the slot
|
|
225
|
+
is written, naming the slot and the element, with the `styles()` declaration to hand instead.
|
|
226
|
+
|
|
227
|
+
## CLI
|
|
228
|
+
- **`page shot --click` (and `--clip`, `--wait-for`, `--scroll-to`, `--steps`) takes any selector**: a value that is
|
|
229
|
+
not an element's name (letters, digits, `-`, `_`) is a selector, CSS or Playwright's own (`button:has-text("Orbit")`).
|
|
230
|
+
It was wrapped as a name, and an invalid selector ended the command with Playwright's stack trace; it is now refused
|
|
231
|
+
with the reason.
|
|
232
|
+
|
|
233
|
+
- **`plitzi functions add <package>`**: a package the functions use comes with them, as a function carries its
|
|
234
|
+
dependencies. Installed in the project, it is bundled (web APIs only, minified, its licence kept) into
|
|
235
|
+
`src/functions/vendor/<package>.js`, with a `.d.ts` re-exporting the installed package's types, imported as
|
|
236
|
+
`./vendor/<package>.js` and pushed, built and run with the rest — nothing is resolved anywhere else, so the builder,
|
|
237
|
+
the sandbox and the push are unchanged. A package that reaches Node (`fs`, `node:*`) is refused, naming what it
|
|
238
|
+
reached; one past the functions' 1 MB is too; one that reads `process`/`Buffer` is warned about. The build's refusal
|
|
239
|
+
of a package import now names the command.
|
|
240
|
+
- **`page shot` targets**: a bare word is an element's name, or — no element named so — a tag (`textarea`); resolved on
|
|
241
|
+
the loaded page for `--click`, `--clip`, `--scroll-to`, `--wait-for` and `--steps`. In `--steps`, `type` takes a
|
|
242
|
+
quoted element with spaces (`type ".panel textarea" hola`) — it was cut at its first space and typed the rest — and
|
|
243
|
+
fails when the click leaves no field focused, rather than sending the keys to the page's shortcuts.
|
|
244
|
+
|
|
245
|
+
## Server
|
|
246
|
+
- **`server.listen()` resolves once the port answers** (`@plitzi/sdk-server`) — in a fleet, once the first worker
|
|
247
|
+
does. `serveProject` writes `tmp/dev-server.json` and says `pages on …` after it, not on the line after `listen`:
|
|
248
|
+
for about 0.4 s a tool trusting the line (CI, Playwright's `webServer`, `page check`) was refused. A port it cannot
|
|
249
|
+
take still ends the process, or goes to `onListenError`, and the promise is then never resolved.
|
|
250
|
+
- **Runs set for later** (`@plitzi/sdk-server`, `@plitzi/sdk-shared`, `@plitzi/sdk-authoring`, `@plitzi/plitzi-builder`):
|
|
251
|
+
a turn that runs out, a bot's move, a hold that lapses — one run starting one of the space's actions in N seconds,
|
|
252
|
+
whether or not a page is still open. The action says it may be with a **`later` trigger** (no access rule: the run
|
|
253
|
+
that set it was let in); a flow sets it with `flow.later { action, in, input, key }`, a function with
|
|
254
|
+
`ctx.later({ … })`, and `flow.cancelLater` / `ctx.cancelLater(key)` drops it. A `key` names it: set again under the
|
|
255
|
+
same key, the one still waiting is replaced — the newer of two set at once, on every replica — and a running one is
|
|
256
|
+
left. It is a job of the queue schedules use: due by the store's clock (0 s to 30 days, about a second late at most),
|
|
257
|
+
once across replicas, retried, shown in Automations → Queue. Refused before anything is queued, with why: no `later`
|
|
258
|
+
trigger, one switched off, a time out of range, a key that is not one, a server with no jobs. A plugin's functions
|
|
259
|
+
set none. `ActionJobQueue` gains `cancelPending({ spaceId, key, olderThan? })` and jobs a `key`: the memory, Mongo
|
|
260
|
+
and MySQL queues implement it, and the shared contract tests it. **MySQL**: `action_jobs` gains `job_key` (and the
|
|
261
|
+
`action_jobs_key` index), added on first use; with `createTables: false`, run that statement of
|
|
262
|
+
`mysqlJobSchemaUpgrades()`. A queue of a deployment's own implements `cancelPending` (`09-schedules` shows one).
|
|
263
|
+
- **A project's `kv` file has one holder** (`@plitzi/sdk-server`): `createFileKv` takes `<file>.lock` with its pid;
|
|
264
|
+
a second process — another `npm start`, a `--watch` left running — is refused, naming the first (`the server of
|
|
265
|
+
"orbita", on port 8080`) instead of both writing their whole map over each other's changes, and a lock whose process
|
|
266
|
+
is gone is taken over. `close()` writes what is pending and lets go. A server with `workers` opens the file once, in
|
|
267
|
+
the primary, and its workers reach it through the fleet (`fleetKv`): each used to open a copy of its own.
|
|
268
|
+
- **A self-hosted project's credentials** (`@plitzi/sdk-server`, `@plitzi/cli`): `serveProject` answers
|
|
269
|
+
`getCredential` from `PLITZI_CREDENTIALS` in `.env` — one JSON object, credential id → its keys — so
|
|
270
|
+
`ctx.fetch({ credential })`, a connector and an `http.request` step work on the project's own server, not only in
|
|
271
|
+
`functions dev`. The same variable for both (it was `PLITZI_FUNCTIONS_CREDENTIALS`, read by the CLI alone); a value
|
|
272
|
+
that is not that object is refused with how to write it, instead of every credential going missing.
|
|
273
|
+
- **`HOST` beyond loopback says where to open it**: with `HOST=0.0.0.0`, `serveProject` prints the machine's network
|
|
274
|
+
addresses — what a tablet on the same Wi-Fi opens — and that anyone on that network can. `.env.example` names `HOST`
|
|
275
|
+
and `PLITZI_CREDENTIALS`.
|
|
276
|
+
|
|
277
|
+
## SDK
|
|
278
|
+
- **`useElementSize(ref)`** (`@plitzi/plitzi-sdk`): the size a plugin's own box is drawn at, followed as it changes —
|
|
279
|
+
what `useDisplayMode()` cannot say: a tablet held upright is `mobile` by the window and still a week wide by the
|
|
280
|
+
plugin's box. `undefined` until measured, so the server's page and the hydrated one agree. The breakpoints are
|
|
281
|
+
unchanged.
|
|
282
|
+
- The functions docs say how a task's `params` types (how the builder edits them: `codemirror-json`) and an action's
|
|
283
|
+
`input` types (what the value is: `json`) correspond.
|
|
284
|
+
|
|
285
|
+
- Updated dependencies [cadf70a]
|
|
286
|
+
- @plitzi/sdk-authoring@0.38.11
|
|
287
|
+
|
|
3
288
|
## 0.38.10
|
|
4
289
|
|
|
5
290
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ npx @plitzi/cli plugin upload # that zip, on the space you work
|
|
|
22
22
|
several separated by commas), `--api` for the platform, `--json` for a tool or an agent.
|
|
23
23
|
- **`--dry-run` says what it would do, and does none of it** — on every command that writes or sends: `create`,
|
|
24
24
|
`plugin add`, `runtime add`, `space pull`, `space push`, `plugin pack`, `source pack`, `page import`, `plugin upload`, `functions pull`/
|
|
25
|
-
`functions push`, `runtime push`/`start`/`stop`/`size`/`vars`, `skills update`, `doctor --fix`. Each file it would write (`+` new, `~` replaced, `-`
|
|
25
|
+
`functions push`/`functions add`, `runtime push`/`start`/`stop`/`size`/`vars`, `skills update`, `doctor --fix`. Each file it would write (`+` new, `~` replaced, `-`
|
|
26
26
|
removed), what it would install or run, what it would send and where. It still reads what it needs to say so — the
|
|
27
27
|
project, the files it would send, the space it would pull, signing in for that. `upgrade` and `space fix` only show until
|
|
28
28
|
`--write`.
|
|
@@ -160,7 +160,8 @@ with its fix). A plugin is declared by its folder: the server, `author` and `pag
|
|
|
160
160
|
`src/plugins/<Name>/declaration.ts` (`pluginDeclarations` from `@plitzi/sdk-authoring/node`). What the server does
|
|
161
161
|
besides serving the space is the project's own, in files it reads: `src/config/serverOptions.ts` (handed to `serveProject` —
|
|
162
162
|
`images`, `action.limits`, `action.kv`, `rsc`) and, with `--source local`, `src/actions/index.ts` (the space's server
|
|
163
|
-
actions, one `defineAction` each, a file each as they
|
|
163
|
+
actions, one `defineAction` each — `taskAction(task, { trigger })` for one that only runs a task — a file each as they
|
|
164
|
+
grow).
|
|
164
165
|
What `serveProject` wires itself — where the space comes from, the plugins, `public/`, `src/data/`, `src/functions/`,
|
|
165
166
|
the actions' lookups — is left out of `serverOptions`' type (`ProjectServerOptions`), and comes after it, so an option
|
|
166
167
|
there can never unwire it.
|
|
@@ -237,6 +238,12 @@ default, and `page shot` names the file by the theme it was painted in. The dev
|
|
|
237
238
|
full-page `page shot` is the whole page — the pane the SDK scrolls in unrolled, every lazy picture loaded, every arrival
|
|
238
239
|
waiting for the scroll shown as it ends — in `tmp/shots/` unless `--out` says where.
|
|
239
240
|
|
|
241
|
+
Both load a page as one that watches its realtime channels: it hears them — a topic the server refuses is still
|
|
242
|
+
reported — and says nothing on them, so nobody on the page sees it arrive, join their members or send. `--presence`
|
|
243
|
+
makes it take part as a visitor does. `--click` in `page shot` takes an element's name, a tag no element is named by
|
|
244
|
+
(`textarea`) or any selector, CSS or Playwright's own (`button:has-text("Orbit")`). In `--steps`, an element with a
|
|
245
|
+
space in it is quoted — `type ".panel textarea" hola` — and `type` fails when the click leaves no field focused.
|
|
246
|
+
|
|
240
247
|
`page shot --compare` writes the two pictures side by side and the differences in red. It compares each section where it
|
|
241
248
|
is on the other page, so a page 400 px longer is said once, with the section the drift starts at; then it pairs the
|
|
242
249
|
texts both pages have and says what each does differently there — `h1 "Learn CSS" — font-size 68px → 60px · y +19px`.
|
|
@@ -421,8 +428,8 @@ What a name means when authoring, from the catalogues the checks themselves read
|
|
|
421
428
|
otherwise be a search through the SDK's types. A name no catalogue holds — `pageFamily`, `styles`, `SpaceSpec` — is any
|
|
422
429
|
export of `@plitzi/sdk-authoring`, answered from the `.d.ts` the project installed, so it is the version the project
|
|
423
430
|
runs. An element of the project's own — `src/plugins/<Name>/` — is explained by its type the same way: what it takes
|
|
424
|
-
(each attribute at its default), fires and answers, and
|
|
425
|
-
add` prints too. `--json` answers in one object; over MCP it is `plitzi://explain/{name}`.
|
|
431
|
+
(each attribute at its default), fires and answers, and how it is placed — its declaration imported and
|
|
432
|
+
`defineElement(declaration)` called — which `plugin add` prints too. `--json` answers in one object; over MCP it is `plitzi://explain/{name}`.
|
|
426
433
|
|
|
427
434
|
## `doctor`
|
|
428
435
|
|
|
@@ -479,7 +486,7 @@ did you mean `index.ts`, `src/plugins/`? — and one that differs only in case s
|
|
|
479
486
|
| `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 |
|
|
480
487
|
| `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 |
|
|
481
488
|
| `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) |
|
|
482
|
-
| `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`) |
|
|
489
|
+
| `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`); its `Settings.tsx`, the panel the builder edits it with, written and passed as `pluginSettings` — even with nothing to set |
|
|
483
490
|
| `data` | every JSON file of `src/data/` and `public/data/` parses — what the server answers with and `space push` sends |
|
|
484
491
|
| `functions` | `src/functions/` built by the project's own `@plitzi/sdk-server` (`buildFunctions`), as every runner builds them |
|
|
485
492
|
| `records` | `.plitzi/space.json`, `scaffold.json` and `functions.json` readable, and of the same space |
|
|
@@ -598,14 +605,15 @@ said before anything is sent, with what to do: a provider reading a file `src/da
|
|
|
598
605
|
|
|
599
606
|
Adds elements of your own to the project you are in — one, several at once (`plugin add seat-picker legend`), or one at
|
|
600
607
|
a time as the need comes. Each is a folder, written the way Plitzi's own elements are (`@plitzi/sdk-elements`): the
|
|
601
|
-
component, its `declaration.ts` (its `type`, the events it fires,
|
|
602
|
-
adds), its `Settings.tsx` panel for the builder, and the `index.ts` that puts them together — what the folder is built
|
|
608
|
+
component, its `declaration.ts` (`definePlugin` from `@plitzi/sdk-authoring/plugin`: its `type`, the events it fires,
|
|
609
|
+
the actions it answers to, its defaults — the element the builder adds is derived from them), its `Settings.tsx` panel for the builder, and the `index.ts` that puts them together — what the folder is built
|
|
603
610
|
from: `index.ts`, or `index.tsx` for one that writes its JSX there, never both. It asks what to call each, what the
|
|
604
611
|
builder shows, and what it is for, and checks every folder is free before writing any.
|
|
605
612
|
|
|
606
613
|
- **In a project `plitzi create` wrote**, it goes in `src/plugins`, where the project already looks: nothing to
|
|
607
|
-
register, and a running `start:dev` picks it up without a restart.
|
|
608
|
-
— or, when the space lives in
|
|
614
|
+
register, and a running `start:dev` picks it up without a restart. Place it in `src/space/` from its declaration —
|
|
615
|
+
`defineElement(declaration)`, then `seatPicker({ id: 'seats' })` — or, when the space lives in
|
|
616
|
+
Plitzi, pack and upload it and add it in the builder.
|
|
609
617
|
- **In a plugin package**, it goes in `src/`, and is added to `src/elements.ts` and `src/declarations.ts`, from which
|
|
610
618
|
the package publishes it.
|
|
611
619
|
- **In any other project**, it asks which folder holds the project's components (`--dir` answers it) and prints how
|
|
@@ -622,7 +630,8 @@ plitzi plugin add ticker --prop interval:number=5000 --prop paused:boolean --tri
|
|
|
622
630
|
`--prop name:type=default` (string, number or boolean) is an attribute: in the props, the declaration's defaults and
|
|
623
631
|
`bindingsAllowed`, and a control in `Settings.tsx`; `--prop rows:list` and `--prop meta:json` are data a binding fills
|
|
624
632
|
(`unknown[]`, `Record<string, unknown>`, empty until it does). `--trigger onTick:count,at` is an event and what a flow
|
|
625
|
-
started by it reads, fired with
|
|
633
|
+
started by it reads, fired with `usePluginTrigger(declaration)` — `fire('onTick', { count, at })`, typed by the
|
|
634
|
+
declaration, and never on the builder's canvas. `--callback reset`
|
|
626
635
|
is an action a flow can call. `--headless` is an element with nothing to see: hidden on a page, a badge in the builder,
|
|
627
636
|
and `drawsNothing` in its declaration, so a page check does not look for it. The files are written as the project's
|
|
628
637
|
Prettier writes them.
|
|
@@ -690,7 +699,6 @@ plitzi source pack src/runtime/index.ts --kind runtime --name runtime -o runtime
|
|
|
690
699
|
|
|
691
700
|
What `plugin upload` and `runtime push` keep, written to a file to look at: the closure of the entries named, gzipped.
|
|
692
701
|
|
|
693
|
-
|
|
694
702
|
## `login`, `space use` and `plugin upload`
|
|
695
703
|
|
|
696
704
|
```bash
|
|
@@ -765,13 +773,14 @@ plitzi functions pull # the space's
|
|
|
765
773
|
plitzi functions push # src/functions/ saved as the space's draft, built and checked
|
|
766
774
|
plitzi functions try seismic.feed --params '{"minMagnitude":"4"}' # one task of the saved draft, in the sandbox
|
|
767
775
|
plitzi functions dev seismic.feed --params '{}' --watch # on this machine, as the platform runs it
|
|
776
|
+
plitzi functions add ical.js # an installed package bundled into src/functions/vendor/
|
|
768
777
|
```
|
|
769
778
|
|
|
770
779
|
A space's own server code — tasks its actions run as steps, routes under `/fn/` — and `src/functions/` is a working copy
|
|
771
780
|
of it: `.plitzi/functions.json` keeps what was pulled, so `functions pull` refuses to overwrite what is not pushed (`--force`
|
|
772
781
|
throws it away) and `functions push` refuses when the space moved on since. A problem comes back as
|
|
773
782
|
`src/functions/<file>:<line> <message>`. `dev` runs with the project's own `@plitzi/sdk-server` (`isolated-vm` and
|
|
774
|
-
`core-js` beside it); credentials come from `
|
|
783
|
+
`core-js` beside it); credentials come from `PLITZI_CREDENTIALS` (`.env`), as they do for the project's server. See `docs/en/functions.md`.
|
|
775
784
|
|
|
776
785
|
## Credentials
|
|
777
786
|
|