wizards 0.5.0 → 0.5.2

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.
Files changed (160) hide show
  1. package/README.md +45 -42
  2. package/apps/runtime/dist/agents/studio-assistant.js +3 -3
  3. package/apps/runtime/dist/app.js +7 -4
  4. package/apps/runtime/dist/auth/index.js +2 -2
  5. package/apps/runtime/dist/authoring/guide.js +1 -1
  6. package/apps/runtime/dist/cli/account.js +31 -28
  7. package/apps/runtime/dist/cli/autostart.js +5 -3
  8. package/apps/runtime/dist/cli/clients.js +1 -1
  9. package/apps/runtime/dist/cli/connect.js +24 -24
  10. package/apps/runtime/dist/cli/features.js +6 -6
  11. package/apps/runtime/dist/cli/main.js +51 -39
  12. package/apps/runtime/dist/cli/mcp.js +5 -4
  13. package/apps/runtime/dist/cli/menu.js +32 -30
  14. package/apps/runtime/dist/cli/report.js +7 -9
  15. package/apps/runtime/dist/cli/setup.js +42 -38
  16. package/apps/runtime/dist/cli/start.js +16 -15
  17. package/apps/runtime/dist/cli/status.js +20 -20
  18. package/apps/runtime/dist/cli/ui.js +9 -2
  19. package/apps/runtime/dist/cli/update.js +6 -6
  20. package/apps/runtime/dist/cli/validate.js +1 -1
  21. package/apps/runtime/dist/connectors/external.js +3 -2
  22. package/apps/runtime/dist/connectors/index.js +5 -5
  23. package/apps/runtime/dist/connectors/plugin-connections.js +2 -2
  24. package/apps/runtime/dist/connectors/via-account.js +5 -5
  25. package/apps/runtime/dist/db/control-schema.js +14 -0
  26. package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
  27. package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
  28. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +7 -0
  29. package/apps/runtime/dist/docs/dev/index.md +16 -14
  30. package/apps/runtime/dist/docs/dev/plugins/connections.md +27 -24
  31. package/apps/runtime/dist/docs/dev/plugins/events.md +19 -17
  32. package/apps/runtime/dist/docs/dev/plugins/examples.md +13 -12
  33. package/apps/runtime/dist/docs/dev/plugins/index.md +29 -24
  34. package/apps/runtime/dist/docs/dev/plugins/layout.md +20 -19
  35. package/apps/runtime/dist/docs/dev/plugins/quick-start.md +16 -15
  36. package/apps/runtime/dist/docs/dev/plugins/reference.md +52 -40
  37. package/apps/runtime/dist/docs/dev/plugins/reloading.md +24 -23
  38. package/apps/runtime/dist/docs/dev/plugins/routes.md +26 -22
  39. package/apps/runtime/dist/docs/dev/plugins/runners.md +49 -44
  40. package/apps/runtime/dist/docs/dev/plugins/server.md +95 -43
  41. package/apps/runtime/dist/docs/dev/plugins/shipping.md +19 -16
  42. package/apps/runtime/dist/docs/dev/plugins/space.md +75 -69
  43. package/apps/runtime/dist/docs/dev/plugins/starters.md +22 -17
  44. package/apps/runtime/dist/docs/dev/plugins/studio.md +80 -37
  45. package/apps/runtime/dist/docs/dev/plugins/styling.md +44 -41
  46. package/apps/runtime/dist/docs/dev/plugins/tables.md +11 -11
  47. package/apps/runtime/dist/docs/dev/plugins/tools.md +26 -25
  48. package/apps/runtime/dist/docs/dev/wizard-format.md +35 -23
  49. package/apps/runtime/dist/docs/user/ai-apps.md +46 -43
  50. package/apps/runtime/dist/docs/user/assistant.md +41 -36
  51. package/apps/runtime/dist/docs/user/build-a-wizard.md +64 -39
  52. package/apps/runtime/dist/docs/user/command-line.md +47 -44
  53. package/apps/runtime/dist/docs/user/connectors.md +40 -35
  54. package/apps/runtime/dist/docs/user/create-account.md +27 -22
  55. package/apps/runtime/dist/docs/user/data.md +29 -29
  56. package/apps/runtime/dist/docs/user/first-start.md +26 -28
  57. package/apps/runtime/dist/docs/user/index.md +16 -17
  58. package/apps/runtime/dist/docs/user/install.md +28 -27
  59. package/apps/runtime/dist/docs/user/local-only.md +21 -17
  60. package/apps/runtime/dist/docs/user/models.md +92 -84
  61. package/apps/runtime/dist/docs/user/plugins.md +28 -23
  62. package/apps/runtime/dist/docs/user/run.md +51 -50
  63. package/apps/runtime/dist/docs/user/server.md +9 -9
  64. package/apps/runtime/dist/docs/user/space.md +87 -65
  65. package/apps/runtime/dist/docs/user/steps.md +73 -69
  66. package/apps/runtime/dist/docs/user/test-and-share.md +127 -105
  67. package/apps/runtime/dist/docs/user/troubleshooting.md +40 -38
  68. package/apps/runtime/dist/docs/user/wordpress.md +62 -54
  69. package/apps/runtime/dist/documents/parse.js +2 -2
  70. package/apps/runtime/dist/engenty/shims/web-ingest.js +17 -1
  71. package/apps/runtime/dist/engine/input.js +4 -4
  72. package/apps/runtime/dist/engine/push.js +2 -2
  73. package/apps/runtime/dist/engine/runner.js +8 -8
  74. package/apps/runtime/dist/engine/steps.js +2 -2
  75. package/apps/runtime/dist/engine/surface.js +1 -1
  76. package/apps/runtime/dist/film/step.js +3 -3
  77. package/apps/runtime/dist/harness/claude.js +1 -1
  78. package/apps/runtime/dist/harness/codex.js +1 -1
  79. package/apps/runtime/dist/harness/model.js +2 -2
  80. package/apps/runtime/dist/harness/terminal.js +3 -3
  81. package/apps/runtime/dist/mcp/handler.js +2 -2
  82. package/apps/runtime/dist/mcp/tools.js +9 -9
  83. package/apps/runtime/dist/models.js +15 -15
  84. package/apps/runtime/dist/plugins/claims.js +56 -0
  85. package/apps/runtime/dist/plugins/loader.js +2 -0
  86. package/apps/runtime/dist/plugins/public.js +2 -3
  87. package/apps/runtime/dist/plugins/runs.js +13 -8
  88. package/apps/runtime/dist/render/chromium.js +24 -11
  89. package/apps/runtime/dist/routes/api.js +15 -9
  90. package/apps/runtime/dist/routes/debug.js +1 -1
  91. package/apps/runtime/dist/routes/delivery.js +46 -0
  92. package/apps/runtime/dist/routes/lang.js +7 -0
  93. package/apps/runtime/dist/routes/marketplace.js +2 -1
  94. package/apps/runtime/dist/routes/plugin-public.js +2 -1
  95. package/apps/runtime/dist/routes/plugins.js +13 -14
  96. package/apps/runtime/dist/routes/runs.js +59 -49
  97. package/apps/runtime/dist/routes/studio.js +53 -23
  98. package/apps/runtime/dist/services/access.js +3 -3
  99. package/apps/runtime/dist/services/assistant-chats.js +1 -1
  100. package/apps/runtime/dist/services/brand.js +2 -2
  101. package/apps/runtime/dist/services/cloud.js +5 -4
  102. package/apps/runtime/dist/services/errors.js +2 -1
  103. package/apps/runtime/dist/services/knowledge-model.js +2 -2
  104. package/apps/runtime/dist/services/marketplace.js +2 -2
  105. package/apps/runtime/dist/services/package-file.js +12 -9
  106. package/apps/runtime/dist/services/package.js +2 -2
  107. package/apps/runtime/dist/services/project-files.js +10 -12
  108. package/apps/runtime/dist/services/projects.js +13 -8
  109. package/apps/runtime/dist/services/runners.js +4 -3
  110. package/apps/runtime/dist/services/runs.js +3 -3
  111. package/apps/runtime/dist/services/site.js +2 -2
  112. package/apps/runtime/dist/services/space-categories.js +4 -4
  113. package/apps/runtime/dist/services/space-data.js +13 -13
  114. package/apps/runtime/dist/services/space-origin.js +1 -1
  115. package/apps/runtime/dist/services/spaces.js +7 -7
  116. package/apps/runtime/dist/services/wizards.js +5 -5
  117. package/apps/runtime/dist/tools/net-guard.js +135 -24
  118. package/apps/runtime/dist/tools/plugin.js +1 -1
  119. package/apps/runtime/dist/tools/store.js +1 -1
  120. package/apps/runtime/dist/widgets/step.js +1 -1
  121. package/apps/web/dist/assets/AboutDialog-hRgrS60N.js +1 -0
  122. package/apps/web/dist/assets/{ChangelogDialog-BXpkgatF.js → ChangelogDialog-BUSpLhC6.js} +1 -1
  123. package/apps/web/dist/assets/{ChatView-t7z44uFN.js → ChatView-DO7P5Vv_.js} +1 -1
  124. package/apps/web/dist/assets/EditorPage-BabV35Bj.js +3 -0
  125. package/apps/web/dist/assets/{FlowPreview-WpS8DCPl.js → FlowPreview-CKrwLPN0.js} +1 -1
  126. package/apps/web/dist/assets/{Harness-DL7Bse40.js → Harness-o8IIQXZp.js} +1 -1
  127. package/apps/web/dist/assets/{NewWizardChannels-Crt6PzH2.js → NewWizardChannels-DqU79Myj.js} +1 -1
  128. package/apps/web/dist/assets/{NewWizardPage-COiVmNsl.js → NewWizardPage-D1UCvmDp.js} +1 -1
  129. package/apps/web/dist/assets/{OnboardingPage-BwluEqXq.js → OnboardingPage-C70bqPnq.js} +1 -1
  130. package/apps/web/dist/assets/{ProjectPage-BIRU_AlN.js → ProjectPage-BOLvmQWZ.js} +1 -1
  131. package/apps/web/dist/assets/{PublicRunner-BxMb4gEt.js → PublicRunner-B0PGyHI9.js} +1 -1
  132. package/apps/web/dist/assets/{ReadOnly-D9r5ze5S.js → ReadOnly-B0mJBD1q.js} +1 -1
  133. package/apps/web/dist/assets/{RunDrawer-DmJl2QOJ.js → RunDrawer-BsnsIJ0Y.js} +1 -1
  134. package/apps/web/dist/assets/{RunnerView-CF_1rC-7.js → RunnerView-B56i3nKO.js} +1 -1
  135. package/apps/web/dist/assets/SettingsPage-BvfRUqb2.js +1 -0
  136. package/apps/web/dist/assets/{SetupPage-BGKtbS7j.js → SetupPage-BvAFPu1J.js} +1 -1
  137. package/apps/web/dist/assets/{SharePage-C4MqXKDA.js → SharePage-hV5pYrO2.js} +1 -1
  138. package/apps/web/dist/assets/changelog-BftXQzUA.js +1 -0
  139. package/apps/web/dist/assets/{esm-CsY8TkyE.js → esm-DfapVSy6.js} +1 -1
  140. package/apps/web/dist/assets/{index-BjQvGQp_.js → index-BuFrRzvG.js} +4 -4
  141. package/apps/web/dist/assets/{index-Bi2x2g7n.css → index-DSbQiZY8.css} +1 -1
  142. package/apps/web/dist/assets/{lock-CI6TpWL-.js → lock-B-tJwE4p.js} +1 -1
  143. package/apps/web/dist/assets/oss-credits-BJrR7BR1.js +1 -0
  144. package/apps/web/dist/assets/{phone-BrtQz-fG.js → phone-DRHxY0l_.js} +1 -1
  145. package/apps/web/dist/assets/{settings-menu-BtEKL72n.js → settings-menu-OPrJTW8a.js} +1 -1
  146. package/apps/web/dist/assets/{ui-4IaTD7LB.js → ui-DftgEA2k.js} +3 -3
  147. package/apps/web/dist/assets/{upload-CWJAtPRo.js → upload-B73coFNw.js} +1 -1
  148. package/apps/web/dist/index.html +3 -3
  149. package/apps/web/dist/mcp/flow.html +4 -4
  150. package/bin/wizards.mjs +1 -1
  151. package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +21 -2
  152. package/node_modules/@engenty-wizards/shared/dist/projects.js +1 -1
  153. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +48 -48
  154. package/node_modules/@engenty-wizards/shared/dist/run.js +48 -48
  155. package/package.json +5 -4
  156. package/apps/web/dist/assets/AboutDialog-A_ILyeue.js +0 -1
  157. package/apps/web/dist/assets/EditorPage-4qxNJgKr.js +0 -3
  158. package/apps/web/dist/assets/SettingsPage-3xSInE-A.js +0 -1
  159. package/apps/web/dist/assets/changelog-CM_GdIVI.js +0 -1
  160. package/apps/web/dist/assets/oss-credits-BQQX0kvk.js +0 -1
