AI-native workflow engine for GTM/RevOps automation.
Monorepo using pnpm workspaces:
crayon/
├── packages/
│ ├── core/ # Main SDK + CLI + MCP server + Dev UI (published as `crayon`)
│ ├── ui/ # React UI components (@crayon/ui)
│ └── auth-server/ # Next.js OAuth server (private, Nango-based)
├── skills/ # Claude Code skills
├── examples/uptime-app/ # Example app using crayon
├── docs/plans/ # Design documents
└── scripts/ # MCP server launcher
This repo is a Claude Code plugin. Load it with:
claude --plugin-dir /path/to/crayon/crayon:create-workflow- Collaborative workflow design (guides through creating workflows with embedded descriptions)/crayon:refine-node- Refine node definitions (adds tools, guidelines, typed Zod schemas to nodes)/crayon:compile-workflow- Update workflow implementation from embedded descriptions/crayon:integrations- Generate integration nodes for external APIs (Salesforce, HubSpot, etc.)/crayon:deploy- Deploy a crayon app to the cloud. Verifies deployment files, sets up environment, and deploys.
16 tools exposed via MCP (crayon-sandbox):
listIntegrations/listConnections/getConnection/assignConnection- OAuth connection managementlistWorkflows/runWorkflow/runNode- Workflow executionlistRuns/getRun/getTrace- Run history and tracingcreateVersion/listVersions/restoreVersion- Version management (git-backed)
Workflow code with embedded descriptions → Compiler (Claude Code skill) → Updated implementation → DBOS runtime
- Descriptions embedded in code as
descriptionfields (workflow-level for flow, node-level for details) - Agent specs (
src/crayon/agents/*.md) are markdown files colocated with agent code, used as runtime system prompts - No separate spec files for workflows — the code IS the spec
- DBOS provides durability: workflows register as DBOS workflows, nodes run as DBOS steps
| Type | Location | Example |
|---|---|---|
| Built-in | crayon package |
webRead |
| User node | src/crayon/nodes/ in app |
Custom logic functions |
| Agent | src/crayon/agents/ in app (.ts + colocated .md spec) |
AI reasoning via Vercel AI SDK |
my-app/
├── src/
│ ├── crayon/
│ │ ├── workflows/ # Compiled workflows (checked into git)
│ │ ├── nodes/ # User-defined function nodes
│ │ ├── agents/ # Agent .ts files + colocated .md specs
│ │ ├── tools/ # Agent tool implementations
│ │ ├── integrations/ # External API SDKs (Salesforce, etc.)
│ │ └── generated/ # Auto-generated (registry.ts)
│ ├── lib/crayon.ts # crayon singleton
│ └── ... # Rest of Next.js app
└── dbos-config.yaml # DBOS runtime config
Nodes with side effects (sending emails, Slack messages, updating databases) support a test mode where they describe what they would do without actually performing the action. This is controlled via ctx.testMode on WorkflowContext.
| Trigger | testMode default | Rationale |
|---|---|---|
CLI workflow run / node run |
ON (--live to disable) |
Interactive dev |
MCP tools run_workflow / run_node |
ON (test_mode: false to disable) |
Claude experimenting |
| HTTP API (webhooks) | OFF (test_mode: true to enable) |
Production triggers |
| Cron jobs | OFF (pass test_mode: true in job input to enable) |
Scheduled automation |
Side-effect nodes check ctx.testMode and skip the actual action when true. The output schema is the same in both modes — always includes action details (what was sent, to whom) plus a testMode: boolean field.
execute: async (ctx, inputs) => {
const message = `Hello ${inputs.name}`;
if (!ctx.testMode) {
await slack.postMessage({ channel: inputs.channel, text: message });
}
return { messageSent: message, channel: inputs.channel, testMode: ctx.testMode };
},Nodes with side effects use an extended description format with **Side Effect:** and **Test Mode:** tags. These are documented in the skill files (create-workflow, refine-node, compile-workflow).
index.ts- Public API exportsfactory.ts-createCrayon()factoryworkflow.ts-Workflow.create(), WorkflowContext, DBOS integrationnode.ts-Node.create()for function nodesagent.ts-Agent.create()for AI agentstypes.ts- Executable interface, WorkflowContext, CrayonConfigregistry.ts- Workflow/agent/node registrydiscover.ts- Auto-discovery from project directories
nodes/agent/executor.ts- Agent execution with Vercel AI SDK (generateText)nodes/agent/parser.ts- Parse agent spec markdown filesnodes/agent/model-config.ts- Model provider config (OpenAI, Anthropic)
connections/resolver.ts- Connection ID resolution (workflow → node → integration hierarchy)connections/local-integration-provider.ts- Self-hosted Nango modeconnections/cloud-integration-provider.ts- crayon cloud proxy mode
index.ts- Commander.js CLI entry pointrun.ts- Interactivecrayon local run(create or launch project)discovery.ts- Workflow/node/agent discovery via jitiruns.ts/trace.ts- Run history and trace viewing
dev-server.ts- Vite + Express dev serverapi.ts- REST API for workflows/runs/connectionswatcher.ts- File watcher for live DAG updates (watches workflows/, nodes/, agents/)dag/- React Flow DAG visualizationpty.ts- Embedded Claude Code terminal- Debug endpoint:
GET /dev/api/debug/dag-state— dumps current watcher state (workflows, nodes with descriptions, parse errors). Useful for debugging via SSH:crayon cloud ssh <app> "curl -s http://localhost:4173/dev/api/debug/dag-state"
- Each tool is a separate file with Zod input/output schemas
- Discovery uses jiti to load TypeScript files directly (no compilation)
| Command | Description |
|---|---|
crayon local run |
Interactive: create new project or launch existing |
crayon dev |
Start Dev UI with live DAG + embedded Claude Code |
crayon workflow list |
List workflows (--json supported) |
crayon workflow run <name> |
Run workflow with -i <json> |
crayon node list / node run <name> |
List/run nodes |
crayon history [run-id] |
List runs or get details |
crayon trace <run-id> |
Show execution trace |
crayon install / uninstall |
Install/remove Claude Code plugin |
crayon deploy |
Deploy app to the cloud |
crayon cloud ssh [app] [cmd] |
SSH into cloud workspace (interactive or one-shot) |
crayon login / logout |
Authenticate with crayon cloud |
crayon mcp start |
Start MCP server |
- Build:
pnpm --filter runcrayon build(TypeScript + Vite for dev-ui) - Test: Vitest —
pnpm --filter runcrayon test 2>&1 > /tmp/test-output.txt; grep -E "Test Files|Tests " /tmp/test-output.txt(pipe to file to avoid noisy output, then check summary) - Lint/Format: Biome —
pnpm biome check - CI: GitHub Actions (
publish-dev.yml) publishes to npm withdevtag on push to main - Never swallow errors — do not use empty
catch {}blocks. Always log, rethrow, or return the error to the caller. Silent failures hide bugs and make debugging impossible.
To test local core changes on a cloud dev machine:
-
Build & push a Docker image with your changes:
cd packages/core/docker && ./build-dev.sh <tag>
This builds the core package, packs it, builds/pushes the Docker image to
registry.fly.io/crayon-cloud-dev-image:<tag>, and updatesCLOUD_DEV_IMAGEinpackages/auth-server/.env.local. -
Start the local auth server (separate terminal):
cd packages/auth-server && pnpm dev
Ensure
packages/auth-server/.env.localhas these set:DEV_UI_JWT_PRIVATE_KEY— Ed25519 private key (see auth-server README for generation command)PUBLIC_URL=http://localhost:3000— tells cloud machines where to redirect browsers for authGITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET/NEXT_PUBLIC_GITHUB_CLIENT_ID— use a local dev GitHub OAuth app with callback URLhttp://localhost:3000/api/auth/github/callback(separate from the production app, so GitHub redirects back to localhost after OAuth)
-
Create a new cloud machine using the local auth server:
CRAYON_SERVER_URL=http://localhost:3000 pnpm --filter runcrayon exec tsx src/cli/index.ts cloud run --image-tag <tag>
The
--image-tagflag overrides the Docker image tag (default:latest). This lets you test a specific build without changingCLOUD_DEV_IMAGEin the auth-server env. -
Open the dev UI at
https://<fly-app-name>.fly.dev/dev/
To update existing cloud machines to a new image:
cd packages/core/docker && npx tsx update-all-machines.ts [--image <image>] [--app <fly-app-name>]- auth-server:
cd packages/auth-server && flyctl deploy
docs/plans/2026-01-23-crayon-design.md- Main design document (architecture, SDK API, spec formats, MVP scope)docs/plans/2026-01-23-outreach-automation-example.md- Reference implementation example