@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,276 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { existsSync, mkdirSync, openSync, readFileSync } from "node:fs";
|
|
4
|
+
import { createServer } from "node:net";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import { mintLocalTicket } from "../auth/local-ticket.js";
|
|
7
|
+
import { readRunning } from "../running.js";
|
|
8
|
+
import { RESTART_EXIT } from "../update.js";
|
|
9
|
+
import { applyPendingUpdate, autoUpdatePolicy, notesUrl } from "./autoupdate.js";
|
|
10
|
+
import { runtimeEnv } from "./environment.js";
|
|
11
|
+
import { installedByScript, packageRoot, readEnvFile } from "./home.js";
|
|
12
|
+
import { findOnPath } from "./machine.js";
|
|
13
|
+
import { cmd, cyan, dim, live, tilde } from "./ui.js";
|
|
14
|
+
const DEFAULT_PORT = 24368;
|
|
15
|
+
const START_TIMEOUT_MS = 60_000;
|
|
16
|
+
/** The settings this install starts with: its `.env`, overridden by the terminal's variables. */
|
|
17
|
+
export function settings(paths, env = process.env) {
|
|
18
|
+
const fileEnv = readEnvFile(paths.envFile);
|
|
19
|
+
const value = (key) => env[key]?.trim() || fileEnv[key]?.trim() || "";
|
|
20
|
+
return {
|
|
21
|
+
fileEnv,
|
|
22
|
+
dataDir: value("DATA_DIR") ? resolve(paths.home, value("DATA_DIR")) : paths.data,
|
|
23
|
+
port: Number(value("API_PORT")) || null,
|
|
24
|
+
appUrl: value("APP_URL").replace(/\/$/, ""),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The secret the runtime this command starts signs with, read the way it reads it (env.ts): its
|
|
29
|
+
* APP_SECRET, else the one it keeps in the data folder; null before it made one. The runtime
|
|
30
|
+
* never sees the terminal's APP_SECRET (cli/environment.ts), only its folder's `.env.local` and
|
|
31
|
+
* `.env`, so the terminal's is left out here too: a ticket signed with it would be refused.
|
|
32
|
+
*/
|
|
33
|
+
export function readSecret(paths, env = process.env) {
|
|
34
|
+
const { fileEnv, dataDir } = settings(paths, env);
|
|
35
|
+
const given = readEnvFile(join(paths.home, ".env.local")).APP_SECRET?.trim() || fileEnv.APP_SECRET?.trim();
|
|
36
|
+
if (given) {
|
|
37
|
+
return given;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return readFileSync(join(dataDir, "secret"), "utf8").trim() || null;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export async function healthy(port) {
|
|
47
|
+
try {
|
|
48
|
+
const response = await fetch(`http://127.0.0.1:${port}/api/health`, {
|
|
49
|
+
signal: AbortSignal.timeout(1500),
|
|
50
|
+
});
|
|
51
|
+
return response.ok;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function portIsFree(port) {
|
|
58
|
+
return new Promise((done) => {
|
|
59
|
+
const probe = createServer();
|
|
60
|
+
probe.once("error", () => done(false));
|
|
61
|
+
probe.listen(port, "127.0.0.1", () => probe.close(() => done(true)));
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** The usual port, or the next free one after it. */
|
|
65
|
+
async function freePort() {
|
|
66
|
+
for (let port = DEFAULT_PORT; port < DEFAULT_PORT + 20; port++) {
|
|
67
|
+
if (await portIsFree(port)) {
|
|
68
|
+
return port;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`No free port between ${DEFAULT_PORT} and ${DEFAULT_PORT + 19}.`);
|
|
72
|
+
}
|
|
73
|
+
/** The runtime that already runs on this install's data folder and answers. */
|
|
74
|
+
export async function runningRuntime(dataDir) {
|
|
75
|
+
const running = readRunning(dataDir);
|
|
76
|
+
return running && (await healthy(running.port)) ? running : null;
|
|
77
|
+
}
|
|
78
|
+
/** A link that lets this browser into a running runtime: a ticket signed with the runtime's secret. */
|
|
79
|
+
export function entryUrl(running, paths, env = process.env) {
|
|
80
|
+
const secret = readSecret(paths, env);
|
|
81
|
+
// No secret to be read here: the browser gets in if it was let in before.
|
|
82
|
+
return secret ? `${running.url}/api/local/enter?t=${mintLocalTicket(secret)}` : `${running.url}/`;
|
|
83
|
+
}
|
|
84
|
+
/** Opens an address in the person's browser; false when this machine has none to open it with. */
|
|
85
|
+
export function openBrowser(url) {
|
|
86
|
+
const opener = process.platform === "darwin"
|
|
87
|
+
? "open"
|
|
88
|
+
: process.env.DISPLAY || process.env.WAYLAND_DISPLAY
|
|
89
|
+
? "xdg-open"
|
|
90
|
+
: null;
|
|
91
|
+
if (!opener || !findOnPath(opener, process.env.PATH ?? "")) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
spawn(opener, [url], { stdio: "ignore", detached: true }).unref();
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function show(url, entry, open) {
|
|
103
|
+
const opened = open && openBrowser(entry);
|
|
104
|
+
console.log("");
|
|
105
|
+
console.log(` ${live} engenty wizards is running: ${cyan(url)}`);
|
|
106
|
+
if (opened) {
|
|
107
|
+
console.log(dim(" The studio opens in your browser."));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.log(` Open the studio: ${cyan(entry)}`);
|
|
111
|
+
console.log(dim(" The link signs in one browser and works only once."));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** The command of this install, as it is on disk now: `wizards <args>`. */
|
|
115
|
+
function spawnCommand(paths, args, options) {
|
|
116
|
+
const wrapper = join(paths.bin, "wizards");
|
|
117
|
+
return existsSync(wrapper)
|
|
118
|
+
? spawn(wrapper, args, options)
|
|
119
|
+
: spawn(process.execPath, [join(packageRoot, "bin/wizards.mjs"), ...args], options);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* `wizards start --no-open` detached from this terminal, its output in logs/runtime.log; the
|
|
123
|
+
* runtime once it answers, or null when it ended or did not answer within a minute.
|
|
124
|
+
*/
|
|
125
|
+
export async function startInBackground(paths) {
|
|
126
|
+
const { dataDir } = settings(paths);
|
|
127
|
+
mkdirSync(paths.logs, { recursive: true });
|
|
128
|
+
const log = openSync(join(paths.logs, "runtime.log"), "a");
|
|
129
|
+
const child = spawnCommand(paths, ["start", "--no-open"], {
|
|
130
|
+
cwd: paths.home,
|
|
131
|
+
detached: true,
|
|
132
|
+
stdio: ["ignore", log, log],
|
|
133
|
+
});
|
|
134
|
+
let exited = false;
|
|
135
|
+
child.on("error", () => {
|
|
136
|
+
exited = true;
|
|
137
|
+
});
|
|
138
|
+
child.on("exit", () => {
|
|
139
|
+
exited = true;
|
|
140
|
+
});
|
|
141
|
+
child.unref();
|
|
142
|
+
const began = Date.now();
|
|
143
|
+
while (!exited && Date.now() - began < START_TIMEOUT_MS) {
|
|
144
|
+
await new Promise((wait) => setTimeout(wait, 300));
|
|
145
|
+
const started = await runningRuntime(dataDir);
|
|
146
|
+
if (started) {
|
|
147
|
+
return started;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Starts the runtime of this install and opens the studio: in the foreground, or with
|
|
154
|
+
* `background` detached from this terminal. If one already runs on the same data folder
|
|
155
|
+
* (another terminal, the desktop app), that one is opened instead.
|
|
156
|
+
*/
|
|
157
|
+
export async function start(paths, options) {
|
|
158
|
+
const { fileEnv, dataDir, port: wanted, appUrl } = settings(paths);
|
|
159
|
+
mkdirSync(dataDir, { recursive: true });
|
|
160
|
+
mkdirSync(paths.logs, { recursive: true });
|
|
161
|
+
const running = await runningRuntime(dataDir);
|
|
162
|
+
if (running) {
|
|
163
|
+
show(running.url, entryUrl(running, paths), options.open);
|
|
164
|
+
console.log(dim(` It was already running. To stop it: ${cmd("stop")}`));
|
|
165
|
+
return 0;
|
|
166
|
+
}
|
|
167
|
+
// Nothing runs, so no run is cut off: a version downloaded meanwhile becomes current and
|
|
168
|
+
// takes this process's place (the login item keeps waiting on the same pid). In the
|
|
169
|
+
// background, the `start` spawned below does it.
|
|
170
|
+
if (!options.background && installedByScript(paths) && process.execve) {
|
|
171
|
+
const switched = autoUpdatePolicy(paths, { installed: true }).on && applyPendingUpdate(paths);
|
|
172
|
+
if (switched) {
|
|
173
|
+
console.log(` ${live} Updated to ${switched.to}. What changed: ${notesUrl(switched.to)}`);
|
|
174
|
+
const wrapper = join(paths.bin, "wizards");
|
|
175
|
+
try {
|
|
176
|
+
process.execve(wrapper, [wrapper, "start", ...(options.open ? [] : ["--no-open"])]);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// This version starts once more; the next start is the new one.
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (options.background) {
|
|
184
|
+
const started = await startInBackground(paths);
|
|
185
|
+
if (!started) {
|
|
186
|
+
console.error(`engenty wizards didn’t start. Its log is in ${tilde(join(paths.logs, "runtime.log"))}.`);
|
|
187
|
+
return 1;
|
|
188
|
+
}
|
|
189
|
+
show(started.url, entryUrl(started, paths), options.open);
|
|
190
|
+
console.log(dim(` It’s running in the background. To stop it: ${cmd("stop")}`));
|
|
191
|
+
console.log(dim(` Its log is in ${tilde(join(paths.logs, "runtime.log"))}.`));
|
|
192
|
+
return 0;
|
|
193
|
+
}
|
|
194
|
+
const port = wanted ?? (await freePort());
|
|
195
|
+
if (!wanted && port !== DEFAULT_PORT) {
|
|
196
|
+
console.log(dim(` Port ${DEFAULT_PORT} is taken, so it uses ${port}.`));
|
|
197
|
+
}
|
|
198
|
+
const accessKey = randomBytes(24).toString("hex");
|
|
199
|
+
const url = appUrl || `http://localhost:${port}`;
|
|
200
|
+
const child = spawn(process.execPath, [join(packageRoot, "apps/runtime/dist/index.js")], {
|
|
201
|
+
cwd: paths.home,
|
|
202
|
+
env: {
|
|
203
|
+
...runtimeEnv(paths, { port, url, dataDir, accessKey }, process.env, fileEnv),
|
|
204
|
+
// This command starts it again when it exits with RESTART_EXIT.
|
|
205
|
+
ENGENTY_WIZARDS_RESTARTS: "1",
|
|
206
|
+
},
|
|
207
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
208
|
+
});
|
|
209
|
+
let current = child;
|
|
210
|
+
let exited = null;
|
|
211
|
+
const ended = new Promise((done) => {
|
|
212
|
+
child.on("error", (error) => {
|
|
213
|
+
console.error(`engenty wizards didn’t start: ${error.message}`);
|
|
214
|
+
exited = 1;
|
|
215
|
+
done(1);
|
|
216
|
+
});
|
|
217
|
+
child.on("exit", (code, signal) => {
|
|
218
|
+
exited = code ?? (signal ? 0 : 1);
|
|
219
|
+
done(exited);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
// Ctrl-C reaches the runtime as well (same terminal); it closes its browser and its databases.
|
|
223
|
+
process.on("SIGINT", () => undefined);
|
|
224
|
+
process.on("SIGTERM", () => current.kill("SIGTERM"));
|
|
225
|
+
const began = Date.now();
|
|
226
|
+
while (exited === null && !(await healthy(port))) {
|
|
227
|
+
if (Date.now() - began > START_TIMEOUT_MS) {
|
|
228
|
+
child.kill("SIGTERM");
|
|
229
|
+
console.error("engenty wizards didn’t respond within 60 seconds.");
|
|
230
|
+
return 1;
|
|
231
|
+
}
|
|
232
|
+
await new Promise((wait) => setTimeout(wait, 150));
|
|
233
|
+
}
|
|
234
|
+
if (exited !== null) {
|
|
235
|
+
return exited || 1;
|
|
236
|
+
}
|
|
237
|
+
show(url, `${url}/api/local/enter?k=${accessKey}`, options.open);
|
|
238
|
+
console.log(dim(" To stop it, press Ctrl-C."));
|
|
239
|
+
console.log("");
|
|
240
|
+
const code = await ended;
|
|
241
|
+
if (code !== RESTART_EXIT) {
|
|
242
|
+
return code;
|
|
243
|
+
}
|
|
244
|
+
// Updated or `wizards restart`: the command as it is on disk now starts it again, in this
|
|
245
|
+
// terminal or under the login item, which keeps waiting on this process.
|
|
246
|
+
console.log(dim(" Restarting…"));
|
|
247
|
+
current = spawnCommand(paths, ["start", "--no-open"], { stdio: "inherit" });
|
|
248
|
+
return new Promise((done) => {
|
|
249
|
+
current.on("error", () => done(1));
|
|
250
|
+
current.on("exit", (exit) => done(exit ?? 0));
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
/** `wizards studio`: opens the studio in the browser; when nothing runs, it starts as a service first. */
|
|
254
|
+
export async function studio(paths) {
|
|
255
|
+
const { dataDir } = settings(paths);
|
|
256
|
+
const running = await runningRuntime(dataDir);
|
|
257
|
+
if (running) {
|
|
258
|
+
show(running.url, entryUrl(running, paths), true);
|
|
259
|
+
return 0;
|
|
260
|
+
}
|
|
261
|
+
return start(paths, { open: true, background: true });
|
|
262
|
+
}
|
|
263
|
+
/** `wizards open`: lets the browser into the runtime that runs. */
|
|
264
|
+
export async function open(paths, print) {
|
|
265
|
+
const { dataDir } = settings(paths);
|
|
266
|
+
const running = await runningRuntime(dataDir);
|
|
267
|
+
if (!running) {
|
|
268
|
+
console.error(`engenty wizards isn’t running. To start it: ${cmd("start")}`);
|
|
269
|
+
return 1;
|
|
270
|
+
}
|
|
271
|
+
const entry = entryUrl(running, paths);
|
|
272
|
+
if (print || !openBrowser(entry)) {
|
|
273
|
+
console.log(entry);
|
|
274
|
+
}
|
|
275
|
+
return 0;
|
|
276
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { accessSync, constants, existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { accountState, describeAccount } from "./account.js";
|
|
4
|
+
import { autostartForStatus, autostartState, setAutostart } from "./autostart.js";
|
|
5
|
+
import { autoUpdatePolicy, updateNotice } from "./autoupdate.js";
|
|
6
|
+
import { installedByScript, isCheckout, packageRoot, packageVersion } from "./home.js";
|
|
7
|
+
import { detectClients, findChrome, findFfmpeg, nodeIsCurrent } from "./machine.js";
|
|
8
|
+
import { findWizardsProcesses, stopProcesses } from "./processes.js";
|
|
9
|
+
import { entryUrl, runningRuntime, settings, startInBackground } from "./start.js";
|
|
10
|
+
import { bad, badge, cmd, cyan, dim, no, ok, tilde } from "./ui.js";
|
|
11
|
+
/**
|
|
12
|
+
* What is installed and what runs. With `checks` (`doctor`) it also says what is wrong and
|
|
13
|
+
* returns 1 when something is.
|
|
14
|
+
*/
|
|
15
|
+
export async function status(paths, checks) {
|
|
16
|
+
const { dataDir } = settings(paths);
|
|
17
|
+
const [running, clients, ffmpeg, atLogin, account] = await Promise.all([
|
|
18
|
+
runningRuntime(dataDir),
|
|
19
|
+
detectClients(paths),
|
|
20
|
+
findFfmpeg(),
|
|
21
|
+
autostartForStatus(paths),
|
|
22
|
+
accountState(),
|
|
23
|
+
]);
|
|
24
|
+
const chrome = findChrome();
|
|
25
|
+
const row = (label, value) => console.log(` ${label.padEnd(9)} ${value}`);
|
|
26
|
+
console.log(`\n${badge("engenty wizards")} ${dim(packageVersion())}\n`);
|
|
27
|
+
row("Install", installedByScript()
|
|
28
|
+
? tilde(paths.home)
|
|
29
|
+
: `${tilde(packageRoot)} ${dim(isCheckout() ? "(a checkout)" : "(npm)")}`);
|
|
30
|
+
row("Data", tilde(dataDir));
|
|
31
|
+
row("Node", `${process.version} ${dim(tilde(process.execPath))}`);
|
|
32
|
+
row("Running", running
|
|
33
|
+
? `${ok} ${cyan(running.url)} ${dim(`pid ${running.pid}, since ${new Date(running.startedAt).toLocaleString()}`)}`
|
|
34
|
+
: `${no} not running`);
|
|
35
|
+
if (!("unavailable" in atLogin)) {
|
|
36
|
+
row("At login", atLogin.on ? `${ok} starts ${dim(`(${atLogin.how})`)}` : `${no} doesn’t start`);
|
|
37
|
+
}
|
|
38
|
+
if (installedByScript(paths)) {
|
|
39
|
+
const policy = autoUpdatePolicy(paths, { installed: true });
|
|
40
|
+
row("Updates", policy.on ? `${ok} automatic` : `${no} ${policy.reason} ${dim(`(${cmd("autoupdate on")})`)}`);
|
|
41
|
+
}
|
|
42
|
+
row("Account", `${account.kind === "linked" ? ok : no} ${describeAccount(account)}`);
|
|
43
|
+
for (const { client, path, version } of clients) {
|
|
44
|
+
row(client.name.split(" ")[0], path ? `${ok} ${version} ${dim(tilde(path))}` : `${no} not installed`);
|
|
45
|
+
}
|
|
46
|
+
row("Browser", chrome ? `${ok} ${dim(tilde(chrome))}` : `${no} not found (needed for PDF and PNG)`);
|
|
47
|
+
row("ffmpeg", ffmpeg.path ? `${ok} ${ffmpeg.version ?? ""}` : `${no} not found (needed for MP4)`);
|
|
48
|
+
const { updated, pending } = updateNotice(paths, packageVersion());
|
|
49
|
+
if (updated) {
|
|
50
|
+
console.log(`\n ${ok} Updated to ${updated.to}. What changed: ${cyan(updated.notes)}`);
|
|
51
|
+
}
|
|
52
|
+
else if (pending) {
|
|
53
|
+
console.log(`\n ${ok} Version ${pending.version} is downloaded; it runs from the next start.`);
|
|
54
|
+
}
|
|
55
|
+
console.log("");
|
|
56
|
+
if (!checks) {
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
const problems = [];
|
|
60
|
+
if (!nodeIsCurrent()) {
|
|
61
|
+
problems.push(`Node ${process.version} is too old. engenty wizards needs 24.11 or newer.`);
|
|
62
|
+
}
|
|
63
|
+
for (const part of ["apps/runtime/dist/index.js", "apps/web/dist/index.html", "plugin"]) {
|
|
64
|
+
if (!existsSync(join(packageRoot, part))) {
|
|
65
|
+
problems.push(`${part} is missing from this install (${tilde(packageRoot)}).`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
mkdirSync(paths.home, { recursive: true });
|
|
70
|
+
accessSync(paths.home, constants.W_OK);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
problems.push(`${tilde(paths.home)} can’t be written to.`);
|
|
74
|
+
}
|
|
75
|
+
if (!clients.some((state) => state.path)) {
|
|
76
|
+
console.log(` ${no} No AI client. The studio needs an API key, Ollama or Apple Intelligence (Mac only) instead. ${dim(`To install one: ${cmd("setup")}`)}`);
|
|
77
|
+
}
|
|
78
|
+
for (const problem of problems) {
|
|
79
|
+
console.log(` ${bad} ${problem}`);
|
|
80
|
+
}
|
|
81
|
+
if (!problems.length) {
|
|
82
|
+
console.log(` ${ok} No problems found.`);
|
|
83
|
+
}
|
|
84
|
+
console.log("");
|
|
85
|
+
return problems.length ? 1 : 0;
|
|
86
|
+
}
|
|
87
|
+
/** Waits for a process to end; false when it still runs after `ms`. */
|
|
88
|
+
async function ended(pid, ms) {
|
|
89
|
+
for (let waited = 0; waited < ms; waited += 100) {
|
|
90
|
+
try {
|
|
91
|
+
process.kill(pid, 0);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
await new Promise((wait) => setTimeout(wait, 100));
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Stops engenty wizards: the runtime that runs on this install's data folder, and every other
|
|
102
|
+
* runtime or `start` of this install still about (an older `start --no-open` whose note another
|
|
103
|
+
* one overwrote). `wizards mcp` processes belong to the AI apps and stay.
|
|
104
|
+
*/
|
|
105
|
+
export async function stop(paths) {
|
|
106
|
+
const { dataDir } = settings(paths);
|
|
107
|
+
const running = await runningRuntime(dataDir);
|
|
108
|
+
const found = findWizardsProcesses(paths.home);
|
|
109
|
+
const pids = [
|
|
110
|
+
...new Set([
|
|
111
|
+
...(running ? [running.pid] : []),
|
|
112
|
+
...found.filter((p) => p.kind === "runtime" || p.kind === "start").map((p) => p.pid),
|
|
113
|
+
]),
|
|
114
|
+
];
|
|
115
|
+
if (!pids.length) {
|
|
116
|
+
console.log("engenty wizards isn’t running.");
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
const left = await stopProcesses(pids);
|
|
120
|
+
const stopped = pids.length - left.length;
|
|
121
|
+
if (stopped) {
|
|
122
|
+
console.log(pids.length === 1
|
|
123
|
+
? `Stopped (pid ${pids[0]}). Your data is kept.`
|
|
124
|
+
: `Stopped ${stopped} processes (pid ${pids.filter((pid) => !left.includes(pid)).join(", ")}). Your data is kept.`);
|
|
125
|
+
}
|
|
126
|
+
const apps = found.filter((p) => p.kind === "mcp").length;
|
|
127
|
+
if (apps && !left.length) {
|
|
128
|
+
console.log(dim(`${apps === 1 ? "An AI app connection still runs" : `${apps} AI app connections still run`}. Using a wizard there starts engenty wizards again.`));
|
|
129
|
+
}
|
|
130
|
+
if (left.length) {
|
|
131
|
+
console.error(`${left.length === 1 ? "A process" : `${left.length} processes`} of engenty wizards didn’t stop (pid ${left.join(", ")}). To stop ${left.length === 1 ? "it" : "them"}: ${cyan(`kill -9 ${left.join(" ")}`)}`);
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Stops the runtime and starts it again, the version on disk now. One the command started (a
|
|
138
|
+
* terminal, the login item) is started again by that command, where it ran; any other is
|
|
139
|
+
* stopped and started in the background. When nothing runs, it is started in the background.
|
|
140
|
+
*/
|
|
141
|
+
export async function restart(paths) {
|
|
142
|
+
const { dataDir } = settings(paths);
|
|
143
|
+
const running = await runningRuntime(dataDir);
|
|
144
|
+
if (running?.restarts && process.platform !== "win32") {
|
|
145
|
+
process.kill(running.pid, "SIGUSR2");
|
|
146
|
+
for (let waited = 0; waited < 60_000; waited += 300) {
|
|
147
|
+
await new Promise((wait) => setTimeout(wait, 300));
|
|
148
|
+
const again = await runningRuntime(dataDir);
|
|
149
|
+
if (again && again.pid !== running.pid) {
|
|
150
|
+
console.log(`${ok} Restarted: ${cyan(again.url)} ${dim(`pid ${again.pid}`)}`);
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
console.error("engenty wizards didn’t restart within a minute.");
|
|
155
|
+
return 1;
|
|
156
|
+
}
|
|
157
|
+
if (running) {
|
|
158
|
+
process.kill(running.pid, "SIGTERM");
|
|
159
|
+
if (!(await ended(running.pid, 8000))) {
|
|
160
|
+
console.error(`engenty wizards (pid ${running.pid}) didn’t stop within 8 seconds.`);
|
|
161
|
+
return 1;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const started = await startInBackground(paths);
|
|
165
|
+
if (!started) {
|
|
166
|
+
console.error(`engenty wizards didn’t start. Its log is in ${tilde(join(paths.logs, "runtime.log"))}.`);
|
|
167
|
+
return 1;
|
|
168
|
+
}
|
|
169
|
+
console.log(`${ok} ${running ? "Restarted" : "Started"}: ${cyan(started.url)} ${dim(`pid ${started.pid}, in the background`)}`);
|
|
170
|
+
if (!running) {
|
|
171
|
+
console.log(` Open the studio: ${cyan(entryUrl(started, paths))}`);
|
|
172
|
+
}
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
/** `autostart [on|off]`: whether it starts at login, and the switch. */
|
|
176
|
+
export async function autostart(paths, value) {
|
|
177
|
+
if (value && value !== "on" && value !== "off") {
|
|
178
|
+
console.error(`Use ${cmd("autostart on")} or ${cmd("autostart off")}.`);
|
|
179
|
+
return 2;
|
|
180
|
+
}
|
|
181
|
+
let state;
|
|
182
|
+
try {
|
|
183
|
+
state = await autostartState(paths);
|
|
184
|
+
if (value && !("unavailable" in state)) {
|
|
185
|
+
state = await setAutostart(paths, value === "on");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
console.error(`Couldn’t ${value ? `turn start at login ${value}` : "check start at login"}: ${error.message}`);
|
|
190
|
+
return 1;
|
|
191
|
+
}
|
|
192
|
+
if ("unavailable" in state) {
|
|
193
|
+
console.error(`Start at login isn’t available here: ${state.unavailable}.`);
|
|
194
|
+
return value ? 1 : 0;
|
|
195
|
+
}
|
|
196
|
+
console.log(state.on
|
|
197
|
+
? `${ok} engenty wizards starts at login: ${state.how}.`
|
|
198
|
+
: `${no} engenty wizards doesn’t start at login. ${dim(`To turn it on: ${cmd("autostart on")}`)}`);
|
|
199
|
+
if (state.on && process.platform === "linux") {
|
|
200
|
+
console.log(dim(` To start it even before anyone logs in: ${cyan("loginctl enable-linger")}`));
|
|
201
|
+
}
|
|
202
|
+
return value && state.on !== (value === "on") ? 1 : 0;
|
|
203
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { emitKeypressEvents } from "node:readline";
|
|
3
|
+
import { styleText } from "node:util";
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import { command } from "./home.js";
|
|
6
|
+
const colours = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
|
|
7
|
+
/** The name on engenty's orange. */
|
|
8
|
+
export const badge = (text) => colours ? `\x1b[48;2;224;83;27m\x1b[97m\x1b[1m ${text} \x1b[0m` : text;
|
|
9
|
+
export const dim = (text) => styleText("dim", text);
|
|
10
|
+
export const bold = (text) => styleText("bold", text);
|
|
11
|
+
export const cyan = (text) => styleText("cyan", text);
|
|
12
|
+
export const ok = styleText("green", "✓");
|
|
13
|
+
export const no = styleText("yellow", "–");
|
|
14
|
+
export const bad = styleText("red", "✗");
|
|
15
|
+
export const live = styleText("green", "●");
|
|
16
|
+
/** A path as the person would write it. */
|
|
17
|
+
export const tilde = (path) => path.startsWith(homedir()) ? `~${path.slice(homedir().length)}` : path;
|
|
18
|
+
/** A command as the person types it, with this install's prefix: `cmd("stop")` → wizards stop. */
|
|
19
|
+
export const cmd = (args = "") => cyan(args ? `${command()} ${args}` : command());
|
|
20
|
+
/**
|
|
21
|
+
* A spinner on a terminal; where nobody watches, only what came of it. The message ends in "…"
|
|
22
|
+
* ("Checking status…"); clack animates its own dots in its place.
|
|
23
|
+
*/
|
|
24
|
+
export function busy(message) {
|
|
25
|
+
if (!process.stdout.isTTY) {
|
|
26
|
+
return { stop: (text) => p.log.step(text), fail: (text) => p.log.warn(text) };
|
|
27
|
+
}
|
|
28
|
+
exitOnCtrlC();
|
|
29
|
+
const spinner = p.spinner();
|
|
30
|
+
spinner.start(message.replace(/…$/, ""));
|
|
31
|
+
return {
|
|
32
|
+
stop: (text) => spinner.stop(text),
|
|
33
|
+
fail: (text) => spinner.error(text),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let watching = false;
|
|
37
|
+
/**
|
|
38
|
+
* Ctrl-C under a spinner: clack ends the process itself, with code 0, as if all went well. The
|
|
39
|
+
* key is noted before clack sees it (this listener comes first), and the process ends with 130
|
|
40
|
+
* instead, as a command stopped by Ctrl-C does: `wizards setup && …` goes no further.
|
|
41
|
+
*/
|
|
42
|
+
function exitOnCtrlC() {
|
|
43
|
+
if (watching || !process.stdin.isTTY) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
watching = true;
|
|
47
|
+
let pressed = false;
|
|
48
|
+
emitKeypressEvents(process.stdin);
|
|
49
|
+
process.stdin.on("keypress", (_text, key) => {
|
|
50
|
+
if (key?.ctrl && key.name === "c") {
|
|
51
|
+
pressed = true;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
process.on("exit", () => {
|
|
55
|
+
if (pressed) {
|
|
56
|
+
process.exitCode = 130;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { layout } from "./home.js";
|
|
2
|
+
import { nodeIsCurrent } from "./machine.js";
|
|
3
|
+
import { parseUninstall, uninstall } from "./uninstall.js";
|
|
4
|
+
/**
|
|
5
|
+
* `wizards uninstall` on its own: bin/wizards.mjs starts it instead of main.ts, whose modules make
|
|
6
|
+
* the install folder, its data folder and a secret when they load (install-env.ts, env.ts,
|
|
7
|
+
* db/client.ts). An uninstall must find the computer as it is, and leave nothing behind.
|
|
8
|
+
*/
|
|
9
|
+
if (!nodeIsCurrent()) {
|
|
10
|
+
console.error(`engenty wizards needs Node.js 24.11 or newer. This is ${process.version}.`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const options = parseUninstall(process.argv.slice(2));
|
|
14
|
+
if (typeof options === "string") {
|
|
15
|
+
console.error(options);
|
|
16
|
+
process.exitCode = 2;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
process.exitCode = await uninstall(layout(), options);
|
|
20
|
+
}
|