wizards 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -42
- package/apps/runtime/dist/agents/studio-assistant.js +3 -3
- package/apps/runtime/dist/app.js +7 -4
- package/apps/runtime/dist/auth/index.js +2 -2
- package/apps/runtime/dist/authoring/guide.js +1 -1
- package/apps/runtime/dist/cli/account.js +31 -28
- package/apps/runtime/dist/cli/autostart.js +5 -3
- package/apps/runtime/dist/cli/clients.js +1 -1
- package/apps/runtime/dist/cli/connect.js +24 -24
- package/apps/runtime/dist/cli/features.js +6 -6
- package/apps/runtime/dist/cli/main.js +51 -39
- package/apps/runtime/dist/cli/mcp.js +5 -4
- package/apps/runtime/dist/cli/menu.js +32 -30
- package/apps/runtime/dist/cli/report.js +7 -9
- package/apps/runtime/dist/cli/setup.js +42 -38
- package/apps/runtime/dist/cli/start.js +16 -15
- package/apps/runtime/dist/cli/status.js +20 -20
- package/apps/runtime/dist/cli/ui.js +9 -2
- package/apps/runtime/dist/cli/update.js +6 -6
- package/apps/runtime/dist/cli/validate.js +1 -1
- package/apps/runtime/dist/connectors/external.js +3 -2
- package/apps/runtime/dist/connectors/index.js +5 -5
- package/apps/runtime/dist/connectors/plugin-connections.js +2 -2
- package/apps/runtime/dist/connectors/via-account.js +5 -5
- package/apps/runtime/dist/db/control-schema.js +14 -0
- package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
- package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
- package/apps/runtime/dist/db/migrations/control/meta/_journal.json +7 -0
- package/apps/runtime/dist/docs/dev/index.md +16 -14
- package/apps/runtime/dist/docs/dev/plugins/connections.md +27 -24
- package/apps/runtime/dist/docs/dev/plugins/events.md +19 -17
- package/apps/runtime/dist/docs/dev/plugins/examples.md +13 -12
- package/apps/runtime/dist/docs/dev/plugins/index.md +29 -24
- package/apps/runtime/dist/docs/dev/plugins/layout.md +20 -19
- package/apps/runtime/dist/docs/dev/plugins/quick-start.md +16 -15
- package/apps/runtime/dist/docs/dev/plugins/reference.md +52 -40
- package/apps/runtime/dist/docs/dev/plugins/reloading.md +24 -23
- package/apps/runtime/dist/docs/dev/plugins/routes.md +26 -22
- package/apps/runtime/dist/docs/dev/plugins/runners.md +49 -44
- package/apps/runtime/dist/docs/dev/plugins/server.md +95 -43
- package/apps/runtime/dist/docs/dev/plugins/shipping.md +19 -16
- package/apps/runtime/dist/docs/dev/plugins/space.md +75 -69
- package/apps/runtime/dist/docs/dev/plugins/starters.md +22 -17
- package/apps/runtime/dist/docs/dev/plugins/studio.md +80 -37
- package/apps/runtime/dist/docs/dev/plugins/styling.md +44 -41
- package/apps/runtime/dist/docs/dev/plugins/tables.md +11 -11
- package/apps/runtime/dist/docs/dev/plugins/tools.md +26 -25
- package/apps/runtime/dist/docs/dev/wizard-format.md +35 -23
- package/apps/runtime/dist/docs/user/ai-apps.md +46 -43
- package/apps/runtime/dist/docs/user/assistant.md +41 -36
- package/apps/runtime/dist/docs/user/build-a-wizard.md +64 -39
- package/apps/runtime/dist/docs/user/command-line.md +47 -44
- package/apps/runtime/dist/docs/user/connectors.md +40 -35
- package/apps/runtime/dist/docs/user/create-account.md +27 -22
- package/apps/runtime/dist/docs/user/data.md +29 -29
- package/apps/runtime/dist/docs/user/first-start.md +26 -28
- package/apps/runtime/dist/docs/user/index.md +16 -17
- package/apps/runtime/dist/docs/user/install.md +28 -27
- package/apps/runtime/dist/docs/user/local-only.md +21 -17
- package/apps/runtime/dist/docs/user/models.md +92 -84
- package/apps/runtime/dist/docs/user/plugins.md +28 -23
- package/apps/runtime/dist/docs/user/run.md +51 -50
- package/apps/runtime/dist/docs/user/server.md +9 -9
- package/apps/runtime/dist/docs/user/space.md +87 -65
- package/apps/runtime/dist/docs/user/steps.md +73 -69
- package/apps/runtime/dist/docs/user/test-and-share.md +127 -105
- package/apps/runtime/dist/docs/user/troubleshooting.md +40 -38
- package/apps/runtime/dist/docs/user/wordpress.md +62 -54
- package/apps/runtime/dist/documents/parse.js +2 -2
- package/apps/runtime/dist/engenty/shims/web-ingest.js +17 -1
- package/apps/runtime/dist/engine/input.js +4 -4
- package/apps/runtime/dist/engine/push.js +2 -2
- package/apps/runtime/dist/engine/runner.js +8 -8
- package/apps/runtime/dist/engine/steps.js +2 -2
- package/apps/runtime/dist/engine/surface.js +1 -1
- package/apps/runtime/dist/film/step.js +3 -3
- package/apps/runtime/dist/harness/claude.js +1 -1
- package/apps/runtime/dist/harness/codex.js +1 -1
- package/apps/runtime/dist/harness/model.js +2 -2
- package/apps/runtime/dist/harness/terminal.js +3 -3
- package/apps/runtime/dist/mcp/handler.js +2 -2
- package/apps/runtime/dist/mcp/tools.js +9 -9
- package/apps/runtime/dist/models.js +15 -15
- package/apps/runtime/dist/plugins/claims.js +56 -0
- package/apps/runtime/dist/plugins/loader.js +2 -0
- package/apps/runtime/dist/plugins/public.js +2 -3
- package/apps/runtime/dist/plugins/runs.js +13 -8
- package/apps/runtime/dist/render/chromium.js +24 -11
- package/apps/runtime/dist/routes/api.js +15 -9
- package/apps/runtime/dist/routes/debug.js +1 -1
- package/apps/runtime/dist/routes/delivery.js +46 -0
- package/apps/runtime/dist/routes/lang.js +7 -0
- package/apps/runtime/dist/routes/marketplace.js +2 -1
- package/apps/runtime/dist/routes/plugin-public.js +2 -1
- package/apps/runtime/dist/routes/plugins.js +13 -14
- package/apps/runtime/dist/routes/runs.js +59 -49
- package/apps/runtime/dist/routes/studio.js +53 -23
- package/apps/runtime/dist/services/access.js +3 -3
- package/apps/runtime/dist/services/assistant-chats.js +1 -1
- package/apps/runtime/dist/services/brand.js +2 -2
- package/apps/runtime/dist/services/cloud.js +5 -4
- package/apps/runtime/dist/services/errors.js +2 -1
- package/apps/runtime/dist/services/knowledge-model.js +2 -2
- package/apps/runtime/dist/services/marketplace.js +2 -2
- package/apps/runtime/dist/services/package-file.js +12 -9
- package/apps/runtime/dist/services/package.js +2 -2
- package/apps/runtime/dist/services/project-files.js +10 -12
- package/apps/runtime/dist/services/projects.js +13 -8
- package/apps/runtime/dist/services/runners.js +4 -3
- package/apps/runtime/dist/services/runs.js +3 -3
- package/apps/runtime/dist/services/site.js +2 -2
- package/apps/runtime/dist/services/space-categories.js +4 -4
- package/apps/runtime/dist/services/space-data.js +13 -13
- package/apps/runtime/dist/services/space-origin.js +1 -1
- package/apps/runtime/dist/services/spaces.js +7 -7
- package/apps/runtime/dist/services/wizards.js +5 -5
- package/apps/runtime/dist/tools/net-guard.js +135 -24
- package/apps/runtime/dist/tools/plugin.js +1 -1
- package/apps/runtime/dist/tools/store.js +1 -1
- package/apps/runtime/dist/widgets/step.js +1 -1
- package/apps/web/dist/assets/AboutDialog-DaYwk84X.js +1 -0
- package/apps/web/dist/assets/{ChangelogDialog-BXpkgatF.js → ChangelogDialog-CsYbEayb.js} +1 -1
- package/apps/web/dist/assets/{ChatView-t7z44uFN.js → ChatView-BRD3fKZU.js} +1 -1
- package/apps/web/dist/assets/{EditorPage-4qxNJgKr.js → EditorPage-ocPlZD3E.js} +3 -3
- package/apps/web/dist/assets/{FlowPreview-WpS8DCPl.js → FlowPreview-Bm7sv746.js} +1 -1
- package/apps/web/dist/assets/{Harness-DL7Bse40.js → Harness-DKE-YNA5.js} +1 -1
- package/apps/web/dist/assets/{NewWizardChannels-Crt6PzH2.js → NewWizardChannels-CnWckqjO.js} +1 -1
- package/apps/web/dist/assets/{NewWizardPage-COiVmNsl.js → NewWizardPage-BXTpbHVM.js} +1 -1
- package/apps/web/dist/assets/{OnboardingPage-BwluEqXq.js → OnboardingPage-3Rz5uOsa.js} +1 -1
- package/apps/web/dist/assets/{ProjectPage-BIRU_AlN.js → ProjectPage-QdSJwm3k.js} +1 -1
- package/apps/web/dist/assets/{PublicRunner-BxMb4gEt.js → PublicRunner-DEpBer5g.js} +1 -1
- package/apps/web/dist/assets/{ReadOnly-D9r5ze5S.js → ReadOnly-rr_RJD-a.js} +1 -1
- package/apps/web/dist/assets/{RunDrawer-DmJl2QOJ.js → RunDrawer-BsZt0tL9.js} +1 -1
- package/apps/web/dist/assets/{RunnerView-CF_1rC-7.js → RunnerView-BbRukEdE.js} +1 -1
- package/apps/web/dist/assets/SettingsPage-qkWsQIMN.js +1 -0
- package/apps/web/dist/assets/{SetupPage-BGKtbS7j.js → SetupPage-PzvPPLfM.js} +1 -1
- package/apps/web/dist/assets/{SharePage-C4MqXKDA.js → SharePage-7vdDWG1n.js} +1 -1
- package/apps/web/dist/assets/changelog-BFdAYD28.js +1 -0
- package/apps/web/dist/assets/{esm-CsY8TkyE.js → esm-g0kaGp8t.js} +1 -1
- package/apps/web/dist/assets/{index-BjQvGQp_.js → index-BzPid1oQ.js} +4 -4
- package/apps/web/dist/assets/{lock-CI6TpWL-.js → lock-BK9RYIft.js} +1 -1
- package/apps/web/dist/assets/oss-credits-BJrR7BR1.js +1 -0
- package/apps/web/dist/assets/{phone-BrtQz-fG.js → phone-DtkY0NfU.js} +1 -1
- package/apps/web/dist/assets/{settings-menu-BtEKL72n.js → settings-menu-7EJQRFOi.js} +1 -1
- package/apps/web/dist/assets/{ui-4IaTD7LB.js → ui-B6S5hYPd.js} +3 -3
- package/apps/web/dist/assets/{upload-CWJAtPRo.js → upload-rYCAy7ox.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/apps/web/dist/mcp/flow.html +3 -3
- package/bin/wizards.mjs +1 -1
- package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +21 -2
- package/node_modules/@engenty-wizards/shared/dist/projects.js +1 -1
- package/node_modules/@engenty-wizards/shared/dist/run.d.ts +48 -48
- package/node_modules/@engenty-wizards/shared/dist/run.js +48 -48
- package/package.json +5 -4
- package/apps/web/dist/assets/AboutDialog-A_ILyeue.js +0 -1
- package/apps/web/dist/assets/SettingsPage-3xSInE-A.js +0 -1
- package/apps/web/dist/assets/changelog-CM_GdIVI.js +0 -1
- package/apps/web/dist/assets/oss-credits-BQQX0kvk.js +0 -1
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: The space
|
|
3
3
|
description: Knowledge a plugin writes, a block and tools for every AI step of a space, texts in its search index, tools and cards of its assistant.
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
A space holds what all its wizards share: a
|
|
8
|
-
pages, tables and files with their
|
|
9
|
-
space
|
|
10
|
-
own tables call a space a project: `wizard.projectId` in a [run event](./events.md) is
|
|
11
|
-
id.
|
|
7
|
+
A space holds what all its wizards share: a name, its brand (logos, colours, fonts), facts, and
|
|
8
|
+
Knowledge – pages, tables and files with their categories. A plugin can write Knowledge and add to
|
|
9
|
+
what the space’s AI steps know, to what its search finds and to what its assistant can do. The
|
|
10
|
+
runtime’s own tables call a space a project: `wizard.projectId` in a [run event](./events.md) is
|
|
11
|
+
a space’s id.
|
|
12
12
|
|
|
13
13
|
## Knowledge a plugin writes
|
|
14
14
|
|
|
15
|
-
`server.spaceData` writes pages, tables and files into a space
|
|
16
|
-
plugin
|
|
17
|
-
later, filtered by its
|
|
18
|
-
space
|
|
15
|
+
`server.spaceData` writes pages, tables and files into a space’s Knowledge under keys of the
|
|
16
|
+
plugin’s own, with their categories. Every write is indexed: `project_search` finds it a moment
|
|
17
|
+
later, filtered by its categories and checked like everything else in Knowledge. `space` is the
|
|
18
|
+
space’s id.
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
|
-
// The source's
|
|
21
|
+
// The source's categories, once. `proposed: true` shows them to the person to confirm first.
|
|
22
22
|
await server.spaceData.putCategories({
|
|
23
23
|
space,
|
|
24
24
|
categories: [
|
|
@@ -36,7 +36,7 @@ await server.spaceData.putPage({
|
|
|
36
36
|
title: "Weekly meeting, 14 March 2026",
|
|
37
37
|
markdown,
|
|
38
38
|
categories: { Team: "Sales", "Meeting date": "2026-03-14", Duration: 1.5 },
|
|
39
|
-
fill: true, // a model fills the
|
|
39
|
+
fill: true, // a model fills the categories the entry did not bring
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
// A file is read as an upload is: a page, sub-pages, a table per sheet, or a file.
|
|
@@ -45,20 +45,20 @@ const doc = await server.spaceData.putDocument({ space, key, label, name, mime,
|
|
|
45
45
|
|
|
46
46
|
| `server.spaceData.` | Does |
|
|
47
47
|
|---|---|
|
|
48
|
-
| `putCategories({ space, categories, proposed? })` | Adds
|
|
48
|
+
| `putCategories({ space, categories, proposed? })` | Adds categories, or values to known ones. Types: `choice` (with `values`, `multiple`, `ordered`), `date`, `number` (with `unit`), `text`, `boolean`. `column: { table, column }` takes a category’s values from a column of a table the plugin wrote |
|
|
49
49
|
| `putPage(input)` | A page: `title`, `markdown`, `parent` (the key of a page to stand under), `original` (the file it was read from), `categories`, `fill`, `review` (why a person should look) |
|
|
50
50
|
| `putTable(input)` | A table: typed `columns`, `rows` (cells by column id, they replace the rows the key had), `format: "faq"` |
|
|
51
|
-
| `putFile(input)` | A file that is
|
|
52
|
-
| `putDocument(input)` | A file read
|
|
53
|
-
| `readPages(space, { parent? })` | The space
|
|
54
|
-
| `files(space, kind?)`, `readFile(space, id)` | The space
|
|
51
|
+
| `putFile(input)` | A file that is not a page. It is found by its name, `description` and categories; `text` is what a step reads of it |
|
|
52
|
+
| `putDocument(input)` | A file, read the way an upload is. Returns what it became: `items` (pages, tables), and `review` when it was hard to read or could not be read |
|
|
53
|
+
| `readPages(space, { parent? })` | The space’s own pages, whoever wrote them, with their Markdown: `{ id, title, path, parentId, markdown, origin, originKey, updatedAt }` |
|
|
54
|
+
| `files(space, kind?)`, `readFile(space, id)` | The space’s files of a kind (`document`, `logo`, `asset`, `pattern`; `document` when none is named), newest first, and one file with its bytes, such as a price list someone dropped into Knowledge |
|
|
55
55
|
| `list(space)` | Everything the plugin wrote, by key, with its path and `state` |
|
|
56
|
-
| `remove(space, key?)` | Takes out one key, or everything
|
|
57
|
-
| `summarize(space, category?, value?)` | Writes the Overview of
|
|
56
|
+
| `remove(space, key?)` | Takes out one key, or everything the plugin wrote in the space. Returns how many items it removed |
|
|
57
|
+
| `summarize(space, category?, value?)` | Writes the “Overview” of one value, or of every value with three items or more. Each costs a model call. Returns how many it wrote |
|
|
58
58
|
|
|
59
|
-
- `label` is what the person knows the source as
|
|
60
|
-
-
|
|
61
|
-
changes nothing, and `remove` leaves it.
|
|
59
|
+
- `label` is what the person knows the source as. Knowledge shows it beside the item.
|
|
60
|
+
- When a person changes an item, it is theirs: the plugin’s next write returns `state: "kept"`
|
|
61
|
+
and changes nothing, and `remove` leaves it.
|
|
62
62
|
- What a step reads of an item is its path: `pages/…`, `tables/…`, `files/…`.
|
|
63
63
|
|
|
64
64
|
## A block for every AI step
|
|
@@ -82,40 +82,40 @@ server.registerSpaceContext({
|
|
|
82
82
|
});
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
- Every agent step of the space
|
|
85
|
+
- Every agent step of the space’s wizards gets the block in its instructions, after what the
|
|
86
86
|
space says about itself and its documents, and gets the tools with it. No step lists them.
|
|
87
|
-
- `block` is
|
|
88
|
-
the tools.
|
|
87
|
+
- `block` is called once per step. If it returns `null` or an empty text, the step gets neither
|
|
88
|
+
the block nor the tools.
|
|
89
89
|
- A block is cut at 8,000 characters. A block that throws is logged, and the step runs without
|
|
90
90
|
it.
|
|
91
91
|
- The tools are [tools](./tools.md) like the ones a step lists; the model sees
|
|
92
|
-
`<plugin>_<name>`. Their names and the names of the plugin
|
|
93
|
-
- A model on the device calls no tools
|
|
94
|
-
followed on, which answers only steps that list no tools themselves.
|
|
95
|
-
block without the tools.
|
|
96
|
-
- `steps` says which steps get
|
|
97
|
-
document or a dashboard as HTML
|
|
98
|
-
brand
|
|
92
|
+
`<plugin>_<name>`. Their names and the names of the plugin’s other tools are one list.
|
|
93
|
+
- A model on the device calls no tools. That is Apple Intelligence on a Mac, or on the phone a
|
|
94
|
+
run is followed on, which answers only steps that list no tools themselves. Such a step gets
|
|
95
|
+
the block without the tools.
|
|
96
|
+
- `steps` says which steps get the block: `["agent"]` when left out. `"html"` stands for the
|
|
97
|
+
steps that write a document or a dashboard as HTML. They get the block without the tools,
|
|
98
|
+
after the space’s brand – a good place to say how the brand’s elements look.
|
|
99
99
|
|
|
100
|
-
## The space
|
|
100
|
+
## The space’s brand
|
|
101
101
|
|
|
102
|
-
`server.spaces.brand(space)` reads what Info & brand holds of the space
|
|
102
|
+
`server.spaces.brand(space)` reads what Info & brand holds of the space’s look, for a block, a
|
|
103
103
|
page or a model call in it:
|
|
104
104
|
|
|
105
105
|
```ts
|
|
106
106
|
const brand = await server.spaces.brand(space.id);
|
|
107
|
-
// { name: "Mira Kaffee", colors: [{ name: "
|
|
107
|
+
// { name: "Mira Kaffee", colors: [{ name: "Primary", value: "#7a3e1d" }, …],
|
|
108
108
|
// fonts: [{ family: "Fraunces", role: "Headings", weights: [600] }, …] }
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
- The first colour is the accent. A font
|
|
112
|
-
- `null` for a space the tenant does not have. The studio half gets the same
|
|
111
|
+
- The first colour is the accent. A font’s `role` is what it is for, in the person’s words.
|
|
112
|
+
- It returns `null` for a space the tenant does not have. The studio half gets the same from
|
|
113
113
|
`studio.useSpace().brand`.
|
|
114
114
|
|
|
115
115
|
## The search index
|
|
116
116
|
|
|
117
|
-
Every agent step can search the space with `project_search`. It finds Knowledge
|
|
118
|
-
people and by `server.spaceData
|
|
117
|
+
Every agent step can search the space with `project_search`. It finds Knowledge, written by
|
|
118
|
+
people and by `server.spaceData`, and the texts plugins put in themselves, outside Knowledge:
|
|
119
119
|
|
|
120
120
|
```ts
|
|
121
121
|
await server.index.put({
|
|
@@ -131,21 +131,23 @@ await server.index.remove(space.id); // every text of the plugin in the space
|
|
|
131
131
|
```
|
|
132
132
|
|
|
133
133
|
- Putting a key again replaces what it held.
|
|
134
|
-
- A text is cut into passages. Its title is searched with it, and a hit is
|
|
135
|
-
search under Knowledge shows hits as a step gets them.
|
|
136
|
-
- The index searches by words and by trigrams (codes, parts of compounds)
|
|
137
|
-
set up, also by meaning. A classifier then judges each candidate.
|
|
138
|
-
- Such a text has no
|
|
134
|
+
- A text is cut into passages. Its title is searched with it, and a hit is named by it. The test
|
|
135
|
+
search under Knowledge (“Try a search…”) shows hits as a step gets them.
|
|
136
|
+
- The index searches by words and by trigrams (codes, parts of compounds). With an embedding
|
|
137
|
+
model set up, it also searches by meaning. A classifier then judges each candidate.
|
|
138
|
+
- Such a text has no categories, so a search with a filter leaves it out. Write Knowledge with
|
|
139
139
|
`server.spaceData` when it should be filtered.
|
|
140
|
-
- A step gets `project_search` as soon as the space has Knowledge or a plugin
|
|
141
|
-
- A tenant without the plugin does not find its texts. They
|
|
142
|
-
deleted.
|
|
140
|
+
- A step gets `project_search` as soon as the space has Knowledge or a plugin’s text.
|
|
141
|
+
- A tenant without the plugin does not find its texts. They are deleted with the space.
|
|
143
142
|
|
|
144
143
|
## Tools of the space assistant
|
|
145
144
|
|
|
146
|
-
The studio
|
|
147
|
-
and may
|
|
148
|
-
it tools:
|
|
145
|
+
The studio’s assistant, Goose, stands on every page of the studio except the editor. Where a
|
|
146
|
+
space is open and the person may change it, the assistant fills the space in from what the person
|
|
147
|
+
says, a website or files. A plugin gives it tools:
|
|
148
|
+
|
|
149
|
+
> Goose is still being tried out and doesn’t show in every studio yet. Where it doesn’t, nobody
|
|
150
|
+
> sees the tools, cards and page hooks below.
|
|
149
151
|
|
|
150
152
|
```ts
|
|
151
153
|
server.registerAssistantTool({
|
|
@@ -169,9 +171,9 @@ server.registerAssistantTool({
|
|
|
169
171
|
| `emit(message)` | The line the chat shows while the assistant works |
|
|
170
172
|
| `changed()` | The tool changed what the space page shows: the page draws it again |
|
|
171
173
|
|
|
172
|
-
- The model sees the tool as `<plugin>_<name>`, beside the assistant
|
|
173
|
-
- The assistant
|
|
174
|
-
message needs in the plugin
|
|
174
|
+
- The model sees the tool as `<plugin>_<name>`, beside the assistant’s own tools.
|
|
175
|
+
- The assistant doesn’t keep a tool’s result from one message to the next. Keep what a later
|
|
176
|
+
message needs in the plugin’s tables.
|
|
175
177
|
|
|
176
178
|
### A card in the chat
|
|
177
179
|
|
|
@@ -193,8 +195,8 @@ studio.registerAssistantCard({
|
|
|
193
195
|
});
|
|
194
196
|
```
|
|
195
197
|
|
|
196
|
-
- `tool` is the name the server half registered, without the plugin
|
|
197
|
-
- The card stands below the assistant
|
|
198
|
+
- `tool` is the name the server half registered, without the plugin’s prefix.
|
|
199
|
+
- The card stands below the assistant’s answer. Without a card for the tool, nothing shows.
|
|
198
200
|
- `data` is what `execute` returned, sent as it is: keep it small.
|
|
199
201
|
- `send(message)` sends a message to the assistant as if the person typed it.
|
|
200
202
|
|
|
@@ -203,11 +205,11 @@ studio.registerAssistantCard({
|
|
|
203
205
|
`space.created`, `space.updated`, `space.deleted`, `space.file.ready` and `space.file.removed`
|
|
204
206
|
say what changed. See [Events](./events.md).
|
|
205
207
|
|
|
206
|
-
## The assistant on the plugin
|
|
208
|
+
## The assistant on the plugin’s own page
|
|
207
209
|
|
|
208
|
-
The assistant stands on the plugin
|
|
210
|
+
The assistant stands on the plugin’s pages too, as on every page of the studio. A page tells it
|
|
209
211
|
what to say there, and what it shows; the assistant is told what the page holds and uses the
|
|
210
|
-
plugin
|
|
212
|
+
plugin’s assistant tools first.
|
|
211
213
|
|
|
212
214
|
```tsx
|
|
213
215
|
const Assistant = studio.Assistant;
|
|
@@ -231,16 +233,19 @@ server.registerAssistantContext({
|
|
|
231
233
|
```
|
|
232
234
|
|
|
233
235
|
- `studio.Assistant` draws nothing: place it once, anywhere in the page. `title` and `hello`
|
|
234
|
-
greet before the first message
|
|
235
|
-
at once (its `message`, or the label)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
236
|
+
greet the person before the first message, and up to three `suggestions` stand under them. A
|
|
237
|
+
click sends a suggestion at once (its `message`, or the label). With `fill: true` it goes into
|
|
238
|
+
the field instead, for the person to finish.
|
|
239
|
+
- `block` is called once per message, and only when the person writes from the plugin’s page. A
|
|
240
|
+
block is cut at 8,000 characters. One that throws is logged and left out.
|
|
241
|
+
- Where the person may not change the space, the assistant gets neither the space’s tools nor
|
|
242
|
+
the plugins’. That is a space published from engenty wizards on a computer, or a person who
|
|
243
|
+
may not build here.
|
|
239
244
|
|
|
240
245
|
### What the page shows
|
|
241
246
|
|
|
242
247
|
`studio.useAssistantPage` tells the assistant what the person sees: an open item, a selection,
|
|
243
|
-
a line on what the page holds, its fields. It
|
|
248
|
+
a line on what the page holds, its fields. It is sent with every message, beside the page’s
|
|
244
249
|
address and the trail of the top bar.
|
|
245
250
|
|
|
246
251
|
```tsx
|
|
@@ -253,7 +258,7 @@ studio.useAssistantPage({
|
|
|
253
258
|
});
|
|
254
259
|
```
|
|
255
260
|
|
|
256
|
-
- `open` is `{ kind, id?, label }
|
|
261
|
+
- `open` is `{ kind, id?, label }`, `selection` holds the ids of what the person picked, and
|
|
257
262
|
`fields` is `{ id, label, value }[]`.
|
|
258
263
|
- It takes the words of `studio.Assistant` too (`title`, `hello`, `placeholder`, `suggestions`,
|
|
259
264
|
`onChanged`): one call can do both.
|
|
@@ -263,8 +268,9 @@ studio.useAssistantPage({
|
|
|
263
268
|
|
|
264
269
|
`studio.useAssistantTool` gives the assistant a tool that runs in the browser while the page is
|
|
265
270
|
shown: it filters a list, opens an item, picks a tab. The model sees it as `<plugin>_<name>`
|
|
266
|
-
(a `-` in the plugin
|
|
267
|
-
learns.
|
|
271
|
+
(a `-` in the plugin’s id becomes `_`). `run` gets the arguments and returns what the assistant
|
|
272
|
+
learns. Such a tool changes what the page shows and never saves: saving stays with the server
|
|
273
|
+
half’s tools.
|
|
268
274
|
|
|
269
275
|
```tsx
|
|
270
276
|
studio.useAssistantTool(
|
|
@@ -286,6 +292,6 @@ studio.useAssistantTool(
|
|
|
286
292
|
);
|
|
287
293
|
```
|
|
288
294
|
|
|
289
|
-
Besides a page
|
|
295
|
+
Besides a page’s tools, the assistant can open a studio page, point at an element, read what is
|
|
290
296
|
on the screen, fill a field and scroll. It finds elements by their headings, labels and
|
|
291
|
-
buttons
|
|
297
|
+
buttons. `data-assist="<id>"` on an element names it for the assistant.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Starters
|
|
3
|
-
description: Wizards a plugin brings as templates
|
|
4
|
-
version: 0.
|
|
3
|
+
description: Wizards a plugin brings as templates – how to register one, where it shows, and what a wizard made from it gets.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
A starter is a wizard a plugin brings as a template.
|
|
8
|
-
wherever a wizard is made
|
|
7
|
+
A starter is a wizard a plugin brings as a template. For the tenants that have the plugin, it
|
|
8
|
+
stands beside the marketplace’s templates wherever a wizard is made.
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
11
|
import { readFileSync } from "node:fs";
|
|
@@ -15,7 +15,7 @@ const read = (path: string) => readFileSync(wizards.resolvePath(path), "utf8");
|
|
|
15
15
|
server.registerStarter({
|
|
16
16
|
id: "follow-up",
|
|
17
17
|
title: "Follow up a contact",
|
|
18
|
-
description: "Looks the person up and drafts a follow-up
|
|
18
|
+
description: "Looks the person up and drafts a follow-up email.",
|
|
19
19
|
language: "en",
|
|
20
20
|
definition: JSON.parse(read("starters/follow-up.json")),
|
|
21
21
|
files: { "widget/card.html": read("starters/card.html") },
|
|
@@ -29,13 +29,13 @@ server.registerStarter({
|
|
|
29
29
|
| `description` | What it makes, in one or two sentences. Shown under the title |
|
|
30
30
|
| `language` | `"de"` or `"en"`, the language its texts are in. Default: `"en"` |
|
|
31
31
|
| `definition` | A complete wizard definition: the JSON the studio keeps and `get_authoring_guide` describes |
|
|
32
|
-
| `files` | Files of the wizard
|
|
32
|
+
| `files` | Files of the wizard’s workspace by path: widgets, sample data. A string is written as UTF-8, a `Uint8Array` as it is |
|
|
33
33
|
|
|
34
34
|
## Checked when it is registered
|
|
35
35
|
|
|
36
|
-
The definition is read as a wizard when `registerStarter` is called. A starter that is
|
|
37
|
-
an id that is not allowed and an id registered twice throw, and the plugin does
|
|
38
|
-
error names the starter:
|
|
36
|
+
The definition is read as a wizard when `registerStarter` is called. A starter that is not a
|
|
37
|
+
valid wizard, an id that is not allowed and an id registered twice all throw, and the plugin does
|
|
38
|
+
not load. The error names the starter:
|
|
39
39
|
|
|
40
40
|
```
|
|
41
41
|
Starter "follow-up": steps.2.fields: …
|
|
@@ -43,23 +43,28 @@ Starter "follow-up": steps.2.fields: …
|
|
|
43
43
|
|
|
44
44
|
## Where it shows
|
|
45
45
|
|
|
46
|
-
The starter is known as `<plugin id>.<starter id>`: `contacts.follow-up`. A marketplace entry
|
|
47
|
-
has no dot, so the two never
|
|
46
|
+
The starter is known as `<plugin id>.<starter id>`: `contacts.follow-up`. A marketplace entry’s id
|
|
47
|
+
has no dot, so the two never clash.
|
|
48
48
|
|
|
49
49
|
| Where | |
|
|
50
50
|
|---|---|
|
|
51
|
-
| New wizard in the studio | First among the templates,
|
|
51
|
+
| New wizard in the studio | First among the gallery’s templates, and under “Similar wizards” when the wish someone types comes close to it. Its card shows the plugin’s name. It cannot be starred: it is always there, also without a connection |
|
|
52
52
|
| `GET /api/studio/marketplace` | First on the first page, with `plugin: { id, name }` |
|
|
53
53
|
| MCP `list_starters`, `get_starter`, `create_wizard` | Listed first with `plugin`; `starterId` takes its id |
|
|
54
54
|
| `GET /api/v1/templates`, for programs with a key | First, with `plugin`; `POST /api/v1/wizards` takes its id as `starterId` |
|
|
55
55
|
|
|
56
56
|
Only the tenants that have the plugin see it, by the same rule as its tools
|
|
57
|
-
([Which tenant has a plugin](./shipping.md#which-tenant-has-a-plugin)).
|
|
58
|
-
and the plugin
|
|
57
|
+
([Which tenant has a plugin](./shipping.md#which-tenant-has-a-plugin)). A search finds it by its
|
|
58
|
+
title, its description and the plugin’s name.
|
|
59
|
+
|
|
60
|
+
A marketplace entry can stand for a plugin’s starter. Where the tenant has that plugin, the
|
|
61
|
+
entry is left out and the plugin’s own starter is listed. Where it doesn’t, the entry is marked
|
|
62
|
+
Pro with the plugins it needs, and a wizard cannot be made from it.
|
|
59
63
|
|
|
60
64
|
## A wizard made from it
|
|
61
65
|
|
|
62
|
-
- gets a copy of the definition and the files
|
|
63
|
-
- keeps the starter
|
|
64
|
-
the plugin
|
|
66
|
+
- gets a copy of the definition and the files. Later changes to the starter do not reach it.
|
|
67
|
+
- keeps the starter’s id in `starter`. `starterRevision` stays empty: the starter changes with
|
|
68
|
+
the plugin’s version, not with a revision of its own.
|
|
69
|
+
- is written in the starter’s `language`, whatever language the person asked for.
|
|
65
70
|
- is not counted at the marketplace.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: The studio half
|
|
3
|
-
description: Pages, icons in the app bar, sections of the settings and of the space page
|
|
4
|
-
version: 0.
|
|
3
|
+
description: Pages, icons in the app bar, sections of the settings and of the space page – written in React, built once, drawn inside the studio.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
The studio half is `ui/plugin.tsx`. Its default export is a function; the studio calls it after
|
|
@@ -84,16 +84,19 @@ export default defineStudioPlugin((studio) => {
|
|
|
84
84
|
|
|
85
85
|
| Call | Adds |
|
|
86
86
|
|---|---|
|
|
87
|
-
| `studio.registerPage({ path, component, wide? })` | A page of the studio at `/studio<path>`, inside the studio
|
|
87
|
+
| `studio.registerPage({ path, component, wide? })` | A page of the studio at `/studio<path>`, inside the studio’s frame. `path` takes `:name` parts. `wide`: the page lays out its own columns and takes the screen’s width |
|
|
88
88
|
| `studio.registerNav({ to, label, icon })` | An icon in the app bar that opens a page |
|
|
89
89
|
| `studio.registerSettingsSection({ id, label, icon, component, menu? })` | A section of the settings at `/studio/settings/<id>`. `menu`: the user menu links to it directly |
|
|
90
|
-
| `studio.registerSpaceSection({ id, group?, label, hint?, component })` | A section of a part of the space page at `/studio/space/<group>#<id>`, below the part
|
|
91
|
-
| `studio.
|
|
92
|
-
| `studio.
|
|
93
|
-
| `studio.
|
|
90
|
+
| `studio.registerSpaceSection({ id, group?, label, hint?, component })` | A section of a part of the space page at `/studio/space/<group>#<id>`, below the part’s own. See [The space](#the-space) |
|
|
91
|
+
| `studio.registerSpacePart({ id, label, icon, after?, component })` | A part of the space page of the plugin’s own, at `/studio/space/<id>`. See [A part of the plugin’s own](#a-part-of-the-plugins-own) |
|
|
92
|
+
| `studio.registerShareSection({ runner, component })` | A runner’s own settings for a wizard (a keyword), under the share dialog’s gear once the runner is on and set up. See [Runners](./runners.md#the-runners-part-of-the-share-dialog) |
|
|
93
|
+
| `studio.registerShareSetup({ runner, title, component, notice? })` | What “Set up” in the runner’s row opens: a view inside the share dialog, with its buttons at the dialog’s foot, and a banner of the runner’s news. See [Runners](./runners.md#setting-up-inside-the-dialog) |
|
|
94
|
+
| `studio.registerAssistantCard({ tool, component })` | A card in the assistant’s chat for what a tool of the server half returned. See [The space](./space.md#a-card-in-the-chat) |
|
|
94
95
|
|
|
95
|
-
- The studio
|
|
96
|
+
- The studio’s own addresses are taken: `/new`, `/edit`, `/settings`, `/space`, `/setup`,
|
|
96
97
|
`/sign-in`.
|
|
98
|
+
- The settings’ own sections are taken as ids: `account`, `team`, `connectors`, `models`,
|
|
99
|
+
`integrate` and `plugins`.
|
|
97
100
|
- `label` is a function, since the language can change while the studio is open.
|
|
98
101
|
- `icon` is a component that takes `className`: any icon of `lucide-react`.
|
|
99
102
|
|
|
@@ -125,11 +128,11 @@ space page, behind the house icon (Space) in the app bar, shows them in four par
|
|
|
125
128
|
| Part | `group` | Holds |
|
|
126
129
|
|---|---|---|
|
|
127
130
|
| Info & brand | `info` | Basics, Facts, Logos, Colours, Brand assets |
|
|
128
|
-
| Knowledge | `knowledge` | Documents, pages, tables and files with their
|
|
131
|
+
| Knowledge | `knowledge` | Documents, pages, tables and files with their categories: what every AI step looks things up in |
|
|
129
132
|
| Data | `data` | What the wizards keep |
|
|
130
133
|
| Results | `results` | The runs that reached their result |
|
|
131
134
|
|
|
132
|
-
A plugin adds a section to one of them, below the part
|
|
135
|
+
A plugin adds a section to one of them, below the part’s own:
|
|
133
136
|
|
|
134
137
|
```tsx
|
|
135
138
|
function ContactsOfSpace() {
|
|
@@ -152,26 +155,27 @@ studio.registerSpaceSection({
|
|
|
152
155
|
```
|
|
153
156
|
|
|
154
157
|
- `group` is the part; without one the section stands under Knowledge.
|
|
155
|
-
- The studio draws the heading and the hint above the section, as it does for the space
|
|
156
|
-
and lists the section in the part
|
|
158
|
+
- The studio draws the heading and the hint above the section, as it does for the space’s own,
|
|
159
|
+
and lists the section in the part’s menu under the plugin’s name. The component draws the
|
|
157
160
|
rest, usually a `Card`.
|
|
158
|
-
- `id` is the section
|
|
161
|
+
- `id` is the section’s anchor: `/studio/space/data#contacts` opens the page there, and so does
|
|
159
162
|
`/studio/space#contacts`. In Knowledge a section is a page of its own:
|
|
160
163
|
`/studio/space/knowledge?show=s:<id>`, where `#<id>` leads too. Ids are unique on the whole
|
|
161
|
-
page; the space
|
|
164
|
+
page; the space’s own are taken: `base`, `facts`, `logos`, `colors`, `typography`, `assets`,
|
|
162
165
|
`documents`.
|
|
163
166
|
- `studio.useSpace()` is a hook: `{ id, name, readOnly, brand }`, or `null` while there is none.
|
|
164
167
|
A component that calls it draws again when the person picks another space, or changes its
|
|
165
|
-
brand. `readOnly`: the space
|
|
166
|
-
|
|
167
|
-
(`{ name, value }`, the first is the accent) and `fonts`
|
|
168
|
+
brand. `readOnly`: the space is edited in engenty wizards on a computer and only shown here,
|
|
169
|
+
or nothing is built on this runtime. Show it, but change nothing. `brand` is what Info & brand
|
|
170
|
+
holds of the look: `name`, `colors` (`{ name, value }`, the first is the accent) and `fonts`
|
|
171
|
+
(`{ family, role, weights }`).
|
|
168
172
|
- Every wizard belongs to a space: a [run event](./events.md) names it as
|
|
169
|
-
`wizard.projectId`. Keep it with what the plugin stores to show a space
|
|
173
|
+
`wizard.projectId`. Keep it with what the plugin stores to show a space’s part of it.
|
|
170
174
|
|
|
171
|
-
### A part of the plugin
|
|
175
|
+
### A part of the plugin’s own
|
|
172
176
|
|
|
173
177
|
A plugin whose subject is as big as one of the parts adds a part of its own: an entry in the
|
|
174
|
-
parts
|
|
178
|
+
parts’ menu, with a page at `/studio/space/<id>` that the plugin draws whole. The part’s menu
|
|
175
179
|
lists what the page holds; `studio.useSpaceMenu` fills it while the page is drawn.
|
|
176
180
|
|
|
177
181
|
```tsx
|
|
@@ -195,16 +199,16 @@ studio.registerSpacePart({
|
|
|
195
199
|
});
|
|
196
200
|
```
|
|
197
201
|
|
|
198
|
-
- `id` is the address: `/studio/space/library`. The parts
|
|
202
|
+
- `id` is the address: `/studio/space/library`. The parts’ own (`info`, `knowledge`, `data`,
|
|
199
203
|
`results`) are taken.
|
|
200
204
|
- `after` is the part it follows in the menu: `info`, `knowledge` or `data` (default).
|
|
201
205
|
- Each entry of `useSpaceMenu` jumps to the element with its `id` in what the part draws, and
|
|
202
|
-
the menu marks the one in view. `Anchor` and `Section` draw them as the space
|
|
203
|
-
- The component is drawn again for another space: keep the space
|
|
206
|
+
the menu marks the one in view. `Anchor` and `Section` draw them as the space’s own parts do.
|
|
207
|
+
- The component is drawn again for another space: keep the space’s data under its id.
|
|
204
208
|
|
|
205
209
|
## Words in two languages
|
|
206
210
|
|
|
207
|
-
The studio speaks German and English. `studio.i18n.register` takes the plugin
|
|
211
|
+
The studio speaks German and English. `studio.i18n.register` takes the plugin’s words and gives
|
|
208
212
|
the function that reads them in the language in effect:
|
|
209
213
|
|
|
210
214
|
```ts
|
|
@@ -216,12 +220,12 @@ const t = studio.i18n.register({
|
|
|
216
220
|
t("count", { n: 12 });
|
|
217
221
|
```
|
|
218
222
|
|
|
219
|
-
- `de` is the source: a key missing in `en` shows the German.
|
|
223
|
+
- `de` is the source: a key missing in `en` shows the German, so give every key in both.
|
|
220
224
|
- `{name}` in a text is filled from the second argument.
|
|
221
225
|
- `studio.i18n.lang()` is `"de"` or `"en"`, for dates and numbers:
|
|
222
226
|
`new Date(at).toLocaleString(studio.i18n.lang())`.
|
|
223
227
|
|
|
224
|
-
## The plugin
|
|
228
|
+
## The plugin’s own routes
|
|
225
229
|
|
|
226
230
|
`studio.api` calls the routes the server half registered, signed in as the person:
|
|
227
231
|
|
|
@@ -251,8 +255,8 @@ route.
|
|
|
251
255
|
|
|
252
256
|
## Where the page stands
|
|
253
257
|
|
|
254
|
-
The top bar shows a trail after the space
|
|
255
|
-
while the page is shown, in place of a heading of the page
|
|
258
|
+
The top bar shows a trail after the space’s name. `studio.useCrumbs` is a hook that sets it
|
|
259
|
+
while the page is shown, in place of a heading of the page’s own:
|
|
256
260
|
|
|
257
261
|
```tsx
|
|
258
262
|
studio.useCrumbs([{ label: t("title"), to: "/contacts" }, { label: person.name ?? person.email }]);
|
|
@@ -261,16 +265,54 @@ studio.useCrumbs([{ label: t("title"), to: "/contacts" }, { label: person.name ?
|
|
|
261
265
|
- Each step is `{ label, to? }`; the last one is the page itself. A phone does not show the trail.
|
|
262
266
|
- The assistant names the page by its trail.
|
|
263
267
|
|
|
268
|
+
## A page with a menu
|
|
269
|
+
|
|
270
|
+
A page with parts of its own puts its menu where the studio’s own pages put theirs. `MenuPage`
|
|
271
|
+
from `@engenty-wizards/web/ui` draws the menu in the studio’s sidebar while that is open, and at
|
|
272
|
+
the page’s left otherwise, so there is only ever one menu at the left. `PageMenu` draws the menu
|
|
273
|
+
as the settings do: a list with one level below it, and tabs on a phone.
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import { MenuPage, PageMenu } from "@engenty-wizards/web/ui";
|
|
277
|
+
import { useParams } from "react-router";
|
|
278
|
+
|
|
279
|
+
function ContactsPage() {
|
|
280
|
+
const { tab = "all" } = useParams();
|
|
281
|
+
return (
|
|
282
|
+
<MenuPage
|
|
283
|
+
menu={
|
|
284
|
+
<PageMenu
|
|
285
|
+
title={t("title")}
|
|
286
|
+
current={tab}
|
|
287
|
+
entries={[
|
|
288
|
+
{ id: "all", label: t("all"), to: "/contacts/all" },
|
|
289
|
+
{ id: "new", label: t("new"), to: "/contacts/new" },
|
|
290
|
+
]}
|
|
291
|
+
/>
|
|
292
|
+
}
|
|
293
|
+
>
|
|
294
|
+
<ContactList tab={tab} />
|
|
295
|
+
</MenuPage>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
- An entry is `{ id, label, icon?, to, entries? }`; `entries` is the level below.
|
|
301
|
+
- `current` is the id of the entry shown, at either level.
|
|
302
|
+
|
|
264
303
|
## The assistant
|
|
265
304
|
|
|
266
|
-
The studio
|
|
305
|
+
The studio’s assistant stands on a plugin’s pages too. `studio.Assistant`,
|
|
267
306
|
`studio.useAssistantPage` and `studio.useAssistantTool` tell it what to say there, what the page
|
|
268
307
|
shows and what it may do in it. See [The space](./space.md#the-assistant-on-the-plugins-own-page).
|
|
269
308
|
|
|
309
|
+
For now the studio shows its assistant only where it is switched on, and it is off by default.
|
|
310
|
+
While it is off, these calls do no harm and nobody sees what they say.
|
|
311
|
+
|
|
270
312
|
## Build it
|
|
271
313
|
|
|
272
314
|
The studio half is built to two files, `dist/client.js` and `dist/client.css`. The build needs
|
|
273
|
-
a checkout of the repository, since it uses the studio
|
|
315
|
+
a checkout of the repository, since it uses the studio’s own tools:
|
|
274
316
|
|
|
275
317
|
```bash
|
|
276
318
|
node scripts/build-plugin.mjs <plugin folder>
|
|
@@ -280,7 +322,7 @@ node scripts/build-plugin.mjs <plugin folder>
|
|
|
280
322
|
node scripts/build-plugin.mjs <plugin folder> --watch
|
|
281
323
|
```
|
|
282
324
|
|
|
283
|
-
The plugin
|
|
325
|
+
The plugin’s folder may be anywhere, also outside the checkout. With `--watch` the files are
|
|
284
326
|
built again on every save, and an open studio takes them in place.
|
|
285
327
|
|
|
286
328
|
Ship `dist/` with the plugin: an install without a checkout cannot build it.
|
|
@@ -296,11 +338,11 @@ there is one React and one router on the page:
|
|
|
296
338
|
| `react-dom` | `createPortal`, `flushSync` |
|
|
297
339
|
| `react-router` | `Link`, `NavLink`, `Navigate`, `useNavigate`, `useParams`, `useLocation`, `useSearchParams` |
|
|
298
340
|
| `@tanstack/react-query` | `useQuery`, `useMutation`, `useQueryClient` |
|
|
299
|
-
| `@engenty-wizards/web/ui` | The studio
|
|
341
|
+
| `@engenty-wizards/web/ui` | The studio’s components, see [Styles and components](./styling.md) |
|
|
300
342
|
| `@engenty-wizards/plugin-sdk/studio` | `defineStudioPlugin` and the types |
|
|
301
343
|
|
|
302
|
-
Everything else a plugin imports is bundled into `client.js`. A package the plugin
|
|
303
|
-
does not have, such as `lucide-react`, comes from the studio
|
|
344
|
+
Everything else a plugin imports is bundled into `client.js`. A package the plugin’s folder
|
|
345
|
+
does not have, such as `lucide-react`, comes from the studio’s.
|
|
304
346
|
|
|
305
347
|
## Undo on reload
|
|
306
348
|
|
|
@@ -314,7 +356,8 @@ studio.onUnload(() => clearInterval(timer));
|
|
|
314
356
|
|
|
315
357
|
## When it fails
|
|
316
358
|
|
|
317
|
-
- A studio half that throws while it loads registers nothing. Settings → Plugins says
|
|
318
|
-
studio
|
|
319
|
-
|
|
359
|
+
- A studio half that throws while it loads registers nothing. Settings → Plugins says “The
|
|
360
|
+
studio part didn’t load. Check the plugin and reload” with the reason. The server half keeps
|
|
361
|
+
working.
|
|
362
|
+
- A page or section that throws while it draws shows “This part of a plugin crashed.” in its
|
|
320
363
|
place. The rest of the studio stays up.
|