Files
sim/scripts
WaleedandBohdan Vilishchuk 47f5fee8cb fix(setup): launch the docker app the CLI is actually pointed at (#6253)
* fix(setup): detect OrbStack vs Docker Desktop before relaunching the daemon

ensureDocker() always ran `open -a Docker` to relaunch a stopped daemon on
macOS, which silently no-ops for OrbStack users (no Docker.app bundle
exists), leading to a misleading "GUI license acceptance" timeout error.
Now it checks the docker CLI's active context first (accurate regardless
of install location) and falls back to checking for OrbStack.app, so the
wizard launches and messages the app that's actually installed.

* fix(setup): don't let an installed OrbStack override an explicit Docker Desktop context

macDockerApp() fell through to the OrbStack.app existence check whenever
docker context show returned anything other than "orbstack" — including a
known, explicit context like "desktop-linux". With both apps installed but
Docker Desktop active and stopped, this launched OrbStack while daemonUp()
kept polling Docker Desktop's socket, timing out with OrbStack-flavored
guidance for a Docker Desktop problem.

The path fallback now only runs when the context command gives no answer
at all (null); any resolved context is trusted outright.

Flagged identically by Greptile and Cursor Bugbot on PR #6250.

* fix(setup): fall back to the installed app when the context isn't OrbStack

Context detection only fell back to the app bundle when `docker context
show` failed outright, so an OrbStack-only Mac sitting on the `default`
context still resolved to Docker Desktop — the same 90s hang this fix
exists to remove. Treat an explicit OrbStack selection as the only
positive context signal and otherwise pick whichever app is installed.

Read `DOCKER_HOST` first: it overrides the active context, so the
context name is not authoritative while it is set.

* fix(setup): require OrbStack to be installed before selecting it

A context or DOCKER_HOST left behind by an OrbStack uninstall selected an
app that can never launch, turning a working Docker Desktop start into a
guaranteed 90s timeout. Gate the OrbStack signal on the bundle being
present and fall through to whichever app is.

Look in ~/Applications as well as /Applications while here — Homebrew
casks honour --appdir, so a user-local install is not unusual and a
hardcoded /Applications check would misread it as "not installed".

* fix(setup): resolve the docker app through LaunchServices, not fixed paths

A Homebrew `--appdir` can put OrbStack anywhere, so enumerating install
directories will always have a tail that reads a present app as missing
and sends setup to the wrong one. Fall back to LaunchServices when the
well-known directories miss: that is the same lookup `open -a` performs,
so availability now agrees with what the launch will actually do.

* fix(setup): settle the docker app with open(1) instead of probing for it

`path to application` can raise a modal "Where is …?" picker when the name
does not resolve, which in a terminal wizard reads as a hang. Drop it: the
launch itself already answers the question, since `open` exits non-zero
when macOS knows no such app, instantly and without UI.

That inverts the design. Rather than predict which app is installed and
then launch it, pick a provider, try to start it, and let the exit code
correct a guess — so the directory probe no longer has to enumerate every
possible install location to be right.

An explicit OrbStack selection is now never redirected to Docker Desktop.
The CLI is addressing OrbStack's socket, so `docker info` keeps failing no
matter how well Docker Desktop starts; the earlier fallback only replaced
a 90s timeout with a differently worded one. Say the context is stale and
how to fix it instead.

* fix(setup): honour `required` when the docker app fails to launch

db.ts and redis.ts call ensureDocker(false) and branch on the boolean to
offer an external Postgres or Redis instead. Throwing past that aborts the
whole wizard when a working non-Docker path was on the table, so every
post-confirm failure now warns and returns false unless Docker is required.

That covers the 90s-timeout throw too, which ignored `required` before this
branch existed — leaving it as the one path that still aborts would make
the flag mean two different things in one function.

Also name DOCKER_CONTEXT in the stale-selection hint. It overrides the
config context, so `docker context use` alone leaves the CLI pointed at
OrbStack and the next run fails identically.

* improvement(setup): don't tell CLI-runtime users to install Docker Desktop

Having the docker CLI but neither GUI app is exactly what a colima or
Rancher Desktop user looks like, and the failure told them to install
Docker Desktop — advice for a problem they don't have. Name the situation
accurately and add starting an existing runtime as an option.

