@plitzi/sdk-mcp 0.38.6 → 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 +205 -0
- package/dist/modules/mcp/helpers/guide.js +37 -14
- package/dist/modules/mcp/server.js +1 -1
- package/dist/modules/mcp/tools/apply/index.d.ts +636 -6
- package/dist/modules/mcp/tools/operations/index.d.ts +2564 -44
- package/dist/modules/mcp/tools/operations/schema/elements/moveElement.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/schema/elements/repeatElement.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/schema/elements/upsertElement.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/schema/operations.d.ts +3 -3
- package/dist/modules/mcp/tools/operations/schema/shared.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/schemaIds.js +7 -1
- package/dist/modules/mcp/tools/operations/style/definitions/patchDefinition.d.ts +90 -0
- package/dist/modules/mcp/tools/operations/style/definitions/patchDefinition.js +2 -1
- package/dist/modules/mcp/tools/operations/style/definitions/upsertDefinition.d.ts +90 -0
- package/dist/modules/mcp/tools/operations/style/definitions/upsertDefinition.js +2 -1
- package/dist/modules/mcp/tools/operations/style/definitions/upsertDefinitions.d.ts +90 -0
- package/dist/modules/mcp/tools/operations/style/definitions/upsertDefinitions.js +8 -1
- package/dist/modules/mcp/tools/operations/style/globalStyles/patchGlobalStyle.d.ts +90 -0
- package/dist/modules/mcp/tools/operations/style/globalStyles/patchGlobalStyle.js +2 -1
- package/dist/modules/mcp/tools/operations/style/globalStyles/upsertGlobalStyle.d.ts +90 -0
- package/dist/modules/mcp/tools/operations/style/globalStyles/upsertGlobalStyle.js +2 -1
- package/dist/modules/mcp/tools/operations/style/idStyles/patchIdStyle.d.ts +90 -0
- package/dist/modules/mcp/tools/operations/style/idStyles/patchIdStyle.js +2 -1
- package/dist/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.d.ts +90 -0
- package/dist/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.js +2 -1
- package/dist/modules/mcp/tools/operations/style/operations.d.ts +639 -9
- package/dist/modules/mcp/tools/operations/style/shared.d.ts +394 -0
- package/dist/modules/mcp/tools/operations/style/shared.js +26 -8
- package/dist/modules/mcp/tools/operations/style/translator.js +26 -1
- package/dist/modules/mcp/tools/operations/style/validate.d.ts +4 -0
- package/dist/modules/mcp/tools/operations/style/validate.js +63 -0
- package/dist/modules/mcp/tools/operations/style/write.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/style/write.js +88 -2
- package/dist/modules/mcp/tools/preview.d.ts +636 -6
- package/dist/modules/mcp/tools/render.d.ts +636 -6
- package/dist/modules/mcp/tools/screenshot.d.ts +636 -6
- package/dist/modules/mcp/tools/validate.d.ts +636 -6
- package/dist/modules/mcp/types/aiSchema.d.ts +13 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,210 @@
|
|
|
1
1
|
# @plitzi/sdk-mcp
|
|
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
|
+
- @plitzi/sdk-schema@0.38.7
|
|
203
|
+
- @plitzi/sdk-shared@0.38.7
|
|
204
|
+
- @plitzi/sdk-style@0.38.7
|
|
205
|
+
- @plitzi/plitzi-sdk@0.38.7
|
|
206
|
+
- @plitzi/sdk-server@0.38.7
|
|
207
|
+
|
|
3
208
|
## 0.38.6
|
|
4
209
|
|
|
5
210
|
### Patch Changes
|
|
@@ -135,8 +135,8 @@ Never download a whole tree you do not need.
|
|
|
135
135
|
\`link\` navigates between pages, \`list\` repeats a template over a data array. \`plugin\` types are custom elements.
|
|
136
136
|
- \`plitzi://css-properties\` — valid kebab-case CSS property keys.
|
|
137
137
|
- \`plitzi://explain/{name}\` — what a name means: an element type's attributes, triggers and callbacks; a step's
|
|
138
|
-
params; what a trigger hands its flow; a problem code's fix. \`plitzi://explain/steps\` (or
|
|
139
|
-
codes, transformers) lists every one of a kind.
|
|
138
|
+
params and what it publishes; what a trigger hands its flow; a problem code's fix. \`plitzi://explain/steps\` (or
|
|
139
|
+
elements, triggers, codes, transformers) lists every one of a kind.
|
|
140
140
|
- \`plitzi://schema/{env}/pages\` — page **summaries** (ref, label, elementCount, folder). No element trees.
|
|
141
141
|
- \`plitzi://schema/{env}/layouts\` — the shared **layout shells** (header/sidebar/footer) and the pages rendered
|
|
142
142
|
inside each. Read one like a page. See *Shared layouts* below.
|
|
@@ -357,7 +357,11 @@ You do not have to rewrite them.
|
|
|
357
357
|
\`justify-content\` as separate properties.
|
|
358
358
|
- CSS is grouped by breakpoint: \`desktop\`, \`tablet\`, \`mobile\`.
|
|
359
359
|
- Reference a style variable in CSS as \`var(--name)\`; a schema variable in a prop as \`{{name}}\`.
|
|
360
|
-
- \`element.style.base\` is a **list** of definition refs; other slots go under \`element.style.slots
|
|
360
|
+
- \`element.style.base\` is a **list** of definition refs; other slots go under \`element.style.slots\` — the slots
|
|
361
|
+
\`plitzi://explain/{type}\` lists, never custom CSS on the SDK's own class names. A \`markdown\` or a \`richText\`
|
|
362
|
+
has a slot per part of the document it writes (\`heading\`, \`heading2\`, \`paragraph\`, \`link\`, \`code\`,
|
|
363
|
+
\`codeBlockFrame\`…); a \`formControl\` its \`input\` box, the \`field\` inside it, \`label\`, \`requiredMark\`, \`error\`;
|
|
364
|
+
a \`pagination\` its \`previous\`, \`page\`, \`next\` (the page shown is the class's \`current\` state).
|
|
361
365
|
- **An element can attach SEVERAL classes at once, and they all apply.** \`style.base\` holds a list, and each
|
|
362
366
|
non-base slot holds its own — every attached definition contributes CSS, and they **cascade** (a later class, then a
|
|
363
367
|
global/id rule, overrides an earlier one on the same property). So when a style looks wrong, the culprit may be
|
|
@@ -403,6 +407,15 @@ hovered or in a variant (\`.card:hover .icon\`, a collapsed sidebar hiding its l
|
|
|
403
407
|
keyed by a class the ancestor wears: \`ancestors: { "toolbar": { "desktop": { … } }, "card": { "states": { "hover":
|
|
404
408
|
{ "desktop": { … } } } }, "sidebar": { "variants": { "collapsed": … } } }\`.
|
|
405
409
|
Any ancestor counts, not only the parent; the class's own states and variants win over these. Never customCss for it.
|
|
410
|
+
\`">"\` keys the parent, whatever it wears — a component's part reacting to what it sits in.
|
|
411
|
+
|
|
412
|
+
**Pseudo-elements and conditions** sit beside \`states\` in a definition and in each of its variants:
|
|
413
|
+
\`pseudos: { "after": { "desktop": { "content": "\\"→\\"" }, "states": { "hover": { "desktop": { … } } } } }\`
|
|
414
|
+
(\`before\`/\`after\` are drawn only with a quoted \`content\`; also \`selection\`, \`marker\`, \`placeholder\`,
|
|
415
|
+
\`first-letter\`, \`first-line\`), and \`conditions: { "motion-reduce": { "desktop": { … } }, "container (max-width:
|
|
416
|
+
30rem)": { … } }\` (the nearest ancestor whose class sets \`container-type\`). A patch keeps the ones it does not name;
|
|
417
|
+
\`null\` removes one. A state beyond \`hover\`/\`focus-visible\`/\`current\`: \`expanded\` (an open trigger), \`first\`,
|
|
418
|
+
\`last\`, \`odd\`, \`even\`.
|
|
406
419
|
|
|
407
420
|
## Variables, design tokens and fonts
|
|
408
421
|
- **Schema variables** are space-wide values a prop reads as \`{{name}}\`: \`upsertVariable { name, variableType,
|
|
@@ -479,9 +492,11 @@ you — never wire them by hand. Each step also has an \`enabled\` flag (see dis
|
|
|
479
492
|
|
|
480
493
|
**Each step reads the page as it is when it runs**: a \`when\` or a \`{{ state.x }}\` after a \`setState\` sees the new
|
|
481
494
|
value, and one after a \`delay\` sees what changed meanwhile. To act on the value from BEFORE a write, put the reading
|
|
482
|
-
step first.
|
|
483
|
-
|
|
484
|
-
\`
|
|
495
|
+
step first. A step's \`when\` asks an earlier step only for what it publishes (\`plitzi://explain/<action>\` lists it):
|
|
496
|
+
a run's \`<step>.status\` (\`runServerAction\` only), a sign-in's \`<step>.ok\` — any other key is refused
|
|
497
|
+
(\`condition-field-unpublished\`). **A trigger fired again while its flow runs is ignored** (no double submit); set
|
|
498
|
+
\`"whileRunning": "queue"\` on the trigger node for a stream of events that must each run in order (\`"parallel"\` runs
|
|
499
|
+
them at once, \`"latest"\` stops the running flow — its server action or request too — for a search as you type).
|
|
485
500
|
**Keyboard shortcuts** are a trigger every element has: \`onKey\` with param \`keys\` — \`"f"\`, \`"shift+f"\`,
|
|
486
501
|
\`"mod+k"\` (⌘ on a Mac, Ctrl elsewhere), \`"plus, ="\`, \`"escape"\`. Heard on the whole page while the element is
|
|
487
502
|
mounted, ignored while someone types in a field; the flow reads the key pressed as \`{{ <trigger id>.key }}\`.
|
|
@@ -727,8 +742,9 @@ any other (\`<namespace>.<action>\`), listed in \`plitzi://actions/{env}/tasks\`
|
|
|
727
742
|
\`defineFunctions\` from \`@plitzi/sdk-server/functions\`. Files import each other by relative path — no package,
|
|
728
743
|
no Node built-in.
|
|
729
744
|
- **\`ctx\` is all a function reaches:** \`ctx.kv\` (the space's store), \`ctx.fetch(url, init)\` to the hosts
|
|
730
|
-
\`allow.hosts\` names (\`*.example.com\` for subdomains), \`ctx.publish/grant/revoke\` (channels),
|
|
731
|
-
\`ctx.
|
|
745
|
+
\`allow.hosts\` names (\`*.example.com\` for subdomains), \`ctx.publish/grant/revoke\` (channels),
|
|
746
|
+
\`ctx.data("products.json")\` (one file of the space's data, parsed — never imported), \`ctx.log\`, \`ctx.user\` (who
|
|
747
|
+
asked, never their session). A secret is NAMED, never read: \`ctx.fetch(url, { credential: "stripe",
|
|
732
748
|
headers: { authorization: "Bearer {{ credential.apiKey }}" } })\`.
|
|
733
749
|
- **Stateless:** nothing a function keeps in memory outlives the call — a module-level cache or counter starts empty
|
|
734
750
|
every time, on whichever instance runs it. What must last goes in \`ctx.kv\`. A call gets 100 ms of CPU and 10 s;
|
|
@@ -917,7 +933,10 @@ the component does not have is reported by \`plitzi_validate\` — fix it before
|
|
|
917
933
|
- **The link to the page being shown marks itself**: it carries \`aria-current="page"\`, and its class's \`current\`
|
|
918
934
|
state says how it looks — \`{ "type": "patchDefinition", "ref": "nav-link", "states": { "current": { "desktop": {
|
|
919
935
|
"color": "var(--primary)" } } } }\`. So a header written once in a layout lights the right item on every page; never
|
|
920
|
-
copy the header per page to style one item.
|
|
936
|
+
copy the header per page to style one item. A link for a section — a journal and its articles — takes
|
|
937
|
+
\`"current": "section"\` in its props: current on every page under its path too (\`aria-current="true"\`), the same
|
|
938
|
+
state dressing it. The same state dresses any chosen one of a set: a pressed toggle (\`aria-pressed\` — a theme
|
|
939
|
+
toggle's option slot) and a selected tab.
|
|
921
940
|
- **A section of a page** is an element with an \`anchor\` (its \`id\` in the DOM: lowercase, digits, \`-\`; one per
|
|
922
941
|
page, layouts included; not inside a list row or a component). A link lands on it with \`hash\`:
|
|
923
942
|
\`{ "mode": "page", "href": "home", "hash": "plans" }\` goes to \`/#plans\` and scrolls there, from any page.
|
|
@@ -946,10 +965,12 @@ Space-level configuration lives in \`plitzi://settings/{env}\` and is edited wit
|
|
|
946
965
|
- \`customCss\` — **raw global CSS** injected for the whole space. Use it only for genuinely site-wide rules
|
|
947
966
|
(\`@keyframes\`, \`@font-face\`, resets). To style an element, write a **definition** and attach it — never customCss.
|
|
948
967
|
- \`notifications\` — how the toasts an \`addNotification\` step shows look: colours (\`background\`, \`text\`,
|
|
949
|
-
\`success\`, \`danger\`, \`warning\`, \`info\`)
|
|
950
|
-
\`padding\`)
|
|
951
|
-
|
|
952
|
-
|
|
968
|
+
\`success\`, \`danger\`, \`warning\`, \`info\`), shape (\`radius\`, \`font\`, \`fontSize\`, \`fontWeight\`, \`lineHeight\`,
|
|
969
|
+
\`minHeight\`, \`border\`, \`shadow\`, \`padding\`) and the parts inside (\`iconSize\`, \`iconGap\`, \`closeColor\`,
|
|
970
|
+
\`closeOpacity\`, \`progressHeight\`), one CSS value each — a token follows the theme: \`{ "type": "patchSettings",
|
|
971
|
+
"notifications": { "background": "var(--card)", "iconSize": "18px" } }\`. Merged field by field, \`null\` removes one.
|
|
972
|
+
It is stored as rules inside \`customCss\` but reads and changes apart from it: never write a \`.Toastify__*\` rule
|
|
973
|
+
yourself.
|
|
953
974
|
- \`keepState\` / \`stateStorage\` — keep the runtime state (\`state.<key>\`, what \`setState\` writes) across reloads,
|
|
954
975
|
in \`localStorage\`/\`sessionStorage\`, filed under whoever is signed in. It is the space's setting — pages do not
|
|
955
976
|
take one. \`transientState\` lists the top-level keys never kept (a filter, a demo, a panel left open); do not
|
|
@@ -957,10 +978,12 @@ Space-level configuration lives in \`plitzi://settings/{env}\` and is edited wit
|
|
|
957
978
|
\`paintedState\` lists the kept keys the FIRST PAINT shows (the tool a toolbar shows, a name in an avatar): they go
|
|
958
979
|
in a cookie too, so the server draws with them instead of the page swapping them in after load. Small values only.
|
|
959
980
|
- **User provider / auth**: \`userProvider\` — \`basic\` for any HTTP+JSON backend, the name of a provider registered
|
|
960
|
-
in the page, or \`""\`
|
|
981
|
+
in the page, or \`""\` for none — plus \`tokenStorage\`, the \`loginUrl\`/\`userUrl\`/\`refreshUrl\`/\`logoutUrl\`
|
|
961
982
|
endpoints and the \`detailsPath\`/\`tokenPath\`/\`refreshTokenPath\`/\`expirationTimePath\` mapping that says where the
|
|
962
983
|
values sit in their responses. \`sessionHintCookie\` is worth setting whenever the backend can: it names a readable
|
|
963
984
|
cookie carrying only expiries, which is what lets a page answer "nobody is signed in" without a request.
|
|
985
|
+
A space served by a self-hosted \`createServer({ auth })\` declares none of these: that server tells its pages where
|
|
986
|
+
they sign in, and only what the space declares overrides it.
|
|
964
987
|
On the Plitzi platform, \`userProvider: "server"\` signs visitors in with their Plitzi account on the space's own
|
|
965
988
|
host: a \`link\` with \`mode: "external"\` to \`/auth/sign-in?return=/\` starts it, \`authLogout\` ends it.
|
|
966
989
|
- \`visitorRoles\` — what each visitor role gives, \`{ "author": ["postPublish"] }\`: the permissions an action's
|
|
@@ -72,7 +72,7 @@ var createMcpServer = async ({ adapters, getGrant, preview, screenshot, logger,
|
|
|
72
72
|
const getSpace = () => spacePromise ??= loadSpace();
|
|
73
73
|
const server = new McpServer({
|
|
74
74
|
name: "plitzi-mcp",
|
|
75
|
-
version: "0.38.
|
|
75
|
+
version: "0.38.7"
|
|
76
76
|
}, { instructions: hasSpace ? serverInstructions : widgetsOnlyInstructions });
|
|
77
77
|
const { getChanges } = adapters;
|
|
78
78
|
registerResources(server, getSpace, MCP_ENV, log, hasSpace, getChanges ? (query) => getChanges(requireSpaceId(), MCP_ENV, query) : void 0);
|