@@ -1,17 +1,17 @@
1
1
  ---
2
2
  title: Styles and components
3
3
  description: The studio's components, Tailwind against the studio's theme, and why a plugin's styles never leak.
4
- version: 0.3.7
4
+ version: 0.5.0
5
5
  ---
6
6
 
7
- A plugin's page should look like the studio. Two things make that easy: the studio's components
7
+ A plugin’s page should look like the studio. Two things make that easy: the studio’s components
8
8
  and its theme.
9
9
 
10
10
  ## Components
11
11
 
12
12
  `@engenty-wizards/web/ui` is what the studio itself is drawn with:
13
13
 
14
- | Component | For | Props beside the element's own |
14
+ | Component | For | Props beside the element’s own |
15
15
  |---|---|---|
16
16
  | `Button` | An action | `variant`: `primary` (default), `secondary`, `ghost`, `quiet`, `danger` · `size`: `sm`, `md`, `lg` · `busy` |
17
17
  | `IconButton` | An action that is only an icon | `label`: its name for screen readers and the tooltip |
@@ -20,26 +20,28 @@ and its theme.
20
20
  | `Segmented` | One or several of a few | `value`, `onChange`, `options: string[]`, `multi`, `disabled` (options shown but not to be picked) |
21
21
  | `Tabs` | A row of tabs; the panels are yours | `value`, `onChange`, `options: { id, label }[]`, `label` (for screen readers) |