---------

Co-authored-by: Bohdan Vilishchuk <iamtheflex@gmail.com>
2026-08-04 11:21:27 -07:00
..

Integration documentation generator

generate-docs.ts compiles the per-service integration pages under apps/docs/content/docs/en/integrations/ from the block/tool/trigger registry in apps/sim. The ontology it encodes: everything is a block, and an integration is one block that has Actions and, optionally, a Trigger.

Golden rule: the generated .mdx files are derived artifacts, not the source of truth. Do not hand-edit them — your changes are overwritten on the next run. The only editable region is the MANUAL-CONTENT block (see below). To change what a page says, edit the TypeScript in apps/sim and regenerate.

Where an integration lives canonically

For a service like Gmail, three TS sources define it:

Source What it is What it feeds in the page
apps/sim/blocks/blocks/<service>.ts The block: type, name, category (tools for integrations), bgColor, config sub-blocks, tools.access (which actions it exposes), an optional triggers capability, outputs Header / BlockInfoCard, Usage Instructions, and which actions + trigger appear
apps/sim/tools/<service>/*.ts Each action's params + outputs Every ### <action> → #### Input / #### Output under ## Actions
apps/sim/triggers/<provider>/ The trigger's config fields + outputs The ## Triggers section
apps/sim/components/icons.tsx The brand glyph The page icon

The block references actions by id in tools.access; the generator looks each one up in apps/sim/tools/.

What the generator does

Run with cd apps/sim && bun run generate-docs (or bun run scripts/generate-docs.ts from the repo root). One pass (generateAllBlockDocs):

  1. Copies icons apps/sim/components/icons.tsx → apps/docs/components/icons.tsx and builds apps/docs/components/ui/icon-mapping.ts.
  2. Block pass — for each integration block (category: 'tools', plus the memory / knowledge / table exceptions), writes integrations/<service>.mdx: BlockInfoCard + Usage Instructions + ## Actions.
  3. Trigger pass (generateAllTriggerDocs) — reads apps/sim/triggers/<provider>/ and appends a ## Triggers section to that service's page, or writes a standalone page for trigger-only services.
  4. Writes integrations/meta.json and regenerates the landing page's integrations.json.

Hand-written pages it never touches

Core block pages (blocks/*), the native trigger pages (triggers/{start,schedule,webhook,rss,table}), the integrations overview (integrations/index.mdx), and the service-account pages are fully hand-written. The generator skips them via HANDWRITTEN_INTEGRATION_DOCS, HANDWRITTEN_TRIGGER_DOCS, and SKIP_TRIGGER_PROVIDERS. Add a page name to those sets if you hand-author a page the generator would otherwise produce.

Manual content (the one editable region)

Each generated page may carry hand-written prose inside marker comments. The generator preserves anything between the markers and overwrites everything else, so this survives every regeneration:

{/* MANUAL-CONTENT-START:intro */}
[AgentMail](https://agentmail.to/) is an API-first email platform…
{/* MANUAL-CONTENT-END */}

Supported section names: intro (after the BlockInfoCard — the most common), usage, configuration, outputs, notes. The merge is by marker name (extractManualContent + mergeWithManualContent), so a section is re-inserted at the matching spot in the freshly generated structure.

If you move the output folder, reseed manual content from the old location first — the generator only preserves markers it finds in the existing output file, so a fresh folder starts with none.

Practical: to change…

  • An action's params/outputs, a trigger, or to add a service → edit apps/sim/{blocks,tools,triggers} and re-run the generator.
  • A page's prose intro → edit its MANUAL-CONTENT:intro block directly; it survives regen.
  • The overview / service-account / core-block / native-trigger pages → hand-edit freely.

Gotchas

  • Never hand-edit apps/docs/components/icons.tsx — step 1 overwrites it from the sim app. Components that need an icon the sim app lacks should define it locally or use @sim/emcn/icons (see components/workflow-preview/block-icons.tsx).
  • The generator is the source of truth for integrations/ and its meta.json; manual edits there are transient.

CI

The generator runs in CI on pushes to the main branch and commits the regenerated docs back. Keep block/tool/trigger metadata accurate in apps/sim and the docs follow.