Files
sim/scripts
Waleed 66a9a18d1f improvement(perf): eight verified cuts to workspace cold-load JavaScript (#6996)
* improvement(perf): eight verified cuts to workspace cold-load JavaScript

Second round of load-time work, adversarially verified for strict behaviour
preservation before implementation. Each item is an import-graph fix — none
changes what renders, when it renders, or any data path:

- knowledge/[id] imported one modal through the [documentId] components
  barrel, which also exports the chunk editor and therefore js-tiktoken
  (~2.5 MB gzip of BPE tables) on a route that never edits chunks. Deep
  import.
- prepareBlockState moved out of stores/workflows/utils.ts into its own
  module. It is the only function there needing the block registry and the
  generated tool-outputs artifact (~476 KB gzip), and utils.ts is reached by
  the persistent shell — so every workspace route paid for a canvas-only
  helper, including a module-scope JSON.parse of a 5.4 MB string.
- ExecutionSnapshot (the frozen-canvas modal) is now React.lazy behind its
  interaction gates, per the code-splitting procedure in sim-imports.md:
  deep import, dead barrel re-export deleted, sibling imports in log-details
  deepened to break the parent->child barrel cycle, local Suspense at both
  render sites. Takes ~7.6 MB of source off logs hydration.
- The api contracts barrel no longer re-exports ./tools, ./selectors, ./v1,
  or ./demo-requests (~58 KB gzip of Zod schema construction on every
  route). Zero importers used the barrel path for any of them.
- createCsvParser (streaming csv-parse, a Node Transform) moved to a
  server-only module so its stream polyfill leaves client bundles.
  Deliberately not re-exported from the lib/table barrel.
- jszip is dynamically imported at both remaining static call sites (skill
  zip extraction, pptx parsing) — both already-async, user-triggered paths,
  mirroring the existing pattern in workflow import-export.
- The desktop local-filesystem tool executor is dynamically imported in
  use-chat; a chunk-load failure now reports an error completion so the
  server-side tool call settles instead of hanging.

Production build, JS downloaded before the load event, vs the previous
release:

  /home       4.44 -> 3.87 MB   /logs    4.44 -> 3.64 MB
  /knowledge  4.22 -> 3.68 MB   /tables  4.17 -> 3.61 MB
  /files      4.68 -> 4.10 MB   /w/[id]  4.80 -> 4.67 MB
  /home total after idle prefetch: 8.15 -> 5.52 MB

The lazy snapshot was exercised end-to-end: its chunk loads when a log
detail opens (off the route's cold path, warm before the View Snapshot
click) and the modal renders without errors. Boundary baseline retightened.

* improvement(logs): contain snapshot chunk-load failures and settle the local-fs tool on recovery failure

Review round: wrap both lazy ExecutionSnapshot render sites in a small error
boundary (Suspense handles the lazy import's pending state, not its
rejection — a failed chunk load would have unwound to the route boundary and
replaced the logs page over an optional modal; mirrors PreviewErrorBoundary),
and contain rejections inside the local-filesystem executor's load-failure
recovery so a failed completion report degrades to a log instead of an
unhandled rejection.

* fix(logs): recover cleanly from snapshot chunk failures

* fix(logs): preserve snapshot modal while loading
2026-08-22 21:24:14 -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.