22
22
  | `Switch` | On or off | `checked`, `onChange(checked)`, `label`, `disabled` |
23
- | `Swatch` | A colour | The native colour input's |
24
- | `Label` | A field's label | `hint`, `required` |
23
+ | `Swatch` | A colour | The native colour input’s |
24
+ | `Label` | A field’s label | `hint`, `required` |
25
25
  | `Card` | A surface | |
26
26
  | `Chip` | A state in a word | `tone`: `neutral` (default), `live`, `warn`, `ember` · `icon` (in place of the live dot) · `title` (on hover) |
27
- | `DatePicker` | A date from a month | `value` ("YYYY-MM-DD" or ""), `onChange`, `min`, `max`, `clearable` |
27
+ | `DatePicker` | A date from a month | `value` (“YYYY-MM-DD” or “”), `onChange`, `min`, `max`, `clearable` |
28
28
  | `DateRangePicker` | A day or a period in one month: the first click is the start, the second the end | `from`, `to`, `onChange({ from, to })`, `min`, `max` |
29
- | `TimePicker` | A time of day from an hour and a minute column; arrow keys on the field move it by `step` | `value` ("HH:MM" or ""), `onChange`, `step` (minutes, default 5), `compact` (narrow, no clock) |
30
- | `PageMenu` | A page's own menu: a list at the side with one level below that slides in, tabs on a phone | `title`, `entries` ({ id, label, icon?, to, entries? }), `current`, `footer` |
29
+ | `TimePicker` | A time of day from an hour and a minute column; arrow keys on the field move it by `step` | `value` (“HH:MM” or “”), `onChange`, `step` (minutes, default 5), `compact` (narrow, no clock) |
30
+ | `PageMenu` | A page’s own menu: a list at the side with one level below that slides in, tabs on a phone | `title`, `entries` ({ id, label, icon?, to, entries? }), `current`, `footer` |
31
+ | `MenuPage` | A page with a menu of its own: the menu stands at the page’s left, or in the studio’s sidebar while that is open, so there is only ever one menu at the left | `menu` (a `PageMenu`, or any), `children` (the page) |
31
32
  | `Composer` | The field a message is written in: text, dictation, files, send | `onSend(text, files)` (false keeps the draft), `placeholder`, `disabled`, `attach`, `floating` |
32
33
  | `Dialog` | A modal; on a phone it fills the screen | `open`, `onClose`, `title`, `wide` (`true`, or `"page"` for a document), `height="tall"` (for tabs, folds or lists: its height does not jump), `bare` (the children are the panel) |
33
34
  | `Spinner`, `Empty` | Loading, and nothing there yet | |
34
35
  | `LinkedText` | A sentence with its web addresses as links, named by their host | `text` |
36
+ | `QrCode` | A QR code of a text, such as a link or a `tel:` number, as the share dialog draws it | `text`, `label` (for screen readers) |
35
37
  | `cn(...)` | Joins class names, skipping what is false | |
36
- | `dateText(date, withWeekday?)` | A "YYYY-MM-DD" date in the studio's language: "Wed 14 Oct 2026" | |
38
+ | `dateText(date, withWeekday?)` | A “YYYY-MM-DD” date in the studio’s language: “Wed 14 Oct 2026” | |
37
39
  | `Anchor`, `Section` | A section of the space page and the spot the menu jumps to: the heading and its hint above the card | `id` on the anchor · `title`, `hint`, `save` (how the last save went), `action` (beside the heading), `plain` (the content draws its own cards) |
