@engenty/wizards-runtime 0.0.0-stage → 0.7.5
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/LICENSE +110 -0
- package/README.md +214 -2
- package/apps/runtime/dist/agents/architect.js +444 -0
- package/apps/runtime/dist/agents/studio-assistant.js +883 -0
- package/apps/runtime/dist/agents/subscription.js +207 -0
- package/apps/runtime/dist/agents/thought.js +21 -0
- package/apps/runtime/dist/agents/website.js +480 -0
- package/apps/runtime/dist/app.js +359 -0
- package/apps/runtime/dist/apple/wizards-apple +0 -0
- package/apps/runtime/dist/assistant/browser.js +26 -0
- package/apps/runtime/dist/assistant/docs.js +158 -0
- package/apps/runtime/dist/assistant/knows.js +353 -0
- package/apps/runtime/dist/assistant/primer.js +26 -0
- package/apps/runtime/dist/assistant/runs.js +24 -0
- package/apps/runtime/dist/auth/account.js +175 -0
- package/apps/runtime/dist/auth/device.js +112 -0
- package/apps/runtime/dist/auth/index.js +358 -0
- package/apps/runtime/dist/auth/keys.js +55 -0
- package/apps/runtime/dist/auth/local-ticket.js +26 -0
- package/apps/runtime/dist/authoring/example.js +74 -0
- package/apps/runtime/dist/authoring/guide.js +433 -0
- package/apps/runtime/dist/authoring/ops.js +117 -0
- package/apps/runtime/dist/browser/fast/action-space.js +160 -0
- package/apps/runtime/dist/browser/fast/classifier.js +91 -0
- package/apps/runtime/dist/browser/fast/decide.js +171 -0
- package/apps/runtime/dist/browser/fast/driver.js +141 -0
- package/apps/runtime/dist/browser/fast/instructions.js +33 -0
- package/apps/runtime/dist/browser/fast/run.js +249 -0
- package/apps/runtime/dist/browser/fast/span-picker.js +153 -0
- package/apps/runtime/dist/browser/fast/text-helper.js +178 -0
- package/apps/runtime/dist/browser/snapshot.js +335 -0
- package/apps/runtime/dist/cli/account.js +385 -0
- package/apps/runtime/dist/cli/autostart.js +182 -0
- package/apps/runtime/dist/cli/autoupdate.js +221 -0
- package/apps/runtime/dist/cli/clients.js +44 -0
- package/apps/runtime/dist/cli/connect.js +540 -0
- package/apps/runtime/dist/cli/environment.js +93 -0
- package/apps/runtime/dist/cli/exec.js +45 -0
- package/apps/runtime/dist/cli/features.js +50 -0
- package/apps/runtime/dist/cli/home.js +88 -0
- package/apps/runtime/dist/cli/install-env.js +33 -0
- package/apps/runtime/dist/cli/machine.js +107 -0
- package/apps/runtime/dist/cli/main.js +222 -0
- package/apps/runtime/dist/cli/mcp.js +136 -0
- package/apps/runtime/dist/cli/menu.js +202 -0
- package/apps/runtime/dist/cli/processes.js +72 -0
- package/apps/runtime/dist/cli/report.js +66 -0
- package/apps/runtime/dist/cli/setup.js +335 -0
- package/apps/runtime/dist/cli/start.js +276 -0
- package/apps/runtime/dist/cli/status.js +203 -0
- package/apps/runtime/dist/cli/ui.js +59 -0
- package/apps/runtime/dist/cli/uninstall-main.js +20 -0
- package/apps/runtime/dist/cli/uninstall.js +231 -0
- package/apps/runtime/dist/cli/update.js +86 -0
- package/apps/runtime/dist/cli/validate.js +75 -0
- package/apps/runtime/dist/cli/versions.js +123 -0
- package/apps/runtime/dist/connectors/builtin.js +86 -0
- package/apps/runtime/dist/connectors/external.js +409 -0
- package/apps/runtime/dist/connectors/gmail.js +107 -0
- package/apps/runtime/dist/connectors/imap.js +261 -0
- package/apps/runtime/dist/connectors/index.js +325 -0
- package/apps/runtime/dist/connectors/mail.js +72 -0
- package/apps/runtime/dist/connectors/outlook.js +90 -0
- package/apps/runtime/dist/connectors/plugin-connections.js +343 -0
- package/apps/runtime/dist/connectors/via-account.js +65 -0
- package/apps/runtime/dist/credits/credits.js +100 -0
- package/apps/runtime/dist/credits/estimate.js +152 -0
- package/apps/runtime/dist/db/adopt.js +149 -0
- package/apps/runtime/dist/db/client.js +173 -0
- package/apps/runtime/dist/db/control-schema.js +133 -0
- package/apps/runtime/dist/db/migrations/control/0000_last_absorbing_man.sql +47 -0
- package/apps/runtime/dist/db/migrations/control/0001_gorgeous_nicolaos.sql +41 -0
- package/apps/runtime/dist/db/migrations/control/0002_secret_penance.sql +1 -0
- package/apps/runtime/dist/db/migrations/control/0003_nasty_mordo.sql +3 -0
- package/apps/runtime/dist/db/migrations/control/0004_breezy_eddie_brock.sql +6 -0
- package/apps/runtime/dist/db/migrations/control/0005_chilly_oracle.sql +1 -0
- package/apps/runtime/dist/db/migrations/control/0006_sleepy_mojo.sql +1 -0
- package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
- package/apps/runtime/dist/db/migrations/control/0008_runner.sql +8 -0
- package/apps/runtime/dist/db/migrations/control/0009_plugin_claim.sql +9 -0
- package/apps/runtime/dist/db/migrations/control/0010_tan_snowbird.sql +6 -0
- package/apps/runtime/dist/db/migrations/control/meta/0000_snapshot.json +311 -0
- package/apps/runtime/dist/db/migrations/control/meta/0001_snapshot.json +599 -0
- package/apps/runtime/dist/db/migrations/control/meta/0002_snapshot.json +607 -0
- package/apps/runtime/dist/db/migrations/control/meta/0003_snapshot.json +311 -0
- package/apps/runtime/dist/db/migrations/control/meta/0004_snapshot.json +350 -0
- package/apps/runtime/dist/db/migrations/control/meta/0005_snapshot.json +358 -0
- package/apps/runtime/dist/db/migrations/control/meta/0006_snapshot.json +365 -0
- package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
- package/apps/runtime/dist/db/migrations/control/meta/0008_snapshot.json +505 -0
- package/apps/runtime/dist/db/migrations/control/meta/0009_snapshot.json +561 -0
- package/apps/runtime/dist/db/migrations/control/meta/0010_snapshot.json +600 -0
- package/apps/runtime/dist/db/migrations/control/meta/_journal.json +83 -0
- package/apps/runtime/dist/db/migrations/tenant/0000_eminent_freak.sql +188 -0
- package/apps/runtime/dist/db/migrations/tenant/0001_salty_master_chief.sql +1 -0
- package/apps/runtime/dist/db/migrations/tenant/0002_cloudy_firebird.sql +1 -0
- package/apps/runtime/dist/db/migrations/tenant/0003_brown_warbound.sql +52 -0
- package/apps/runtime/dist/db/migrations/tenant/0004_romantic_nocturne.sql +6 -0
- package/apps/runtime/dist/db/migrations/tenant/0005_reflective_forgotten_one.sql +2 -0
- package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
- package/apps/runtime/dist/db/migrations/tenant/0007_space_data.sql +43 -0
- package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
- package/apps/runtime/dist/db/migrations/tenant/0009_knowledge.sql +104 -0
- package/apps/runtime/dist/db/migrations/tenant/0010_plugin_connection.sql +15 -0
- package/apps/runtime/dist/db/migrations/tenant/0011_runners.sql +2 -0
- package/apps/runtime/dist/db/migrations/tenant/0012_assistant_chat.sql +40 -0
- package/apps/runtime/dist/db/migrations/tenant/0013_run_origin.sql +1 -0
- package/apps/runtime/dist/db/migrations/tenant/0014_run_answer.sql +2 -0
- package/apps/runtime/dist/db/migrations/tenant/0015_device_calls.sql +13 -0
- package/apps/runtime/dist/db/migrations/tenant/0016_even_trish_tilby.sql +12 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0000_snapshot.json +1323 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0001_snapshot.json +1330 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0002_snapshot.json +1337 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0003_snapshot.json +1605 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0004_snapshot.json +1645 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0005_snapshot.json +1659 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0007_snapshot.json +2012 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0009_snapshot.json +2837 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0010_snapshot.json +2942 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0011_snapshot.json +2956 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0012_snapshot.json +3132 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0013_snapshot.json +3139 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0014_snapshot.json +3154 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0015_snapshot.json +3243 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0016_snapshot.json +3326 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +125 -0
- package/apps/runtime/dist/db/schema.js +602 -0
- package/apps/runtime/dist/debug.js +196 -0
- package/apps/runtime/dist/docs/dev/index.md +41 -0
- package/apps/runtime/dist/docs/dev/meta.json +7 -0
- package/apps/runtime/dist/docs/dev/plugins/connections.md +74 -0
- package/apps/runtime/dist/docs/dev/plugins/events.md +89 -0
- package/apps/runtime/dist/docs/dev/plugins/examples.md +101 -0
- package/apps/runtime/dist/docs/dev/plugins/index.md +78 -0
- package/apps/runtime/dist/docs/dev/plugins/layout.md +90 -0
- package/apps/runtime/dist/docs/dev/plugins/meta.json +28 -0
- package/apps/runtime/dist/docs/dev/plugins/quick-start.md +94 -0
- package/apps/runtime/dist/docs/dev/plugins/reference.md +348 -0
- package/apps/runtime/dist/docs/dev/plugins/reloading.md +76 -0
- package/apps/runtime/dist/docs/dev/plugins/routes.md +185 -0
- package/apps/runtime/dist/docs/dev/plugins/runners.md +230 -0
- package/apps/runtime/dist/docs/dev/plugins/server.md +281 -0
- package/apps/runtime/dist/docs/dev/plugins/shipping.md +79 -0
- package/apps/runtime/dist/docs/dev/plugins/space.md +297 -0
- package/apps/runtime/dist/docs/dev/plugins/starters.md +70 -0
- package/apps/runtime/dist/docs/dev/plugins/studio.md +363 -0
- package/apps/runtime/dist/docs/dev/plugins/styling.md +129 -0
- package/apps/runtime/dist/docs/dev/plugins/tables.md +104 -0
- package/apps/runtime/dist/docs/dev/plugins/tools.md +139 -0
- package/apps/runtime/dist/docs/dev/wizard-format.md +125 -0
- package/apps/runtime/dist/docs/meta.json +3 -0
- package/apps/runtime/dist/docs/user/ai-apps.md +112 -0
- package/apps/runtime/dist/docs/user/assistant.md +77 -0
- package/apps/runtime/dist/docs/user/build-a-wizard.md +116 -0
- package/apps/runtime/dist/docs/user/command-line.md +83 -0
- package/apps/runtime/dist/docs/user/connectors.md +90 -0
- package/apps/runtime/dist/docs/user/create-account.md +52 -0
- package/apps/runtime/dist/docs/user/data.md +66 -0
- package/apps/runtime/dist/docs/user/first-start.md +60 -0
- package/apps/runtime/dist/docs/user/index.md +49 -0
- package/apps/runtime/dist/docs/user/install.md +123 -0
- package/apps/runtime/dist/docs/user/local-only.md +42 -0
- package/apps/runtime/dist/docs/user/meta.json +32 -0
- package/apps/runtime/dist/docs/user/models.md +156 -0
- package/apps/runtime/dist/docs/user/plugins.md +71 -0
- package/apps/runtime/dist/docs/user/run.md +98 -0
- package/apps/runtime/dist/docs/user/server.md +52 -0
- package/apps/runtime/dist/docs/user/space.md +126 -0
- package/apps/runtime/dist/docs/user/steps.md +220 -0
- package/apps/runtime/dist/docs/user/test-and-share.md +224 -0
- package/apps/runtime/dist/docs/user/troubleshooting.md +67 -0
- package/apps/runtime/dist/docs/user/wordpress.md +121 -0
- package/apps/runtime/dist/documents/parse.js +246 -0
- package/apps/runtime/dist/engenty/connections-external/build-connector.js +193 -0
- package/apps/runtime/dist/engenty/connections-external/errors.js +11 -0
- package/apps/runtime/dist/engenty/connections-external/import-service.js +270 -0
- package/apps/runtime/dist/engenty/connections-external/importer/classify.js +34 -0
- package/apps/runtime/dist/engenty/connections-external/importer/map-auth.js +185 -0
- package/apps/runtime/dist/engenty/connections-external/importer/normalize-mcp.js +63 -0
- package/apps/runtime/dist/engenty/connections-external/importer/normalize-openapi.js +130 -0
- package/apps/runtime/dist/engenty/connections-external/invoke/http-invoker.js +143 -0
- package/apps/runtime/dist/engenty/connections-external/invoke/mcp-client.js +143 -0
- package/apps/runtime/dist/engenty/connections-external/net/guarded-fetch.js +119 -0
- package/apps/runtime/dist/engenty/connections-external/oauth-dcr.js +88 -0
- package/apps/runtime/dist/engenty/connections-external/registry-client.js +336 -0
- package/apps/runtime/dist/engenty/connections-external/registry-source.js +82 -0
- package/apps/runtime/dist/engenty/connections-external/types.js +7 -0
- package/apps/runtime/dist/engenty/connections-github/connector.js +209 -0
- package/apps/runtime/dist/engenty/connections-google/connectors/calendar.js +381 -0
- package/apps/runtime/dist/engenty/connections-google/connectors/contacts.js +94 -0
- package/apps/runtime/dist/engenty/connections-google/connectors/drive.js +290 -0
- package/apps/runtime/dist/engenty/connections-google/connectors/gmail.js +567 -0
- package/apps/runtime/dist/engenty/connections-google/definitions.js +11 -0
- package/apps/runtime/dist/engenty/connections-google/shared.js +73 -0
- package/apps/runtime/dist/engenty/connections-hubspot/connector.js +140 -0
- package/apps/runtime/dist/engenty/connections-microsoft/action.js +17 -0
- package/apps/runtime/dist/engenty/connections-microsoft/graph.js +114 -0
- package/apps/runtime/dist/engenty/connections-microsoft/onedrive.js +286 -0
- package/apps/runtime/dist/engenty/connections-microsoft/outlook.js +492 -0
- package/apps/runtime/dist/engenty/connections-s3/s3.js +328 -0
- package/apps/runtime/dist/engenty/connections-sdk/files-capability.js +86 -0
- package/apps/runtime/dist/engenty/connections-sdk/oauth2.js +150 -0
- package/apps/runtime/dist/engenty/connections-sdk/registry.js +89 -0
- package/apps/runtime/dist/engenty/connections-sdk/storage-capability.js +84 -0
- package/apps/runtime/dist/engenty/connections-sdk/types.js +30 -0
- package/apps/runtime/dist/engenty/connections-slack/connector.js +360 -0
- package/apps/runtime/dist/engenty/csv-import/csv-matrix.js +178 -0
- package/apps/runtime/dist/engenty/csv-import/import-sources.js +87 -0
- package/apps/runtime/dist/engenty/csv-import/parse-csv.js +129 -0
- package/apps/runtime/dist/engenty/csv-import/serialize-csv.js +20 -0
- package/apps/runtime/dist/engenty/csv-import/types.js +1 -0
- package/apps/runtime/dist/engenty/csv-import/xlsx-workbook.js +159 -0
- package/apps/runtime/dist/engenty/doc-converter/interface.js +9 -0
- package/apps/runtime/dist/engenty/doc-converter/page-break.js +92 -0
- package/apps/runtime/dist/engenty/doc-converter/providers/local/index.js +72 -0
- package/apps/runtime/dist/engenty/document-scanner/schemas/classifier.js +30 -0
- package/apps/runtime/dist/engenty/document-scanner/schemas/index.js +4 -0
- package/apps/runtime/dist/engenty/document-scanner/schemas/invoice.js +73 -0
- package/apps/runtime/dist/engenty/document-scanner/schemas/receipt.js +63 -0
- package/apps/runtime/dist/engenty/document-scanner/schemas/shared.js +40 -0
- package/apps/runtime/dist/engenty/search-index/chunks.js +164 -0
- package/apps/runtime/dist/engenty/search-index/contracts.js +9 -0
- package/apps/runtime/dist/engenty/shims/connections-sdk.js +39 -0
- package/apps/runtime/dist/engenty/shims/plugin-sdk.js +1 -0
- package/apps/runtime/dist/engenty/shims/web-ingest.js +19 -0
- package/apps/runtime/dist/engenty/web-ingest/ssrf.js +277 -0
- package/apps/runtime/dist/engine/asks.js +82 -0
- package/apps/runtime/dist/engine/decide.js +82 -0
- package/apps/runtime/dist/engine/device.js +194 -0
- package/apps/runtime/dist/engine/events.js +128 -0
- package/apps/runtime/dist/engine/input.js +208 -0
- package/apps/runtime/dist/engine/owner.js +32 -0
- package/apps/runtime/dist/engine/prepare.js +90 -0
- package/apps/runtime/dist/engine/push.js +58 -0
- package/apps/runtime/dist/engine/requirements.js +355 -0
- package/apps/runtime/dist/engine/resources.js +198 -0
- package/apps/runtime/dist/engine/runner.js +970 -0
- package/apps/runtime/dist/engine/steps.js +1000 -0
- package/apps/runtime/dist/engine/surface.js +91 -0
- package/apps/runtime/dist/engine/template.js +240 -0
- package/apps/runtime/dist/engine/types.js +4 -0
- package/apps/runtime/dist/env.js +295 -0
- package/apps/runtime/dist/features.js +123 -0
- package/apps/runtime/dist/files/blobs.js +22 -0
- package/apps/runtime/dist/files/objects.js +86 -0
- package/apps/runtime/dist/files/storage.js +120 -0
- package/apps/runtime/dist/files/web-images.js +101 -0
- package/apps/runtime/dist/film/project.js +257 -0
- package/apps/runtime/dist/film/skills.js +91 -0
- package/apps/runtime/dist/film/sounds.js +122 -0
- package/apps/runtime/dist/film/step.js +289 -0
- package/apps/runtime/dist/film/tools.js +99 -0
- package/apps/runtime/dist/geocode.js +58 -0
- package/apps/runtime/dist/harness/antigravity.js +129 -0
- package/apps/runtime/dist/harness/apple.js +270 -0
- package/apps/runtime/dist/harness/claude.js +147 -0
- package/apps/runtime/dist/harness/codex.js +229 -0
- package/apps/runtime/dist/harness/cursor.js +93 -0
- package/apps/runtime/dist/harness/env.js +124 -0
- package/apps/runtime/dist/harness/index.js +95 -0
- package/apps/runtime/dist/harness/model.js +279 -0
- package/apps/runtime/dist/harness/prompt.js +121 -0
- package/apps/runtime/dist/harness/terminal.js +194 -0
- package/apps/runtime/dist/harness/types.js +7 -0
- package/apps/runtime/dist/index.js +113 -0
- package/apps/runtime/dist/limits.js +81 -0
- package/apps/runtime/dist/link-preview.js +60 -0
- package/apps/runtime/dist/log.js +106 -0
- package/apps/runtime/dist/manage.js +249 -0
- package/apps/runtime/dist/mcp/auth.js +161 -0
- package/apps/runtime/dist/mcp/bridge.js +59 -0
- package/apps/runtime/dist/mcp/flow-app.js +97 -0
- package/apps/runtime/dist/mcp/handler.js +54 -0
- package/apps/runtime/dist/mcp/scopes.js +14 -0
- package/apps/runtime/dist/mcp/seen.js +65 -0
- package/apps/runtime/dist/mcp/tools.js +572 -0
- package/apps/runtime/dist/media/conversation.js +167 -0
- package/apps/runtime/dist/media/ffmpeg.js +121 -0
- package/apps/runtime/dist/media/generate.js +120 -0
- package/apps/runtime/dist/media/marking.js +121 -0
- package/apps/runtime/dist/media/transcribe.js +198 -0
- package/apps/runtime/dist/model-errors.js +42 -0
- package/apps/runtime/dist/models.js +1164 -0
- package/apps/runtime/dist/plugin.js +61 -0
- package/apps/runtime/dist/plugins/channels.js +78 -0
- package/apps/runtime/dist/plugins/claims.js +56 -0
- package/apps/runtime/dist/plugins/discovery.js +155 -0
- package/apps/runtime/dist/plugins/events.js +63 -0
- package/apps/runtime/dist/plugins/jobs.js +64 -0
- package/apps/runtime/dist/plugins/loader.js +508 -0
- package/apps/runtime/dist/plugins/migrations.js +69 -0
- package/apps/runtime/dist/plugins/pro-keys.js +34 -0
- package/apps/runtime/dist/plugins/pro-state.js +83 -0
- package/apps/runtime/dist/plugins/pro.js +310 -0
- package/apps/runtime/dist/plugins/public.js +44 -0
- package/apps/runtime/dist/plugins/registry.js +122 -0
- package/apps/runtime/dist/plugins/runs.js +210 -0
- package/apps/runtime/dist/render/browser-path.js +54 -0
- package/apps/runtime/dist/render/chromium.js +98 -0
- package/apps/runtime/dist/render/convert.js +158 -0
- package/apps/runtime/dist/render/downloads.js +299 -0
- package/apps/runtime/dist/render/guard.js +25 -0
- package/apps/runtime/dist/render/shaped.js +137 -0
- package/apps/runtime/dist/routes/api.js +440 -0
- package/apps/runtime/dist/routes/debug.js +42 -0
- package/apps/runtime/dist/routes/delivery.js +90 -0
- package/apps/runtime/dist/routes/internal.js +81 -0
- package/apps/runtime/dist/routes/lang.js +25 -0
- package/apps/runtime/dist/routes/marketplace.js +43 -0
- package/apps/runtime/dist/routes/plugin-public.js +113 -0
- package/apps/runtime/dist/routes/plugins.js +212 -0
- package/apps/runtime/dist/routes/runs.js +1422 -0
- package/apps/runtime/dist/routes/studio.js +1629 -0
- package/apps/runtime/dist/routes/wizard-stream.js +30 -0
- package/apps/runtime/dist/running.js +39 -0
- package/apps/runtime/dist/sandbox/docker.js +75 -0
- package/apps/runtime/dist/sandbox/index.js +23 -0
- package/apps/runtime/dist/sandbox/types.js +1 -0
- package/apps/runtime/dist/secrets/crypto.js +28 -0
- package/apps/runtime/dist/secrets/signing.js +52 -0
- package/apps/runtime/dist/secrets/vault.js +59 -0
- package/apps/runtime/dist/services/access.js +88 -0
- package/apps/runtime/dist/services/api.js +248 -0
- package/apps/runtime/dist/services/architect.js +95 -0
- package/apps/runtime/dist/services/assistant-chats.js +311 -0
- package/apps/runtime/dist/services/brand.js +85 -0
- package/apps/runtime/dist/services/cloud.js +456 -0
- package/apps/runtime/dist/services/draft-events.js +27 -0
- package/apps/runtime/dist/services/engenty-shapes.js +71 -0
- package/apps/runtime/dist/services/errors.js +29 -0
- package/apps/runtime/dist/services/files.js +178 -0
- package/apps/runtime/dist/services/knowledge-model.js +559 -0
- package/apps/runtime/dist/services/knowledge.js +721 -0
- package/apps/runtime/dist/services/links.js +16 -0
- package/apps/runtime/dist/services/marketplace.js +492 -0
- package/apps/runtime/dist/services/onboarding.js +152 -0
- package/apps/runtime/dist/services/package-file.js +82 -0
- package/apps/runtime/dist/services/package.js +170 -0
- package/apps/runtime/dist/services/profile.js +51 -0
- package/apps/runtime/dist/services/project-files.js +439 -0
- package/apps/runtime/dist/services/project-index.js +707 -0
- package/apps/runtime/dist/services/projects.js +387 -0
- package/apps/runtime/dist/services/relevance.js +58 -0
- package/apps/runtime/dist/services/runners.js +178 -0
- package/apps/runtime/dist/services/runs.js +524 -0
- package/apps/runtime/dist/services/shares.js +130 -0
- package/apps/runtime/dist/services/site.js +270 -0
- package/apps/runtime/dist/services/space-categories.js +861 -0
- package/apps/runtime/dist/services/space-data.js +792 -0
- package/apps/runtime/dist/services/space-origin.js +207 -0
- package/apps/runtime/dist/services/spaces.js +656 -0
- package/apps/runtime/dist/services/translations.js +306 -0
- package/apps/runtime/dist/services/widgets.js +34 -0
- package/apps/runtime/dist/services/wizard-icon.js +157 -0
- package/apps/runtime/dist/services/wizards.js +420 -0
- package/apps/runtime/dist/settings.js +16 -0
- package/apps/runtime/dist/store/errors.js +4 -0
- package/apps/runtime/dist/store/index.js +299 -0
- package/apps/runtime/dist/store/shared-lists.js +123 -0
- package/apps/runtime/dist/tenants/control.js +238 -0
- package/apps/runtime/dist/tenants/tenant.js +26 -0
- package/apps/runtime/dist/texts.js +207 -0
- package/apps/runtime/dist/tools/browser.js +703 -0
- package/apps/runtime/dist/tools/connector.js +204 -0
- package/apps/runtime/dist/tools/index.js +291 -0
- package/apps/runtime/dist/tools/mail.js +104 -0
- package/apps/runtime/dist/tools/net-guard.js +170 -0
- package/apps/runtime/dist/tools/pages.js +81 -0
- package/apps/runtime/dist/tools/plugin.js +180 -0
- package/apps/runtime/dist/tools/project.js +154 -0
- package/apps/runtime/dist/tools/shared.js +69 -0
- package/apps/runtime/dist/tools/store.js +238 -0
- package/apps/runtime/dist/update.js +113 -0
- package/apps/runtime/dist/widgets/bundle.js +99 -0
- package/apps/runtime/dist/widgets/render.js +329 -0
- package/apps/runtime/dist/widgets/runtime.js +108 -0
- package/apps/runtime/dist/widgets/script.js +30 -0
- package/apps/runtime/dist/widgets/step.js +223 -0
- package/apps/web/dist/ai-labels/ai-black.svg +20 -0
- package/apps/web/dist/ai-labels/ai-generated-black.svg +31 -0
- package/apps/web/dist/ai-labels/ai-generated-white.svg +32 -0
- package/apps/web/dist/ai-labels/ai-modified-black.svg +30 -0
- package/apps/web/dist/ai-labels/ai-modified-white.svg +31 -0
- package/apps/web/dist/ai-labels/ai-white.svg +21 -0
- package/apps/web/dist/assets/AboutDialog-D4mvc-zu.js +1 -0
- package/apps/web/dist/assets/ChangelogDialog-DLqpJsF6.js +1 -0
- package/apps/web/dist/assets/ChatView-3laypRcE.js +10 -0
- package/apps/web/dist/assets/EditorPage-BalA5U2Y.js +3 -0
- package/apps/web/dist/assets/FlowPreview-CusP7ci9.js +1 -0
- package/apps/web/dist/assets/Harness-BrP-ENHg.css +1 -0
- package/apps/web/dist/assets/Harness-iYLtOLaK.js +16 -0
- package/apps/web/dist/assets/NewWizardChannels-CbwJ9A56.js +1 -0
- package/apps/web/dist/assets/NewWizardPage-BOBYiB9i.js +7 -0
- package/apps/web/dist/assets/OnboardingPage-CUwCiVIr.js +1 -0
- package/apps/web/dist/assets/ProjectPage-Bb16MdYG.js +1 -0
- package/apps/web/dist/assets/PublicRunner-BCt7Q6C-.js +1 -0
- package/apps/web/dist/assets/ReadOnly-kIHX2TEy.js +1 -0
- package/apps/web/dist/assets/RunDrawer-hZ9oeSXu.js +4 -0
- package/apps/web/dist/assets/RunnerView-DUS9fPmx.js +1 -0
- package/apps/web/dist/assets/SettingsPage-BzwR50fi.js +1 -0
- package/apps/web/dist/assets/SetupPage-gAp7rPxp.js +1 -0
- package/apps/web/dist/assets/SharePage-DqZWHva_.js +1 -0
- package/apps/web/dist/assets/changelog-DugmCNSf.js +1 -0
- package/apps/web/dist/assets/engenty-eXZ-EAwd.js +1 -0
- package/apps/web/dist/assets/esm-DXeMu8Lb.js +7 -0
- package/apps/web/dist/assets/fluffy-engenty-ClRou7yu.js +456 -0
- package/apps/web/dist/assets/index-AfUa8xKD.css +1 -0
- package/apps/web/dist/assets/index-C5Sm7tTR.js +14 -0
- package/apps/web/dist/assets/jsx-runtime-BNakU3Ej.js +1 -0
- package/apps/web/dist/assets/lock-R_CfU0Xo.js +1 -0
- package/apps/web/dist/assets/oss-credits-cZ9NUaLZ.js +1 -0
- package/apps/web/dist/assets/pdfmake-Cx9scTbD.js +228 -0
- package/apps/web/dist/assets/phone-CgrIS4_-.js +1 -0
- package/apps/web/dist/assets/preload-helper-CNEI7N0N.js +1 -0
- package/apps/web/dist/assets/qr-scanner-worker.min-CJaXo3yu.js +98 -0
- package/apps/web/dist/assets/qr-scanner.min-C_UI0gH-.js +1 -0
- package/apps/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/apps/web/dist/assets/settings-menu-2IMOOlLl.js +1 -0
- package/apps/web/dist/assets/ui-dzGvc3xk.js +137 -0
- package/apps/web/dist/assets/upload-BSuTilFF.js +1 -0
- package/apps/web/dist/assets/vfs_fonts-DllDSYt1.js +1 -0
- package/apps/web/dist/embed.js +266 -0
- package/apps/web/dist/favicon.svg +1 -0
- package/apps/web/dist/icons/apple-touch-icon.png +0 -0
- package/apps/web/dist/icons/icon-192.png +0 -0
- package/apps/web/dist/icons/icon-512.png +0 -0
- package/apps/web/dist/icons/icon-maskable-512.png +0 -0
- package/apps/web/dist/index.html +48 -0
- package/apps/web/dist/install.sh +577 -0
- package/apps/web/dist/manifest.webmanifest +21 -0
- package/apps/web/dist/mcp/flow.html +980 -0
- package/apps/web/dist/sw.js +15 -0
- package/bin/wizards.mjs +288 -0
- package/modules/README.md +15 -0
- package/node_modules/@engenty/wizards/dist/plugin/index.d.ts +1150 -0
- package/node_modules/@engenty/wizards/dist/plugin/index.js +4 -0
- package/node_modules/@engenty/wizards/dist/plugin/studio.d.ts +322 -0
- package/node_modules/@engenty/wizards/dist/plugin/studio.js +4 -0
- package/node_modules/@engenty/wizards/dist/plugin/thread.d.ts +174 -0
- package/node_modules/@engenty/wizards/dist/plugin/thread.js +821 -0
- package/node_modules/@engenty/wizards/package.json +11 -0
- package/node_modules/@engenty-wizards/shared/dist/assistant.d.ts +174 -0
- package/node_modules/@engenty-wizards/shared/dist/assistant.js +65 -0
- package/node_modules/@engenty-wizards/shared/dist/changes.d.ts +22 -0
- package/node_modules/@engenty-wizards/shared/dist/changes.js +61 -0
- package/node_modules/@engenty-wizards/shared/dist/connectors.d.ts +77 -0
- package/node_modules/@engenty-wizards/shared/dist/connectors.js +2 -0
- package/node_modules/@engenty-wizards/shared/dist/decision.d.ts +76 -0
- package/node_modules/@engenty-wizards/shared/dist/decision.js +147 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +2922 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.js +1920 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.d.ts +5 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-format.js +132 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.d.ts +11 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns-value.js +209 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.d.ts +532 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/columns.js +217 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.d.ts +3 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/data-tables/index.js +3 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.d.ts +14 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-lexical.js +166 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.d.ts +33 -0
- package/node_modules/@engenty-wizards/shared/dist/engenty/search-index/catalog-rank.js +99 -0
- package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +78 -0
- package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +70 -0
- package/node_modules/@engenty-wizards/shared/dist/features.d.ts +41 -0
- package/node_modules/@engenty-wizards/shared/dist/features.js +89 -0
- package/node_modules/@engenty-wizards/shared/dist/fit.d.ts +71 -0
- package/node_modules/@engenty-wizards/shared/dist/fit.js +382 -0
- package/node_modules/@engenty-wizards/shared/dist/json-schema.d.ts +14 -0
- package/node_modules/@engenty-wizards/shared/dist/json-schema.js +66 -0
- package/node_modules/@engenty-wizards/shared/dist/knowledge.d.ts +199 -0
- package/node_modules/@engenty-wizards/shared/dist/knowledge.js +68 -0
- package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.d.ts +35 -0
- package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +107 -0
- package/node_modules/@engenty-wizards/shared/dist/marketplace-search.d.ts +20 -0
- package/node_modules/@engenty-wizards/shared/dist/marketplace-search.js +136 -0
- package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +227 -0
- package/node_modules/@engenty-wizards/shared/dist/marketplace.js +354 -0
- package/node_modules/@engenty-wizards/shared/dist/merge.d.ts +7 -0
- package/node_modules/@engenty-wizards/shared/dist/merge.js +40 -0
- package/node_modules/@engenty-wizards/shared/dist/numbers.d.ts +24 -0
- package/node_modules/@engenty-wizards/shared/dist/numbers.js +54 -0
- package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +224 -0
- package/node_modules/@engenty-wizards/shared/dist/projects.js +319 -0
- package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +101 -0
- package/node_modules/@engenty-wizards/shared/dist/providers.js +390 -0
- package/node_modules/@engenty-wizards/shared/dist/run.d.ts +680 -0
- package/node_modules/@engenty-wizards/shared/dist/run.js +620 -0
- package/node_modules/@engenty-wizards/shared/dist/runner-texts.d.ts +546 -0
- package/node_modules/@engenty-wizards/shared/dist/runner-texts.js +523 -0
- package/node_modules/@engenty-wizards/shared/dist/runners.d.ts +93 -0
- package/node_modules/@engenty-wizards/shared/dist/runners.js +146 -0
- package/node_modules/@engenty-wizards/shared/dist/shape.d.ts +102 -0
- package/node_modules/@engenty-wizards/shared/dist/shape.js +318 -0
- package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +89 -0
- package/node_modules/@engenty-wizards/shared/dist/space-data.js +47 -0
- package/node_modules/@engenty-wizards/shared/dist/store.d.ts +117 -0
- package/node_modules/@engenty-wizards/shared/dist/store.js +81 -0
- package/node_modules/@engenty-wizards/shared/dist/surface.d.ts +115 -0
- package/node_modules/@engenty-wizards/shared/dist/surface.js +442 -0
- package/node_modules/@engenty-wizards/shared/dist/texts.d.ts +45 -0
- package/node_modules/@engenty-wizards/shared/dist/texts.js +54 -0
- package/node_modules/@engenty-wizards/shared/dist/translation.d.ts +23 -0
- package/node_modules/@engenty-wizards/shared/dist/translation.js +154 -0
- package/node_modules/@engenty-wizards/shared/dist/wizard-package.d.ts +48 -0
- package/node_modules/@engenty-wizards/shared/dist/wizard-package.js +49 -0
- package/node_modules/@engenty-wizards/shared/dist/workspace.d.ts +16 -0
- package/node_modules/@engenty-wizards/shared/dist/workspace.js +51 -0
- package/node_modules/@engenty-wizards/shared/package.json +10 -0
- package/package.json +77 -4
- package/plugin/.claude-plugin/plugin.json +9 -0
- package/plugin/.mcp.json +8 -0
- package/plugin/commands/wizard.md +8 -0
- package/plugin/skills/build-wizard/SKILL.md +27 -0
- package/plugin/skills/use-wizard/SKILL.md +18 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Starters
|
|
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
|
+
---
|
|
6
|
+
|
|
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
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
12
|
+
|
|
13
|
+
const read = (path: string) => readFileSync(wizards.resolvePath(path), "utf8");
|
|
14
|
+
|
|
15
|
+
server.registerStarter({
|
|
16
|
+
id: "follow-up",
|
|
17
|
+
title: "Follow up a contact",
|
|
18
|
+
description: "Looks the person up and drafts a follow-up email.",
|
|
19
|
+
language: "en",
|
|
20
|
+
definition: JSON.parse(read("starters/follow-up.json")),
|
|
21
|
+
files: { "widget/card.html": read("starters/card.html") },
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Field | |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `id` | Lower case, digits and `-`, starting with a letter, at most 40 characters. Unique in the plugin |
|
|
28
|
+
| `title` | What the list of templates calls it |
|
|
29
|
+
| `description` | What it makes, in one or two sentences. Shown under the title |
|
|
30
|
+
| `language` | `"de"` or `"en"`, the language its texts are in. Default: `"en"` |
|
|
31
|
+
| `definition` | A complete wizard definition: the JSON the studio keeps and `get_authoring_guide` describes |
|
|
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
|
+
|
|
34
|
+
## Checked when it is registered
|
|
35
|
+
|
|
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
|
+
|
|
40
|
+
```
|
|
41
|
+
Starter "follow-up": steps.2.fields: …
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Where it shows
|
|
45
|
+
|
|
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
|
+
|
|
49
|
+
| Where | |
|
|
50
|
+
|---|---|
|
|
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
|
+
| `GET /api/studio/marketplace` | First on the first page, with `plugin: { id, name }` |
|
|
53
|
+
| MCP `list_starters`, `get_starter`, `create_wizard` | Listed first with `plugin`; `starterId` takes its id |
|
|
54
|
+
| `GET /api/v1/templates`, for programs with a key | First, with `plugin`; `POST /api/v1/wizards` takes its id as `starterId` |
|
|
55
|
+
|
|
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)). 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.
|
|
63
|
+
|
|
64
|
+
## A wizard made from it
|
|
65
|
+
|
|
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.
|
|
70
|
+
- is not counted at the marketplace.
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: The studio half
|
|
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
|
+
---
|
|
6
|
+
|
|
7
|
+
The studio half is `ui/plugin.tsx`. Its default export is a function; the studio calls it after
|
|
8
|
+
sign-in and hands it `studio`. What the plugin draws is part of the studio: the same React, the
|
|
9
|
+
same router, the same components.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { defineStudioPlugin } from "@engenty/wizards/plugin/studio";
|
|
13
|
+
import { Button, Card, Empty, Spinner } from "@engenty-wizards/web/ui";
|
|
14
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
15
|
+
import { Users } from "lucide-react";
|
|
16
|
+
|
|
17
|
+
interface Person {
|
|
18
|
+
id: number;
|
|
19
|
+
email: string;
|
|
20
|
+
name: string | null;
|
|
21
|
+
wizard: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const messages = {
|
|
25
|
+
de: {
|
|
26
|
+
title: "Kontakte",
|
|
27
|
+
hint: "Wer einen Wizard bis zum Ende durchlaufen hat.",
|
|
28
|
+
empty: "Noch keine Kontakte.",
|
|
29
|
+
remove: "Entfernen",
|
|
30
|
+
},
|
|
31
|
+
en: {
|
|
32
|
+
title: "Contacts",
|
|
33
|
+
hint: "Everyone who ran a wizard to its end.",
|
|
34
|
+
empty: "No contacts yet.",
|
|
35
|
+
remove: "Remove",
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default defineStudioPlugin((studio) => {
|
|
40
|
+
const t = studio.i18n.register(messages);
|
|
41
|
+
|
|
42
|
+
function ContactsPage() {
|
|
43
|
+
const list = useQuery({
|
|
44
|
+
queryKey: ["contacts"],
|
|
45
|
+
queryFn: () => studio.api.get<{ contacts: Person[] }>("/"),
|
|
46
|
+
});
|
|
47
|
+
const cache = useQueryClient();
|
|
48
|
+
const remove = useMutation({
|
|
49
|
+
mutationFn: (id: number) => studio.api.del(`/${id}`),
|
|
50
|
+
onSuccess: () => cache.invalidateQueries({ queryKey: ["contacts"] }),
|
|
51
|
+
});
|
|
52
|
+
const admin = studio.me().tenant.role !== "member";
|
|
53
|
+
return (
|
|
54
|
+
<div>
|
|
55
|
+
<h1 className="font-display font-semibold text-[1.75rem] tracking-tight">{t("title")}</h1>
|
|
56
|
+
<p className="mt-1 text-[0.9375rem] text-ink-3">{t("hint")}</p>
|
|
57
|
+
<div className="mt-8 flex flex-col gap-2">
|
|
58
|
+
{list.isLoading ? <Spinner className="mx-auto" /> : null}
|
|
59
|
+
{list.data && !list.data.contacts.length ? <Empty>{t("empty")}</Empty> : null}
|
|
60
|
+
{list.data?.contacts.map((person) => (
|
|
61
|
+
<Card key={person.id} className="flex items-center gap-3 px-5 py-3.5">
|
|
62
|
+
<span className="min-w-0 flex-1 truncate font-medium text-[0.9375rem]">
|
|
63
|
+
{person.name ?? person.email}
|
|
64
|
+
</span>
|
|
65
|
+
<span className="text-[0.8125rem] text-ink-3 max-sm:hidden">{person.wizard}</span>
|
|
66
|
+
{admin ? (
|
|
67
|
+
<Button variant="ghost" size="sm" onClick={() => remove.mutate(person.id)}>
|
|
68
|
+
{t("remove")}
|
|
69
|
+
</Button>
|
|
70
|
+
) : null}
|
|
71
|
+
</Card>
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
studio.registerPage({ path: "/contacts", component: ContactsPage });
|
|
79
|
+
studio.registerNav({ to: "/contacts", label: () => t("title"), icon: Users });
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## What it registers
|
|
84
|
+
|
|
85
|
+
| Call | Adds |
|
|
86
|
+
|---|---|
|
|
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
|
+
| `studio.registerNav({ to, label, icon })` | An icon in the app bar that opens a page |
|
|
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’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) |
|
|
95
|
+
|
|
96
|
+
- The studio’s own addresses are taken: `/new`, `/edit`, `/settings`, `/space`, `/setup`,
|
|
97
|
+
`/sign-in`.
|
|
98
|
+
- The settings’ own sections are taken as ids: `account`, `team`, `connectors`, `models`,
|
|
99
|
+
`integrate` and `plugins`.
|
|
100
|
+
- `label` is a function, since the language can change while the studio is open.
|
|
101
|
+
- `icon` is a component that takes `className`: any icon of `lucide-react`.
|
|
102
|
+
|
|
103
|
+
A settings section draws its own heading and cards:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
function ContactsSettings() {
|
|
107
|
+
return (
|
|
108
|
+
<section className="flex flex-col gap-2.5">
|
|
109
|
+
<h2 className="px-1 font-display font-semibold text-lg leading-tight">{t("title")}</h2>
|
|
110
|
+
<Card className="p-5 text-[0.875rem] text-ink-2">…</Card>
|
|
111
|
+
</section>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
studio.registerSettingsSection({
|
|
116
|
+
id: "contacts",
|
|
117
|
+
label: () => t("title"),
|
|
118
|
+
icon: Users,
|
|
119
|
+
component: ContactsSettings,
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## The space
|
|
124
|
+
|
|
125
|
+
A space holds what all its wizards share: a title, logos, colours, facts and Knowledge. The
|
|
126
|
+
space page, behind the house icon (Space) in the app bar, shows them in four parts:
|
|
127
|
+
|
|
128
|
+
| Part | `group` | Holds |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| Info & brand | `info` | Basics, Facts, Logos, Colours, Brand assets |
|
|
131
|
+
| Knowledge | `knowledge` | Documents, pages, tables and files with their categories: what every AI step looks things up in |
|
|
132
|
+
| Data | `data` | What the wizards keep |
|
|
133
|
+
| Results | `results` | The runs that reached their result |
|
|
134
|
+
|
|
135
|
+
A plugin adds a section to one of them, below the part’s own:
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
function ContactsOfSpace() {
|
|
139
|
+
const space = studio.useSpace();
|
|
140
|
+
const list = useQuery({
|
|
141
|
+
queryKey: ["contacts", space?.id],
|
|
142
|
+
queryFn: () => studio.api.get<{ contacts: Person[] }>(`/?space=${space?.id}`),
|
|
143
|
+
enabled: Boolean(space),
|
|
144
|
+
});
|
|
145
|
+
return <Card className="p-5 text-[0.875rem] text-ink-2">…</Card>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
studio.registerSpaceSection({
|
|
149
|
+
id: "contacts",
|
|
150
|
+
group: "data",
|
|
151
|
+
label: () => t("title"),
|
|
152
|
+
hint: () => t("hint"),
|
|
153
|
+
component: ContactsOfSpace,
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- `group` is the part; without one the section stands under Knowledge.
|
|
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
|
|
160
|
+
rest, usually a `Card`.
|
|
161
|
+
- `id` is the section’s anchor: `/studio/space/data#contacts` opens the page there, and so does
|
|
162
|
+
`/studio/space#contacts`. In Knowledge a section is a page of its own:
|
|
163
|
+
`/studio/space/knowledge?show=s:<id>`, where `#<id>` leads too. Ids are unique on the whole
|
|
164
|
+
page; the space’s own are taken: `base`, `facts`, `logos`, `colors`, `typography`, `assets`,
|
|
165
|
+
`documents`.
|
|
166
|
+
- `studio.useSpace()` is a hook: `{ id, name, readOnly, brand }`, or `null` while there is none.
|
|
167
|
+
A component that calls it draws again when the person picks another space, or changes its
|
|
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 }`).
|
|
172
|
+
- Every wizard belongs to a space: a [run event](./events.md) names it as
|
|
173
|
+
`wizard.projectId`. Keep it with what the plugin stores to show a space’s part of it.
|
|
174
|
+
|
|
175
|
+
### A part of the plugin’s own
|
|
176
|
+
|
|
177
|
+
A plugin whose subject is as big as one of the parts adds a part of its own: an entry in the
|
|
178
|
+
parts’ menu, with a page at `/studio/space/<id>` that the plugin draws whole. The part’s menu
|
|
179
|
+
lists what the page holds; `studio.useSpaceMenu` fills it while the page is drawn.
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
function Library() {
|
|
183
|
+
const space = studio.useSpace();
|
|
184
|
+
const sections = useSections(space?.id);
|
|
185
|
+
studio.useSpaceMenu(sections.map((s) => ({ id: s.id, label: s.title, icon: Component })));
|
|
186
|
+
return sections.map((s) => (
|
|
187
|
+
<Anchor key={s.id} id={s.id}>
|
|
188
|
+
<Section title={s.title}>…</Section>
|
|
189
|
+
</Anchor>
|
|
190
|
+
));
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
studio.registerSpacePart({
|
|
194
|
+
id: "library",
|
|
195
|
+
label: () => t("title"),
|
|
196
|
+
icon: Blocks,
|
|
197
|
+
after: "info",
|
|
198
|
+
component: Library,
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
- `id` is the address: `/studio/space/library`. The parts’ own (`info`, `knowledge`, `data`,
|
|
203
|
+
`results`) are taken.
|
|
204
|
+
- `after` is the part it follows in the menu: `info`, `knowledge` or `data` (default).
|
|
205
|
+
- Each entry of `useSpaceMenu` jumps to the element with its `id` in what the part draws, and
|
|
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.
|
|
208
|
+
|
|
209
|
+
## Words in two languages
|
|
210
|
+
|
|
211
|
+
The studio speaks German and English. `studio.i18n.register` takes the plugin’s words and gives
|
|
212
|
+
the function that reads them in the language in effect:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
const t = studio.i18n.register({
|
|
216
|
+
de: { count: "{n} Kontakte sind gespeichert." },
|
|
217
|
+
en: { count: "{n} contacts are kept." },
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
t("count", { n: 12 });
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
- `de` is the source: a key missing in `en` shows the German, so give every key in both.
|
|
224
|
+
- `{name}` in a text is filled from the second argument.
|
|
225
|
+
- `studio.i18n.lang()` is `"de"` or `"en"`, for dates and numbers:
|
|
226
|
+
`new Date(at).toLocaleString(studio.i18n.lang())`.
|
|
227
|
+
|
|
228
|
+
## The plugin’s own routes
|
|
229
|
+
|
|
230
|
+
`studio.api` calls the routes the server half registered, signed in as the person:
|
|
231
|
+
|
|
232
|
+
| Call | Asks |
|
|
233
|
+
|---|---|
|
|
234
|
+
| `studio.api.get<T>(path)` | `GET /api/studio/plugins/<id><path>` |
|
|
235
|
+
| `studio.api.post<T>(path, body?)` | `POST`, the body as JSON |
|
|
236
|
+
| `studio.api.put<T>(path, body?)`, `studio.api.patch<T>(path, body?)` | `PUT`, `PATCH` |
|
|
237
|
+
| `studio.api.del<T>(path)` | `DELETE` |
|
|
238
|
+
|
|
239
|
+
Each gives the parsed JSON. Use them with `useQuery` and `useMutation`, as the page above does.
|
|
240
|
+
|
|
241
|
+
## The person
|
|
242
|
+
|
|
243
|
+
`studio.me()` is the signed-in person:
|
|
244
|
+
|
|
245
|
+
| | |
|
|
246
|
+
|---|---|
|
|
247
|
+
| `user` | `{ id, name, email }` |
|
|
248
|
+
| `tenant` | `{ id, role }`, the role `owner`, `admin` or `member` |
|
|
249
|
+
| `mode` | `"local"`: the runtime runs alone. `"managed"`: on engenty.ai |
|
|
250
|
+
|
|
251
|
+
Hide what a member may not do, and guard it on the server too with `role: "admin"` on the
|
|
252
|
+
route.
|
|
253
|
+
|
|
254
|
+
`studio.plugin` is the plugin itself: `{ id, name, version }`.
|
|
255
|
+
|
|
256
|
+
## Where the page stands
|
|
257
|
+
|
|
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:
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
studio.useCrumbs([{ label: t("title"), to: "/contacts" }, { label: person.name ?? person.email }]);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
- Each step is `{ label, to? }`; the last one is the page itself. A phone does not show the trail.
|
|
266
|
+
- The assistant names the page by its trail.
|
|
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
|
+
|
|
303
|
+
## The assistant
|
|
304
|
+
|
|
305
|
+
The studio’s assistant stands on a plugin’s pages too. `studio.Assistant`,
|
|
306
|
+
`studio.useAssistantPage` and `studio.useAssistantTool` tell it what to say there, what the page
|
|
307
|
+
shows and what it may do in it. See [The space](./space.md#the-assistant-on-the-plugins-own-page).
|
|
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
|
+
|
|
312
|
+
## Build it
|
|
313
|
+
|
|
314
|
+
The studio half is built to two files, `dist/client.js` and `dist/client.css`. The build needs
|
|
315
|
+
a checkout of the repository, since it uses the studio’s own tools:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
node scripts/build-plugin.mjs <plugin folder>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
node scripts/build-plugin.mjs <plugin folder> --watch
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
The plugin’s folder may be anywhere, also outside the checkout. With `--watch` the files are
|
|
326
|
+
built again on every save, and an open studio takes them in place.
|
|
327
|
+
|
|
328
|
+
Ship `dist/` with the plugin: an install without a checkout cannot build it.
|
|
329
|
+
|
|
330
|
+
## What the studio shares
|
|
331
|
+
|
|
332
|
+
These imports are not in `client.js`. The script takes them from the studio that loads it, so
|
|
333
|
+
there is one React and one router on the page:
|
|
334
|
+
|
|
335
|
+
| Import | What a plugin gets of it |
|
|
336
|
+
|---|---|
|
|
337
|
+
| `react`, `react/jsx-runtime` | All of it |
|
|
338
|
+
| `react-dom` | `createPortal`, `flushSync` |
|
|
339
|
+
| `react-router` | `Link`, `NavLink`, `Navigate`, `useNavigate`, `useParams`, `useLocation`, `useSearchParams` |
|
|
340
|
+
| `@tanstack/react-query` | `useQuery`, `useMutation`, `useQueryClient` |
|
|
341
|
+
| `@engenty-wizards/web/ui` | The studio’s components, see [Styles and components](./styling.md) |
|
|
342
|
+
| `@engenty/wizards/plugin/studio` | `defineStudioPlugin` and the types |
|
|
343
|
+
|
|
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.
|
|
346
|
+
|
|
347
|
+
## Undo on reload
|
|
348
|
+
|
|
349
|
+
The studio half loads again when its built files change. Pages, icons and sections, also those
|
|
350
|
+
of the space page, are taken back for it. Anything else it started, it undoes itself:
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
const timer = setInterval(refresh, 30_000);
|
|
354
|
+
studio.onUnload(() => clearInterval(timer));
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## When it fails
|
|
358
|
+
|
|
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
|
|
363
|
+
place. The rest of the studio stays up.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Styles and components
|
|
3
|
+
description: The studio's components, Tailwind against the studio's theme, and why a plugin's styles never leak.
|
|
4
|
+
version: 0.5.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
A plugin’s page should look like the studio. Two things make that easy: the studio’s components
|
|
8
|
+
and its theme.
|
|
9
|
+
|
|
10
|
+
## Components
|
|
11
|
+
|
|
12
|
+
`@engenty-wizards/web/ui` is what the studio itself is drawn with:
|
|
13
|
+
|
|
14
|
+
| Component | For | Props beside the element’s own |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `Button` | An action | `variant`: `primary` (default), `secondary`, `ghost`, `quiet`, `danger` · `size`: `sm`, `md`, `lg` · `busy` |
|
|
17
|
+
| `IconButton` | An action that is only an icon | `label`: its name for screen readers and the tooltip |
|
|
18
|
+
| `Input`, `Textarea` | Text. The textarea grows with its content | `minRows`, `maxRows` on the textarea |
|
|
19
|
+
| `Select` | One of a list | `value`, `onChange(value)`, `options: { value, label, disabled? }[]`, `placeholder` |
|
|
20
|
+
| `Segmented` | One or several of a few | `value`, `onChange`, `options: string[]`, `multi`, `disabled` (options shown but not to be picked) |
|
|
21
|
+
| `Tabs` | A row of tabs; the panels are yours | `value`, `onChange`, `options: { id, label }[]`, `label` (for screen readers) |
|
|
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` |
|
|
25
|
+
| `Card` | A surface | |
|
|
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` |
|
|
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` |
|
|
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) |
|
|
32
|
+
| `Composer` | The field a message is written in: text, dictation, files, send | `onSend(text, files)` (false keeps the draft), `placeholder`, `disabled`, `attach`, `floating` |
|
|
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) |
|
|
34
|
+
| `Spinner`, `Empty` | Loading, and nothing there yet | |
|
|
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) |
|
|
37
|
+
| `cn(...)` | Joins class names, skipping what is false | |
|
|
38
|
+
| `dateText(date, withWeekday?)` | A “YYYY-MM-DD” date in the studio’s language: “Wed 14 Oct 2026” | |
|
|
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) |
|
|
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` | |
|
|
45
|
+
| `newId()` | A short id for something new | |
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { Button, Card, Chip, Label, Input } from "@engenty-wizards/web/ui";
|
|
49
|
+
|
|
50
|
+
<Card className="flex flex-col gap-4 p-5">
|
|
51
|
+
<Label hint="Where the message goes.">Address</Label>
|
|
52
|
+
<Input value={url} onChange={(e) => setUrl(e.target.value)} />
|
|
53
|
+
<div className="flex items-center gap-3">
|
|
54
|
+
<Button busy={save.isPending} onClick={() => save.mutate()}>Save</Button>
|
|
55
|
+
<Chip tone="live">connected</Chip>
|
|
56
|
+
</div>
|
|
57
|
+
</Card>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Icons are from `lucide-react`.
|
|
61
|
+
|
|
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`.
|
|
66
|
+
|
|
67
|
+
## Tailwind
|
|
68
|
+
|
|
69
|
+
A plugin writes Tailwind classes, as the studio does. The build collects the classes the
|
|
70
|
+
plugin’s files use into `dist/client.css`.
|
|
71
|
+
|
|
72
|
+
The theme’s names are the studio’s:
|
|
73
|
+
|
|
74
|
+
| | Names |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Surfaces | `bg-paper`, `bg-paper-2`, `bg-paper-3`, `bg-card`, `bg-popover`, `bg-accent` |
|
|
77
|
+
| Text | `text-ink`, `text-ink-2`, `text-ink-3`, `text-ink-4` |
|
|
78
|
+
| Lines | `border-border`, `border-border-soft`, `ring-border-soft` |
|
|
79
|
+
| The accent | `ember`, `ember-strong`, `ember-tint`; `primary`, `primary-foreground` |
|
|
80
|
+
| States | `moss` and `moss-tint` (good), `amber` and `amber-tint` (attention), `rose` and `rose-tint` (danger), `cobalt` and `cobalt-tint` (information) |
|
|
81
|
+
| Type | `font-sans`, `font-display` (headings), `font-mono` |
|
|
82
|
+
| Corners | `rounded-sm` to `rounded-3xl`, from the theme’s radius |
|
|
83
|
+
| Shadows | `shadow-soft`, `shadow-elevated`, `shadow-overlay` |
|
|
84
|
+
| Variants | `dark:` and `coarse:` (a finger, not a mouse) beside Tailwind’s own |
|
|
85
|
+
|
|
86
|
+
The full list is
|
|
87
|
+
[packages/runner/src/theme.css](https://github.com/engenty/wizards/blob/main/packages/runner/src/theme.css):
|
|
88
|
+
the studio and a wizard’s run page share it.
|
|
89
|
+
|
|
90
|
+
## Rules
|
|
91
|
+
|
|
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
|
|
97
|
+
components do that themselves.
|
|
98
|
+
- **Don’t style outside your own part.** It would not work anyway: see below.
|
|
99
|
+
|
|
100
|
+
## Why a plugin’s styles never leak
|
|
101
|
+
|
|
102
|
+
`client.css` is built so that it cannot change how the studio looks:
|
|
103
|
+
|
|
104
|
+
- Every rule applies only inside what the plugin draws. The studio wraps each page, section,
|
|
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
|
|
110
|
+
and no resets.
|
|
111
|
+
|
|
112
|
+
## Your own CSS
|
|
113
|
+
|
|
114
|
+
A stylesheet imported in `ui/plugin.tsx` lands in `client.css` as it is:
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
import "./contacts.css";
|
|
118
|
+
```
|
|
119
|
+
|
|
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)`.
|
|
123
|
+
|
|
124
|
+
## The theme is a contract
|
|
125
|
+
|
|
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.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
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.5.0
|
|
5
|
+
---
|
|
6
|
+
|
|
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
|
+
|
|
10
|
+
## 1. The table, as SQL
|
|
11
|
+
|
|
12
|
+
`migrations/0001_init.sql`:
|
|
13
|
+
|
|
14
|
+
```sql
|
|
15
|
+
CREATE TABLE contacts_person (
|
|
16
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
|
+
email TEXT NOT NULL UNIQUE,
|
|
18
|
+
name TEXT,
|
|
19
|
+
wizard TEXT NOT NULL,
|
|
20
|
+
seen_at INTEGER NOT NULL
|
|
21
|
+
);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Register the folder when the plugin loads:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
server.registerMigrations("migrations");
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 2. The table, for Drizzle
|
|
31
|
+
|
|
32
|
+
`src/schema.ts` describes the same table, so queries are typed:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
36
|
+
|
|
37
|
+
export const person = sqliteTable("contacts_person", {
|
|
38
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
39
|
+
email: text("email").notNull().unique(),
|
|
40
|
+
name: text("name"),
|
|
41
|
+
wizard: text("wizard").notNull(),
|
|
42
|
+
seenAt: integer("seen_at", { mode: "timestamp_ms" }).notNull(),
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The runtime does not read this file. It is yours: keep it in step with the SQL by hand.
|
|
47
|
+
|
|
48
|
+
## 3. Read and write
|
|
49
|
+
|
|
50
|
+
`server.getTenantDb()` is the database of the tenant the current request, step or event belongs
|
|
51
|
+
to, as a Drizzle database:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { desc, eq } from "drizzle-orm";
|
|
55
|
+
import { person } from "./schema";
|
|
56
|
+
|
|
57
|
+
const db = () => server.getTenantDb();
|
|
58
|
+
|
|
59
|
+
const newest = await db().select().from(person).orderBy(desc(person.seenAt)).limit(200);
|
|
60
|
+
|
|
61
|
+
await db()
|
|
62
|
+
.insert(person)
|
|
63
|
+
.values({ email, name, wizard, seenAt: new Date() })
|
|
64
|
+
.onConflictDoUpdate({ target: person.email, set: { name, wizard, seenAt: new Date() } });
|
|
65
|
+
|
|
66
|
+
await db().delete(person).where(eq(person.id, id));
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Call `getTenantDb()` inside the handler, the tool, the listener or the job. Outside of them
|
|
70
|
+
there is no tenant.
|
|
71
|
+
|
|
72
|
+
## How the files run
|
|
73
|
+
|
|
74
|
+
| | |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Once | Each `.sql` file runs once per tenant database. The table `plugin_migration` records which ran |
|
|
77
|
+
| In order | By file name: `0001_init.sql`, `0002_note.sql` |
|
|
78
|
+
| Whole or not | A file and its record go in together or not at all. A file may hold several statements |
|
|
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
|
+
| Never back | Nothing is taken back. Unloading or removing a plugin leaves its tables and rows |
|
|
81
|
+
|
|
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
|
+
|
|
86
|
+
## Rules
|
|
87
|
+
|
|
88
|
+
- **Begin table names with the plugin’s id**: `contacts_person`. All plugins and the runtime
|
|
89
|
+
share the database. A `-` in the id becomes `_`.
|
|
90
|
+
- **Never change a file that ran.** It will not run again. Add a new file:
|
|
91
|
+
|
|
92
|
+
```sql
|
|
93
|
+
ALTER TABLE contacts_person ADD COLUMN phone TEXT;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- **Do not touch the runtime’s own tables** in a migration. Their shape changes with releases.
|
|
97
|
+
- **Dates** are integers in milliseconds (`mode: "timestamp_ms"`); they leave a route as ISO
|
|
98
|
+
strings.
|
|
99
|
+
|
|
100
|
+
## The runtime’s own data
|
|
101
|
+
|
|
102
|
+
`getTenantDb()` reaches the whole tenant database, the runtime’s tables included. They are not
|
|
103
|
+
a public interface: a release can rename a column. A plugin that must know about runs listens
|
|
104
|
+
to [run events](./events.md) and keeps what it needs in its own table.
|