Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .changeset/move-ui-library-in-repo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@workflowbuilder/sdk': minor
---

Consume the UI component library from the in-repo `@workflowbuilder/ui` (Base UI) instead of the published `@synergycodes/overflow-ui`.

The SDK previously bundled `@synergycodes/overflow-ui@1.0.0-beta.27` (built on MUI / Mantine / Emotion / Floating UI). It now bundles the in-repo `@workflowbuilder/ui@1.0.0-beta.28`, rebuilt on [Base UI](https://base-ui.com/), together with `@base-ui/react` (both are inlined into the SDK bundle, so SDK consumers gain no new peer dependency). Bundled component visuals and interaction details change accordingly; the SDK's own public API surface is unchanged.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,8 @@ CLAUDE.local.md
# and is copied into this dir by a tiny Astro integration after typedoc
# generation (see astro.config.mjs).
apps/docs/src/content/docs/api/

# UI Library props + CSS-variable data, generated from @workflowbuilder/ui by
# apps/docs/scripts/generate-ui-api.mjs (TypeDoc + CSS extraction) on every
# docs build / dev. Source of truth is the library, so keep it out of git.
apps/docs/src/generated/
54 changes: 29 additions & 25 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ Visual workflow editor SDK (React) with a reference backend and Temporal-based e

Three onboarding paths (A installs from npm; B, C run the repo locally). README "Get started" covers all three. Path A ("Embed the SDK") installs `@workflowbuilder/sdk` from npm; the README has install + a minimal snippet, and the full guide lives in the [docs site](https://www.workflowbuilder.io/docs/get-started/quick-start/wb-as-react-component/).

| Command | Path | What it does |
| ---------------------------- | ---- | --------------------------------------------------------------------------- |
| `pnpm preflight` | B/C | Verify Node / pnpm / Docker / ports / `.env` files. Add `--json` for agents |
| `pnpm dev` / `pnpm dev:demo` | B | Demo (UI only, port 4200). No backend, no Docker |
| `pnpm infra:up` | C | Start Postgres + Temporal in Docker. Required before backend/worker |
| `pnpm -F backend db:migrate` | C | Apply Drizzle migrations. First run, or after schema changes |
| `pnpm dev:ai-studio` | C | Full stack: infra + backend (3001) + worker + AI Studio frontend (4201) |
| `pnpm dev:backend` | C | Backend only (debug). Needs infra up |
| `pnpm dev:worker` | C | Execution worker only (debug). Needs infra up |
| `pnpm infra:down` | C | Stop the Docker stack |
| `pnpm dev:docs` | - | Docs site (Astro + Starlight) |
| `pnpm build:lib` | - | Build the SDK package (`packages/sdk`) |
| `pnpm build` | - | Build the demo app |
| `pnpm test` | - | Run tests in `packages/sdk` and `packages/execution-core` |
| `pnpm check` | - | Lint + typecheck + format + knip |
| Command | Path | What it does |
| ---------------------------- | ---- | --------------------------------------------------------------------------------------- |
| `pnpm preflight` | B/C | Verify Node / pnpm / Docker / ports / `.env` files. Add `--json` for agents |
| `pnpm dev` / `pnpm dev:demo` | B | Demo (UI only, port 4200). No backend, no Docker |
| `pnpm infra:up` | C | Start Postgres + Temporal in Docker. Required before backend/worker |
| `pnpm -F backend db:migrate` | C | Apply Drizzle migrations. First run, or after schema changes |
| `pnpm dev:ai-studio` | C | Full stack: infra + backend (3001) + worker + AI Studio frontend (4201) |
| `pnpm dev:backend` | C | Backend only (debug). Needs infra up |
| `pnpm dev:worker` | C | Execution worker only (debug). Needs infra up |
| `pnpm infra:down` | C | Stop the Docker stack |
| `pnpm dev:docs` | - | Docs site (Astro + Starlight) |
| `pnpm build:lib` | - | Build the publishable chain: `ui-tokens` -> `ui` -> SDK (`build:ui` does the first two) |
| `pnpm build` | - | Build the demo app |
| `pnpm test` | - | Run tests in `packages/sdk` and `packages/execution-core` |
| `pnpm check` | - | Lint + typecheck + format + knip |

Path B is UI-only and does not need Docker. Path C requires `pnpm infra:up` before backend/worker can start, and `db:migrate` on the first run.

Expand Down Expand Up @@ -52,6 +52,8 @@ apps/
tools/ - @workflow-builder/tools workspace (decision-log collector, lint-staged config)
packages/
sdk/ - @workflowbuilder/sdk public package (WorkflowBuilder compound component, plugin API, components)
ui/ - @workflowbuilder/ui published component library (Base UI), consumed by sdk/demo/ai-studio
tokens/ - @workflowbuilder/ui-tokens private design-token build (style-dictionary), feeds packages/ui
execution-core/ - Pure topological graph runner + node executor registry
types/ - Shared TypeScript types
```
Expand All @@ -62,20 +64,22 @@ Where to put a new script: root `tools/` for pure-Node bootstrap (runs before an

Each workspace has its own context. Read the relevant file before extending a workspace.

| Workspace | Authoritative docs |
| ------------------------- | ----------------------------------- |
| `packages/sdk` | `packages/sdk/README.md` |
| `packages/execution-core` | `packages/execution-core/README.md` |
| `apps/demo` | `apps/demo/CLAUDE.md` |
| `apps/ai-studio` | `apps/ai-studio/README.md` |
| `apps/backend` | `apps/backend/README.md` |
| `apps/execution-worker` | `apps/execution-worker/README.md` |
| Workspace | Authoritative docs |
| ------------------------- | ------------------------------------------------------- |
| `packages/sdk` | `packages/sdk/README.md` |
| `packages/ui` | `packages/ui/README.md` (+ `packages/ui/css-layers.md`) |
| `packages/execution-core` | `packages/execution-core/README.md` |
| `apps/demo` | `apps/demo/CLAUDE.md` |
| `apps/ai-studio` | `apps/ai-studio/README.md` |
| `apps/backend` | `apps/backend/README.md` |
| `apps/execution-worker` | `apps/execution-worker/README.md` |

## Types & Aliases

Shared types: `packages/types/` (imported as `@workflow-builder/types/*`).
Icons: `apps/icons/` (imported as `@workflow-builder/icons`).
SDK: `packages/sdk/` (imported as `@workflowbuilder/sdk`).
UI: `packages/ui/` (imported as `@workflowbuilder/ui`; styles via `@workflowbuilder/ui/styles.css`, `/index.css`, `/tokens.css`).

## Local Infrastructure

Expand Down Expand Up @@ -130,7 +134,7 @@ If you're new to this repo and want to build your own consumer app or POC, follo

### Releasing `@workflowbuilder/sdk`

The SDK is the only npm-published workspace; everything else under `apps/` and `packages/` is private (and listed under `ignore` in `.changeset/config.json`).
Two workspaces are npm-published: `@workflowbuilder/sdk` and `@workflowbuilder/ui` (the component library, built on Base UI). Everything else under `apps/` and `packages/` is private (`@workflowbuilder/ui-tokens` is private too) and listed under `ignore` in `.changeset/config.json`. Because there are now two publishable packages, the release tag scheme below (single-package `v*`) still needs migrating to scoped tags (`@workflowbuilder/sdk@X.Y.Z`) before publishing `@workflowbuilder/ui` from this repo - see § "Tag format" and `packages/sdk/RELEASE.md`.

**Commit format is enforced.** Every commit goes through `commitlint` via the `commit-msg` husky hook — Conventional Commits format only (`<type>(<scope>): <subject>`, types from `feat / fix / perf / refactor / docs / test / chore / build / ci / style / revert`). Bad messages are rejected before they land in git history.

Expand All @@ -155,7 +159,7 @@ The SDK is the only npm-published workspace; everything else under `apps/` and `
4. GitHub Action triggered by the tag runs lint + typecheck + test + `pnpm publish --provenance` (authenticated via npm Trusted Publisher / OIDC, no `NPM_TOKEN` stored anywhere) + creates a GitHub Release.
5. Sync back: `git checkout main && git merge release && git push` so main picks up the bumped version + clean `.changeset/`.

Tag format follows the ng-diagram convention (single-package monorepo, `v*` regex). If we ever publish a second package we'll migrate to scoped (`@workflowbuilder/sdk@X.Y.Z`) — ~1h of work, see `packages/sdk/RELEASE.md` § "Why these decisions".
Tag format currently follows the ng-diagram convention (single-package monorepo, `v*` regex). A second publishable package (`@workflowbuilder/ui`) now exists, so this needs migrating to scoped tags (`@workflowbuilder/sdk@X.Y.Z`) — ~1h of work, see `packages/sdk/RELEASE.md` § "Why these decisions".

Canonical procedure with edge cases and rollback: [`packages/sdk/RELEASE.md`](packages/sdk/RELEASE.md).

Expand Down
3 changes: 2 additions & 1 deletion apps/ai-studio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
"test:watch": "vitest --passWithNoTests"
},
"dependencies": {
"@base-ui/react": "catalog:",
"@jsonforms/core": "^3.4.1",
"@jsonforms/react": "^3.4.1",
"@phosphor-icons/react": "^2.1.7",
"@synergycodes/overflow-ui": "1.0.0-beta.27",
"@workflow-builder/types": "workspace:*",
"@workflowbuilder/ui": "workspace:*",
"@xyflow/react": "catalog:",
"clsx": "^2.1.1",
"immer": "^10.1.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NavButton } from '@synergycodes/overflow-ui';
import { Icon, getStoreEdges, getStoreNodes } from '@workflowbuilder/sdk';
import { NavButton } from '@workflowbuilder/ui';
import clsx from 'clsx';
import { useCallback } from 'react';

Expand Down
25 changes: 0 additions & 25 deletions apps/ai-studio/vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,12 @@ import { defineConfig } from 'vite';
import svgr from 'vite-plugin-svgr';

export default defineConfig(() => {
const shouldUseLocalOverflowUI = process.env.LOCAL_OVERFLOW_UI === 'true';

const sdkDirectory = path.resolve(import.meta.dirname, '../../packages/sdk');

return {
plugins: [svgr(), react()],
resolve: {
alias: [
...(shouldUseLocalOverflowUI
? Object.entries(getLocalOverflowUIAliases()).map(([find, replacement]) => ({
find,
replacement,
}))
: []),
{
find: /^@workflowbuilder\/sdk\/style\.css$/,
replacement: path.resolve(sdkDirectory, 'src/index.css'),
Expand All @@ -27,14 +19,6 @@ export default defineConfig(() => {
find: /^@workflowbuilder\/sdk$/,
replacement: path.resolve(sdkDirectory, 'src/index.ts'),
},
// overflow-ui doesn't expose ./dist/index.css via package.json exports
{
find: 'overflow-ui-css',
replacement: path.resolve(
sdkDirectory,
'node_modules/@synergycodes/overflow-ui/dist/index.css',
),
},
// SDK source files use @/ to refer to their own root (packages/sdk/src/...).
// AI Studio files do not use @/ (they import via @workflowbuilder/sdk subpaths),
// so it's safe to point @/ at the SDK root for cross-package alias parity.
Expand All @@ -56,12 +40,3 @@ export default defineConfig(() => {
},
};
});

function getLocalOverflowUIAliases(): Record<string, string> {
const distribution = path.resolve(import.meta.dirname, '../../../overflow-ui/packages/ui/dist');

return {
'@synergycodes/overflow-ui/tokens.css': path.join(distribution, 'tokens.css'),
'@synergycodes/overflow-ui': path.join(distribution, 'overflow-ui.js'),
};
}
1 change: 0 additions & 1 deletion apps/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ All scripts run from the monorepo root. Grouped by purpose:
| `dev:backend` | Backend only (Hono server with `tsx watch`) |
| `dev:worker` | Execution worker only (Temporal worker with `tsx watch`) |
| `dev:docs` | Docs site (Astro) |
| `dev:local` | Demo frontend with `LOCAL_OVERFLOW_UI=true` (linked local overflow-ui) |

### Infra (Docker lifecycle)

Expand Down
3 changes: 2 additions & 1 deletion apps/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
"test:watch": "vitest"
},
"dependencies": {
"@base-ui/react": "catalog:",
"@jsonforms/core": "^3.4.1",
"@jsonforms/react": "^3.4.1",
"@microsoft/clarity": "^1.0.0",
"@phosphor-icons/react": "^2.1.7",
"@synergycodes/overflow-ui": "1.0.0-beta.27",
"@workflowbuilder/ui": "workspace:*",
"@xyflow/react": "catalog:",
"ajv": "catalog:",
"clsx": "^2.1.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NodeDescription, NodeIcon, NodePanel } from '@synergycodes/overflow-ui';
import { Icon, defineNodeTemplate, getHandleId, statusOptions } from '@workflowbuilder/sdk';
import type { NodeDataProperties, WorkflowNodeTemplateProps } from '@workflowbuilder/sdk';
import { NodeDescription, NodeIcon, NodePanel } from '@workflowbuilder/ui';
import { Handle, Position } from '@xyflow/react';
import clsx from 'clsx';
import { memo, useMemo } from 'react';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NavButton } from '@synergycodes/overflow-ui';
import { Icon } from '@workflowbuilder/sdk';
import type { TranslationKey, WBIcon } from '@workflowbuilder/sdk';
import { NavButton } from '@workflowbuilder/ui';
import i18n from 'i18next';

import { openNoAccessModal } from '../../functions/open-no-access-modal';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button } from '@synergycodes/overflow-ui';
import { Button } from '@workflowbuilder/ui';
import { useTranslation } from 'react-i18next';

import { openHelpModal } from '../functions/open-help-modal';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type MenuItemProps } from '@synergycodes/overflow-ui';
import { Icon } from '@workflowbuilder/sdk';
import { type MenuItemProps } from '@workflowbuilder/ui';
import i18n from 'i18next';

import { openNoAccessModal } from './open-no-access-modal';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LinkedinLogo, PaperPlaneRight } from '@phosphor-icons/react';
import { Avatar, Button } from '@synergycodes/overflow-ui';
import { Avatar, Button } from '@workflowbuilder/ui';
import clsx from 'clsx';

import styles from './sales-contact.module.css';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NavButton } from '@synergycodes/overflow-ui';
import { Icon, useStore } from '@workflowbuilder/sdk';
import { NavButton } from '@workflowbuilder/ui';
import { useTranslation } from 'react-i18next';

import { redo, undo, useUndoRedoStore } from '../../stores/use-undo-redo-store';
Expand Down
24 changes: 0 additions & 24 deletions apps/demo/vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
export default defineConfig(({ mode }) => {
const isProduction = mode === 'production';
const isAnalyze = process.env.ANALYZE === 'true';
const shouldUseLocalOverflowUI = process.env.LOCAL_OVERFLOW_UI === 'true';

const plugins: PluginOption[] = [];

Expand Down Expand Up @@ -52,12 +51,6 @@ export default defineConfig(({ mode }) => {
plugins,
resolve: {
alias: [
...(shouldUseLocalOverflowUI
? Object.entries(getLocalOverflowUIAliases()).map(([find, replacement]) => ({
find,
replacement,
}))
: []),
{
find: /^@workflowbuilder\/sdk\/style\.css$/,
replacement: path.resolve(sdkDirectory, 'src/index.css'),
Expand All @@ -66,14 +59,6 @@ export default defineConfig(({ mode }) => {
find: /^@workflowbuilder\/sdk$/,
replacement: path.resolve(sdkDirectory, 'src/index.ts'),
},
// overflow-ui doesn't expose ./dist/index.css via package.json exports
{
find: 'overflow-ui-css',
replacement: path.resolve(
sdkDirectory,
'node_modules/@synergycodes/overflow-ui/dist/index.css',
),
},
// SDK source files use @/ to refer to their own root (packages/sdk/src/...).
// Demo files do not use @/ (they import via @workflowbuilder/sdk subpaths),
// so it's safe to point @/ at the SDK root for cross-package alias parity with sdk's vite.config.
Expand All @@ -96,15 +81,6 @@ export default defineConfig(({ mode }) => {
};
});

function getLocalOverflowUIAliases(): Record<string, string> {
const distribution = path.resolve(import.meta.dirname, '../../../overflow-ui/packages/ui/dist');

return {
'@synergycodes/overflow-ui/tokens.css': path.join(distribution, 'tokens.css'),
'@synergycodes/overflow-ui': path.join(distribution, 'overflow-ui.js'),
};
}

type EnvMode = 'demo' | 'production' | 'development' | 'staging';
const fileReplacementsMap: Record<EnvMode, FileReplacement[]> = {
demo: [],
Expand Down
18 changes: 17 additions & 1 deletion apps/docs/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { copyFileSync, mkdirSync } from 'node:fs';
import path from 'node:path';

import react from '@astrojs/react';
import starlight from '@astrojs/starlight';
import umami from '@yeskunall/astro-umami';
import { defineConfig, passthroughImageService } from 'astro/config';
Expand Down Expand Up @@ -70,6 +71,7 @@ export default defineConfig({
},
integrations: [
icon(),
react(),
umami({ id: UMAMI_WEBSITE_ID }),
starlight({
plugins: [
Expand Down Expand Up @@ -113,7 +115,12 @@ export default defineConfig({
},
}),
],
customCss: ['./src/styles/custom.css'],
// `@workflowbuilder/ui` styles are safe to load globally: styles.css is
// just the @layer order + one :root var + opt-in `.ax-public-*` typography
// classes (no global reset), and tokens.css only defines `--ax-*` custom
// properties keyed on `html[data-theme]` — which Starlight already toggles,
// so the live component showcases follow the docs light/dark theme.
customCss: ['./src/styles/custom.css', '@workflowbuilder/ui/styles.css', '@workflowbuilder/ui/tokens.css'],
components: {
Head: './src/components/head.astro',
Search: './src/components/search.astro',
Expand Down Expand Up @@ -159,6 +166,15 @@ export default defineConfig({
{ label: 'Node Schemas', autogenerate: { directory: 'node-schemas' } },
{ label: 'Built-in Nodes', autogenerate: { directory: 'nodes' } },
{ label: 'Plugins', autogenerate: { directory: 'plugins' } },
{
label: 'UI Library',
items: [
{ label: 'Overview', link: '/ui-library/overview/' },
{ label: 'Design tokens', link: '/ui-library/design-tokens/' },
{ label: 'UI Components', autogenerate: { directory: 'ui-library/ui-components' } },
{ label: 'Diagram Components', autogenerate: { directory: 'ui-library/diagram-components' } },
],
},
// API Reference — pages auto-generated by `starlight-typedoc` from
// packages/sdk's barrel into `src/content/docs/api/<Category>/`.
// Folder names match the `@category` tag in source TSDoc verbatim.
Expand Down
Loading
Loading