38
- | `InlineText` | Text edited where it stands, without a field's frame | `value`, `onChange`, `placeholder`, `label`, `maxLength`, `fit` (as wide as its text) |
39
- | `AddMenu` | The "Add" menu of a section's heading | `entries: { label, icon, onPick }[]` |
40
- | `AddRow` | A quiet "+ …" row at the end of a list | `label`, `onClick` |
41
- | `RuleRows`, `useRuleRows(saved)` | Rules as rows, each with its sign (bullet, do, don't, to check, important, numbered) | `rules` (what the hook gives), `placeholder`, `readOnly` |
42
- | `useAutosave(value, save)` | Saves a value a moment after it last changed; gives the state for a section's `save` | |
40
+ | `InlineText` | Text edited where it stands, without a field’s frame | `value`, `onChange`, `placeholder`, `label`, `maxLength`, `fit` (as wide as its text) |
41
+ | `AddMenu` | The “Add” menu of a section’s heading | `entries: { label, icon, onPick }[]` |
42
+ | `AddRow` | A quiet “+ …” row at the end of a list | `label`, `onClick` |
43
+ | `RuleRows`, `useRuleRows(saved)` | Rules as rows, each with its sign (bullet, do, don’t, to check, important, numbered) | `rules` (what the hook gives), `placeholder`, `readOnly` |
44
+ | `useAutosave(value, save)` | Saves a value a moment after it last changed; gives the state for a section’s `save` | |
43
45
  | `newId()` | A short id for something new | |
44
46
 
45
47
  ```tsx
@@ -57,17 +59,17 @@ import { Button, Card, Chip, Label, Input } from "@engenty-wizards/web/ui";
57
59
 
58
60
  Icons are from `lucide-react`.
59
61
 
60
- Most of these components live in the runner package (`@engenty-wizards/runner`), so a wizard's
61
- run page looks like the studio. Import them from `@engenty-wizards/web/ui` all the same: that
62
- is the import the studio shares. `@engenty-wizards/runner` is not shared and would be bundled
63
- into `client.js`.
62
+ Most of these components live in the runner package (`@engenty-wizards/runner`), so a wizard’s
63
+ run page looks like the studio. Import them from `@engenty-wizards/web/ui` all the same: that is
64
+ the import the studio shares. `@engenty-wizards/runner` is not shared, so the build would bundle
65
+ it into `client.js`.
64
66
 
65
67
  ## Tailwind
66
68
 
67
69
  A plugin writes Tailwind classes, as the studio does. The build collects the classes the
68
- plugin's files use into `dist/client.css`.
70
+ plugin’s files use into `dist/client.css`.
69
71
 
70
- The theme's names are the studio's:
72
+ The theme’s names are the studio’s:
71
73
 
72
74
  | | Names |
73
75
  |---|---|
@@ -77,33 +79,34 @@ The theme's names are the studio's:
77
79
  | The accent | `ember`, `ember-strong`, `ember-tint`; `primary`, `primary-foreground` |
78
80
  | States | `moss` and `moss-tint` (good), `amber` and `amber-tint` (attention), `rose` and `rose-tint` (danger), `cobalt` and `cobalt-tint` (information) |
79
81
  | Type | `font-sans`, `font-display` (headings), `font-mono` |
80
- | Corners | `rounded-sm` to `rounded-3xl`, from the theme's radius |
82
+ | Corners | `rounded-sm` to `rounded-3xl`, from the theme’s radius |
81
83
  | Shadows | `shadow-soft`, `shadow-elevated`, `shadow-overlay` |
82
- | Variants | `dark:` and `coarse:` (a finger, not a mouse) beside Tailwind's own |
84
+ | Variants | `dark:` and `coarse:` (a finger, not a mouse) beside Tailwind’s own |
83
85
 
84
86
  The full list is
85
87
  [packages/runner/src/theme.css](https://github.com/engenty/wizards/blob/main/packages/runner/src/theme.css):
86
- the studio and a wizard's run page share it.
88
+ the studio and a wizard’s run page share it.
87
89
 
88
90
  ## Rules
89
91
 
90
- - **Colours come from the names.** Dark is derived from the theme's values, not a fixed
91
- palette. A literal colour (`#1a1a1a`, `text-gray-700`) breaks in the other theme.
92
- - **Check both themes.** The user menu switches between light and dark.
93
- - **Touch targets.** `coarse:min-h-11` gives a control the 44 px a finger needs. The studio's
92
+ - **Colours come from the names.** The dark theme is derived from the theme’s values, not from a
93
+ fixed palette. A literal colour (`#1a1a1a`, `text-gray-700`) breaks in the other theme.
94
+ - **Check both themes.** Dark is the studio’s default. The user menu and the app bar’s own menu
95
+ switch between light, dark and the system’s.
96
+ - **Touch targets.** `coarse:min-h-11` gives a control the 44 px a finger needs. The studio’s
94
97
  components do that themselves.
95
- - **Do not style outside your own part.** It would not work anyway: see below.
98
+ - **Don’t style outside your own part.** It would not work anyway: see below.
96
99
 
97
- ## Why a plugin's styles never leak
100
+ ## Why a plugin’s styles never leak
98
101
 
99
102
  `client.css` is built so that it cannot change how the studio looks:
100
103
 
101
104
  - Every rule applies only inside what the plugin draws. The studio wraps each page, section,
102
- app bar icon, part of the share dialog and assistant card of a plugin in an element with
103
- `data-plugin="<id>"`, and every rule of `client.css` is nested below that.
104
- - The rules sit in a layer above the studio's utilities, so inside the plugin's part the
105
- plugin's stylesheet decides.
106
- - The theme is used by reference: `client.css` carries the names' uses, none of the variables
105
+ part of the space page, app bar icon, part of the share dialog and assistant card of a plugin
106
+ in an element with `data-plugin="<id>"`, and every rule of `client.css` is nested below that.
107
+ - The rules sit in a layer above the studio’s utilities, so inside the plugin’s part the
108
+ plugin’s stylesheet decides.
109
+ - The theme is used by reference: `client.css` carries the names’ uses, none of the variables
107
110
  and no resets.
108
111
 
109
112
  ## Your own CSS
@@ -114,13 +117,13 @@ A stylesheet imported in `ui/plugin.tsx` lands in `client.css` as it is:
114
117
  import "./contacts.css";
115
118
  ```
116
119
 
117
- It is not nested for you. Begin its class names with the plugin's id (`.contacts-chart`) and use
118
- the theme's variables for colours: `var(--ink-2)`, `var(--paper-2)`, `var(--ember)`.
120
+ The build doesn’t nest it for you. Begin its class names with the plugin’s id
121
+ (`.contacts-chart`) and use the theme’s variables for colours: `var(--ink-2)`, `var(--paper-2)`,
122
+ `var(--ember)`.
119
123
 
120
124
  ## The theme is a contract
121
125
 
122
- A plugin is built against the names of the theme at the time of its build. A name that is
123
- renamed or removed in a later release breaks plugins built before, without an error: the class
124
- is simply not there. Whoever changes `theme.css` treats its names as a contract for that reason.
125
- If you build against a name a release added, say in your plugin's description which release it
126
- needs.
126
+ A plugin is built against the names the theme has at the time of its build. If a later release
127
+ renames or removes a name, plugins built before break without an error: the class is simply not
128
+ there. That is why whoever changes `theme.css` treats its names as a contract. If you build
129
+ against a name a release added, say in your plugin’s description which release it needs.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Tables
3
- description: A plugin's own tables in every tenant's database — SQL files that run once, and Drizzle to read and write.
4
- version: 0.3.2
3
+ description: A plugin's own tables in every tenant's database – SQL files that run once, and Drizzle to read and write.
4
+ version: 0.5.0
5
5
  ---
6
6
 
7
- Every tenant has a database of its own (libSQL, the SQLite dialect). A plugin's tables are made
8
- in each of them, from `.sql` files the plugin brings.
7
+ Every tenant has a database of its own (libSQL, the SQLite dialect). The runtime makes a plugin’s
8
+ tables in each of them, from `.sql` files the plugin brings.
9
9
 
10
10
  ## 1. The table, as SQL
11
11
 
@@ -79,13 +79,13 @@ there is no tenant.
79
79
  | When | A database gets the files when it opens. The open ones get them when the plugin loads, also when it loads again with a new file |
80
80
  | Never back | Nothing is taken back. Unloading or removing a plugin leaves its tables and rows |
81
81
 
82
- A file that fails is logged with the plugin's id and the file's name, and the files after it,
83
- other plugins' included, wait for that database until it is mended. The tenant's database
84
- still opens.
82
+ A file that fails is logged with the plugin’s id and the file’s name. The files after it, other
83
+ plugins’ included, wait for that database until the file is fixed. The tenant’s database still
84
+ opens.
85
85
 
86
86
  ## Rules
87
87
 
88
- - **Begin table names with the plugin's id**: `contacts_person`. All plugins and the runtime
88
+ - **Begin table names with the plugin’s id**: `contacts_person`. All plugins and the runtime
89
89
  share the database. A `-` in the id becomes `_`.
90
90
  - **Never change a file that ran.** It will not run again. Add a new file:
91
91
 
@@ -93,12 +93,12 @@ still opens.
93
93
  ALTER TABLE contacts_person ADD COLUMN phone TEXT;
94
94
  ```
95
95
 
96
- - **Do not touch the runtime's own tables** in a migration. Their shape changes with releases.
96
+ - **Do not touch the runtime’s own tables** in a migration. Their shape changes with releases.
97
97
  - **Dates** are integers in milliseconds (`mode: "timestamp_ms"`); they leave a route as ISO
98
98
  strings.
99
99
 
100
- ## The runtime's own data
100
+ ## The runtime’s own data
101
101
 
102
- `getTenantDb()` reaches the whole tenant database, the runtime's tables included. They are not
102
+ `getTenantDb()` reaches the whole tenant database, the runtime’s tables included. They are not
103
103
  a public interface: a release can rename a column. A plugin that must know about runs listens
104
104
  to [run events](./events.md) and keeps what it needs in its own table.
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  title: Tools
3
- description: A tool an AI step can call — how to register it, how a wizard lists it, and what the model sees.
4
- version: 0.3.2
3
+ description: A tool an AI step can call – how to register it, how a wizard lists it, and what the model sees.
4
+ version: 0.5.0
5
5
  ---
6
6
 
7
7
  A tool is a function an AI step may call while it works. The model decides when, from the
8
- tool's description.
8
+ tool’s description.
9
9
 
10
10
  ```ts
11
11
  server.registerTool({
12
12
  name: "lookup",
13
13
  title: "Contacts",
14
14
  description:
15
- "Looks a person up by e-mail among the people who ran a wizard of this project before.",
15
+ "Looks a person up by email among the people who ran a wizard of this space before.",
16
16
  inputSchema: z.object({ email: z.string().email() }),
17
17
  execute: async ({ email }) => {
18
18
  const [found] = await db()
@@ -36,8 +36,8 @@ server.registerTool({
36
36
 
37
37
  | Where | The tool is called |
38
38
  |---|---|
39
- | A step's `tools` in a wizard | `contacts.lookup`: `<plugin id>.<tool name>` |
40
- | The model | `contacts_lookup`. A `-` in the plugin's id becomes `_`: `run-log.recent` is `run_log_recent` |
39
+ | A step’s `tools` in a wizard | `contacts.lookup`: `<plugin id>.<tool name>` |
40
+ | The model | `contacts_lookup`. A `-` in the plugin’s id becomes `_`: `run-log.recent` is `run_log_recent` |
41
41
  | The editor | Its `title` |
42
42
 
43
43
  ## What `execute` knows
@@ -48,10 +48,10 @@ The second argument is the step that calls the tool:
48
48
  |---|---|
49
49
  | `step.runId`, `step.stepId` | The run and the step |
50
50
  | `step.tenantId` | The tenant |
51
- | `step.space` | `{ id, name }`: the space of the step's wizard |
51
+ | `step.space` | `{ id, name }`: the space of the step’s wizard |
52
52
  | `step.project` | The same as `step.space`, by its older name |
53
53
  | `step.wizard` | `{ id, title }` |
54
- | `step.mode` | `"test"` for a test run from the studio, else `"live"`. Keep what a test makes apart: a booking, a message to someone outside |
54
+ | `step.mode` | `"test"` for a test run from the studio, else `"live"`. Keep what a test run makes apart, such as a booking or a message to someone outside |
55
55
  | `step.signal` | Aborted when the run is cancelled. Pass it to `fetch` |
56
56
  | `step.emit(message)` | Tells the person what the step is doing right now |
57
57
 
@@ -68,8 +68,8 @@ execute: async ({ url }, step) => {
68
68
  ## Errors
69
69
 
70
70
  An error thrown in `execute` does not fail the step. The model gets `{ "error": "<message>" }`
71
- as the tool's result, with the first 400 characters of the message, and can try again or work
72
- around it. Throw an error whose message says what was wrong with the input.
71
+ as the tool’s result, with the first 400 characters of the message, and can try again or work
72
+ around it. Throw errors whose message says what was wrong with the input.
73
73
 
74
74
  ## In a wizard
75
75
 
@@ -79,19 +79,20 @@ A step lists the tool beside the built-in ones:
79
79
  "tools": ["web_search", "contacts.lookup"]
80
80
  ```
81
81
 
82
- - The editor offers the tools of the tenant's plugins in every AI step.
82
+ - The editor offers the tools of the tenant’s plugins in every AI step.
83
83
  - The assistant and the MCP authoring guide list them with their descriptions.
84
- - A draft whose step lists a tool in `tools` that this tenant does not have shows an issue.
85
- - A run fails at the step that names one. A wizard that uses a plugin's tool runs only where
86
- that plugin is installed: think of that before you publish a wizard to the cloud or export it.
87
- - The model has to call tools. Apple Intelligence on a Mac calls none: a step whose class it
84
+ - A draft with a step that lists a tool this tenant does not have shows an issue.
85
+ - A run fails at the step that names such a tool, with “This step needs the tool “…”. The
86
+ plugin “…” isn’t installed here.” A wizard that uses a plugin’s tool runs only where that
87
+ plugin is installed. Keep that in mind before you publish a wizard to the cloud or export it.
88
+ - The model has to call the tools. Apple Intelligence on a Mac calls none: a step whose class it
88
89
  answers (Classifier, Standard) runs from its prompt alone. A step that needs the tool runs on
89
- High, or a [call without a model](#called-without-a-model) does it.
90
+ High, or a [call without a model](#called-without-a-model) does the job.
90
91
 
91
92
  ### Called without a model
92
93
 
93
- Where a step only fetches data and hands it on unchanged, it calls the tool itself: no model
94
- picks the tool, and none copies its answer.
94
+ Where a step only fetches data and hands it on unchanged, it can call the tool itself: no model
95
+ picks the tool, and no model copies its answer.
95
96
 
96
97
  ```json
97
98
  {
@@ -112,26 +113,26 @@ picks the tool, and none copies its answer.
112
113
  }
113
114
  ```
114
115
 
115
- - The tool's answer is the step's json output, as it is. An answer that is not an object (a
116
+ - The tool’s answer is the step’s json output, as it is. An answer that is not an object (a
116
117
  list, a text) is kept as `{ "result": … }`. `output.fields` name the keys later steps read,
117
118
  so the editor and the checks know them.
118
- - String inputs are templates. A filled-in number or `true`/`false` is passed as one; an
119
- empty one is left out. The input is checked against the tool's schema.
120
- - What the tool throws, or an answer that is only `{ "error": … }`, is the step's error. A tool
119
+ - String inputs are templates. A template that fills in to a number or to `true`/`false` is
120
+ passed as one, and an empty one is left out. The input is checked against the tool’s schema.
121
+ - What the tool throws, or an answer that is only `{ "error": … }`, is the step’s error. A tool
121
122
  this tenant does not have fails the step too.
122
123
  - It costs no credits and answers as fast as the tool: the free times of a calendar in under a
123
124
  second instead of half a minute.
124
125
 
125
126
  ## While a step runs
126
127
 
127
- A step that is running keeps the tools it started with. A plugin that loads again changes the
128
- tools of the next step.
128
+ A step that is running keeps the tools it started with. When a plugin loads again, the change
129
+ reaches the next step.
129
130
 
130
131
  ## Write a good tool
131
132
 
132
133
  - One job per tool. Two small tools are easier for a model to choose between than one with a
133
134
  `mode` field.
134
- - Describe the result as well as the input: "returns the working days as a number".
135
+ - Describe the result as well as the input: “returns the working days as a number”.
135
136
  - Return data, not prose. The step writes the sentences.
136
137
  - Bound what it returns: a `limit` with a maximum, the newest 50 rows.
137
138
  - A tool that changes something outside says so in its description. There is no
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  title: The wizard format
3
3
  description: A wizard as JSON and as a .wizard file, its JSON Schema, and checking it with wizards validate.
4
- version: 0.3.2
4
+ version: 0.5.0
5
5
  ---
6
6
 
7
- A wizard is one JSON document, its **definition**. The studio exports it as a `.wizard` file,
8
- and imports one back. Both can be written by hand or by a tool, checked in your editor against a
9
- JSON Schema, and checked completely with `wizards validate`.
7
+ A wizard is one JSON document, its **definition**. The studio exports it as a `.wizard` file
8
+ and imports one back. You can write either by hand or with a tool, check it in your editor
9
+ against a JSON Schema, and check it completely with `wizards validate`.
10
10
 
11
11
  The code that defines the format and checks it is also under the
12
12
  [MIT licence](https://github.com/engenty/wizards/blob/main/packages/shared/LICENSE-MIT), so any
@@ -21,25 +21,31 @@ tool may read and write wizards.
21
21
  "title": "Create an invoice",
22
22
  "description": "A finished invoice from a few details.",
23
23
  "avatar": "round",
24
+ "lang": "en",
24
25
  "steps": [ … ]
25
26
  }
26
27
  ```
27
28
 
28
- `steps` run top to bottom, and the last one is always a `result` step. The step types and their
29
- fields are in the schema below. The studio's MCP tool `get_authoring_guide` explains them with a
30
- complete example.
29
+ `steps` run from top to bottom, and the last one is always a `result` step. The schema below
30
+ lists the step types and their fields. The studio’s MCP tool `get_authoring_guide` explains them
31
+ with a complete example.
31
32
 
32
- `version` is the definition's version. It changes only with a breaking change; the schemas of
33
+ `lang` is the language the wizard speaks to people: `de` or `en`. It sets the runner’s own words
34
+ and how numbers and dates are written. Without it, the language is read from the wizard’s own
35
+ words, and English is the default where they are not clearly German.
36
+
37
+ `version` is the definition’s version. It changes only with a breaking change; the schemas of
33
38
  each version stay online in their own folder (`/schema/v1/`, `/schema/v2/`, …).
34
39
 
35
40
  ## The `.wizard` file
36
41
 
37
- A zip with two things in it:
42
+ The file is a zip with two things in it:
38
43
 
39
44
  | Path | What it holds |
40
45
  |---|---|
41
- | `wizard.json` | The manifest: the definition, plus what it needs from its project |
42
- | `files/…` | The wizard's workspace: widget pages, templates, images. At most 200 files and 25 MB |
46
+ | `wizard.json` | The manifest: the definition, plus what the wizard needs from its space |
47
+ | `files/…` | The wizard’s workspace: widget pages, templates, images. At most 200 files and 25 MB |
48
+ | `files/knowledge/…` | Only when the export was asked for it: the space’s Knowledge pages as Markdown files, one per page, with its title in front. A website runs the wizard with them, without the space |
43
49
 
44
50
  ```json
45
51
  {
@@ -52,11 +58,16 @@ A zip with two things in it:
52
58
  }
53
59
  ```
54
60
 
55
- `connectors` and `mcpServers` name what the wizard's steps use from its project, without
56
- addresses or credentials. A project that lacks one is told so on import.
61
+ `connectors` and `mcpServers` (the space’s connected systems) name what the wizard’s steps use
62
+ from its space, without addresses or credentials. When the space you import into lacks one, the
63
+ import says so.
64
+
65
+ `knowledge` (`{ "pages": 12, "truncated": false }`) is there when the export took the space’s
66
+ pages along. It says how many there are and whether the cap of about 2 MB left some out. The
67
+ share dialog’s website package does this with “Take the knowledge along”.
57
68
 
58
69
  The import also takes a `wizard.json` on its own, or a definition on its own.
59
- The file's media type is `application/vnd.engenty.wizard+zip`.
70
+ The file’s media type is `application/vnd.engenty.wizard+zip`.
60
71
 
61
72
  ## JSON Schema
62
73
 
@@ -66,14 +77,14 @@ The file's media type is `application/vnd.engenty.wizard+zip`.
66
77
  | `wizard.json` in a package | [`https://engenty.ai/schema/v1/wizard-package.json`](https://engenty.ai/schema/v1/wizard-package.json) |
67
78
 
68
79
  Put the address under `"$schema"`, and editors such as VS Code complete keys and mark mistakes
69
- as you type. The studio's export writes it into every `wizard.json`.
80
+ as you type. The studio’s export writes it into every `wizard.json`.
70
81
 
71
82
  The schemas are written from the code that reads wizards, so they match it. They are stricter
72
83
  in one way: a key the app does not know is an error. The app would drop such a key without a
73
84
  word.
74
85
 
75
- What a JSON Schema cannot say is left to `wizards validate`: unique ids, steps and fields that
76
- refer to each other, templates naming answers that exist by then, and files in the workspace.
86
+ `wizards validate` checks what a JSON Schema cannot say: unique ids, steps and fields that refer
87
+ to each other, templates that name answers that exist by then, and files in the workspace.
77
88
 
78
89
  ## `wizards validate`
79
90
 
@@ -81,8 +92,8 @@ refer to each other, templates naming answers that exist by then, and files in t
81
92
  wizards validate invoice.wizard
82
93
  ```
83
94
 
84
- It checks a wizard the way the studio's import does, with no running studio and no account.
85
- It takes any number of paths:
95
+ It checks a wizard the way the studio’s import does, without a running studio and without an
96
+ account. It takes any number of paths:
86
97
 
87
98
  | Path | Read as |
88
99
  |---|---|
@@ -96,12 +107,13 @@ It takes any number of paths:
96
107
  "{{nope}}" refers to a field that is not asked before "g".
97
108
  ```
98
109
 
99
- `--json` prints the issues as JSON. The exit code is `0` when every wizard is fine, `1` when one
100
- has issues and `2` when no path was given. That is enough for a check in CI:
110
+ A wizard without issues gets a ✓ with its number of steps and files. `--json` prints the
111
+ results as JSON. The exit code is `0` when every wizard is fine, `1` when one has issues and `2`
112
+ when no path was given. That is enough for a check in CI:
101
113
 
102
114
  ```bash
103
115
  npx wizards validate wizards/*.wizard
104
116
  ```
105
117
 
106
- The project's own things are checked on import, because only a project has them: its
107
- connectors and their actions, its MCP servers and its plugins' tools.
118
+ The import checks what belongs to the space, because only the space has it: its connectors and
119
+ their actions, its connected systems (MCP servers) and its plugins’ tools.
@@ -1,26 +1,26 @@
1
1
  ---
2
2
  title: AI apps
3
3
  description: Run and build your wizards inside Claude Desktop, Cursor, Codex and other AI apps.
4
- version: 0.3.2
4
+ version: 0.5.0
5
5
  ---
6
6
 
7
- Settings → Integrate brings your wizards to where you work. engenty wizards is an MCP server:
8
- an AI app that adds it gets the tools to find, run and build wizards. Under "Share" the same page
7
+ Settings → Integrate brings your wizards to where you work. engenty wizards is an MCP server: an
8
+ AI app that adds it gets the tools to find, run and build wizards. Under “Share”, the same page
9
9
  has the WordPress plugin: see [WordPress](./wordpress.md).
10
10
 
11
11
  ## What an app can do
12
12
 
13
13
  | In the chat | How |
14
14
  |---|---|
15
- | Run a wizard | "Start one of my engenty wizards." The app asks the wizard's questions, shows the review and hands over the downloads. Only published wizards run |
16
- | See the wizard itself | Apps that show MCP Apps show the wizard as a widget, page by page, and you answer there |
17
- | Build a wizard | "Use engenty wizards to build a wizard that reads amount, date and sender from an invoice PDF." |
18
- | Change one | Create, change and publish wizards, find templates and connectors, read and write a wizard's files |
15
+ | Run a wizard | “Start one of my engenty wizards.” The app asks the wizard’s questions, shows the review and hands over the downloads. Only published wizards run |
16
+ | See the wizard itself | Apps that support MCP Apps show the wizard as a widget, page by page, and you answer there |
17
+ | Build a wizard | “Use engenty wizards to build a wizard that reads amount, date and sender from an invoice PDF.” |
18
+ | Change one | The app can create, change and publish wizards, find templates and connectors, and read and write a wizard’s files |
19
19
 
20
20
  - A run in a chat spends what any run of the wizard spends, and so does a test run.
21
- - What a chat cannot fill in — files, recordings, signatures, line items — is done on the run's
22
- page in the browser. The app hands you the link.
23
- - What an app writes shows up live in an open editor, marked with the app's name.
21
+ - What a chat can’t fill in (files, recordings, signatures, line items) you fill in on the run’s
22
+ page in the browser. The app gives you the link.
23
+ - What an app writes shows up live in an open editor, marked with the app’s name (“Via …”).
24
24
 
25
25
  ## Apps
26
26
 
@@ -40,68 +40,71 @@ has the WordPress plugin: see [WordPress](./wordpress.md).
40
40
 
41
41
  ## Add an app
42
42
 
43
- Settings → Integrate opens on the apps found on this computer, each with one button and where it
44
- stands: works, added but not tested yet, or not set up. The dots in the menu say the same.
43
+ Settings → Integrate opens on the apps found on this computer. Each one has a button and says
44
+ where it stands: “Works”, “Added, not tested yet” or “Not set up yet”. The dots in the menu say
45
+ the same.
45
46
 
46
- Pick an app and follow its numbered steps:
47
+ Choose an app and follow its numbered steps:
47
48
 
48
- 1. **Add to …** writes engenty wizards into the app's settings. No key, no port: the app starts
49
- engenty wizards itself.
50
- 2. **Restart the app**, or reload its MCP servers. The page notices by itself when the app checks
51
- in.
52
- 3. **Try it in the chat**: "Which wizards do I have in engenty?"
49
+ 1. **Add to …** writes engenty wizards into the app’s settings. You need no key and no port: the
50
+ app starts engenty wizards itself.
51
+ 2. **Restart …**, or reload the app’s MCP servers. The page notices by itself when the app
52
+ checks in.
53
+ 3. **Try it in the chat**: “Which wizards do I have in engenty?”
53
54
 
54
- Once the app has called a tool, the page says "Works" and offers first sentences to try, with your
55
- own wizards' names.
55
+ Once the app has used a tool, the page says “Works” and offers first sentences to try, with your
56
+ own wizards’ names.
56
57
 
57
- From a terminal, the same as step 1:
58
+ From a terminal, this command does the same as step 1:
58
59
 
59
60
  ```bash
60
61
  wizards connect
61
62
  ```
62
63
 
63
- That adds every AI app found on the computer. Name apps to add only those, and take one out
64
- again with `disconnect`:
64
+ It adds every AI app found on this computer. To add only some apps, name them. To take an app
65
+ out again, use `disconnect`:
65
66
 
66
67
  ```bash
67
68
  wizards connect cursor codex
68
69
  wizards disconnect cursor
69
70
  ```
70
71
 
71
- - The file an app's settings were in before is kept beside it as `<file>.before-engenty`.
72
- - Quit Claude Desktop before you add it: it writes its settings from memory while it runs.
73
- - A settings file that is not plain JSON is left alone. The command prints the entry to paste.
72
+ - The app’s settings file as it was before is kept beside it as `<file>.before-engenty`.
73
+ - If Claude Desktop is running, the command asks you to quit it first: it writes its settings
74
+ from memory while it runs and would overwrite the change.
75
+ - A settings file that isn’t plain JSON is left alone. The command prints the entry for you to
76
+ paste in yourself.
74
77
 
75
78
  ## An app on another computer
76
79
 
77
- Under the steps, "Connect with the address and an API key" is for an app that runs elsewhere. The
78
- API key is shown once and goes straight into the command or config entry the page shows.
80
+ Under the steps, “Connect with the address and an API key” is for an app that runs elsewhere.
81
+ The API key is shown once and goes straight into the command or settings entry the page shows.
79
82
 
80
- - Each API key signs one app in and has every right: treat it like a password.
81
- - The page lists the API keys with their last use. Delete one and that app is signed out.
83
+ - Each API key signs in one app and has full rights. Treat it like a password.
84
+ - The page lists the API keys with their last use. When you delete one, that app is signed out.
82
85
 
83
86
  ## Apps on the web
84
87
 
85
- claude.ai and ChatGPT connect from their makers' servers, and so do Claude Desktop's connectors.
86
- They cannot reach your computer: for them your wizards run on engenty.ai.
88
+ claude.ai and ChatGPT connect from their makers’ servers, and so do Claude Desktop’s
89
+ connectors. They can’t reach your computer, so for them your wizards run on engenty.ai.
87
90
 
88
- - **From the cloud studio** the page walks through it: open the app's connector settings, enter
89
- the name and the address `https://engenty.ai/api/mcp`, click Connect, sign in at engenty and
90
- allow. No key.
91
- - **From your computer** connect your engenty account first. The wizards you publish go to
92
- engenty.ai, and claude.ai connects there. Without an account, use Claude Desktop on this
93
- computer.
91
+ - **In the studio on engenty.ai**, the page walks you through it: open the app’s connector
92
+ settings, enter the name and the address `https://engenty.ai/api/mcp`, click “Connect”, sign
93
+ in to engenty and choose “Allow”. You need no key.
94
+ - **On your computer**, connect your engenty account first (“Connect to engenty.ai”). The wizards
95
+ you publish then go to engenty.ai, and claude.ai connects there. If you’d rather not use an
96
+ account, use Claude Desktop on this computer.
94
97
 
95
98
  The consent page names the team the access is for and the address it goes back to. An app that
96
- only named itself is marked "Name given by the app itself".
99
+ only named itself is marked “Name given by the app itself”.
97
100
 
98
- Disconnect an app under Account → Connected apps at engenty.ai. Its access ends within half a
99
- minute, even with a token it already holds.
101
+ You disconnect an app at engenty.ai under Account → Connected apps. Its access ends within half
102
+ a minute, even with a token it already holds.
100
103
 
101
104
  ## The Claude Code plugin
102
105
 
103
- With a public https address, Claude Code can also install a plugin. It adds the `/wizard`
104
- command and the skills to build and to use wizards:
106
+ If engenty wizards has a public https address, Claude Code can also install a plugin. It adds
107
+ the `/wizard` command and the skills to build and use wizards:
105
108
 
106
109
  ```bash
107
110
  claude plugin marketplace add <your address>/api/claude-plugin/marketplace.json