Your First Workflow
JJHub workflows are TSX files stored in your repository under.jjhub/workflows/. They use Smithers JSX components wrapped by the @jjhub-ai/workflow package.
Project Setup
The.jjhub/ directory at your repository root is a Bun workspace member with its own package.json and tsconfig.json. This gives you full LSP support (autocomplete, type checking, go-to-definition) when editing workflows.
.jjhub/package.json
.jjhub/tsconfig.json
Root package.json
Add .jjhub and packages/* to your Bun workspaces so the @jjhub-ai/workflow dependency resolves:
bun install to link the workspace.
The @jjhub-ai/workflow package lives at packages/workflow/ and re-exports Smithers JSX components (Workflow, Task, Parallel, Sequence, Branch, Ralph) plus the on trigger builders.
Create a Workflow File
Coming Soon: We are actively working on a first-class feature to allow you to run these exact same workflows entirely on your local machine for rapid testing and debugging! Check our Roadmap for more details.
Trigger a Run
Workflows run automatically on configured events (push, landing request opened, schedule, etc.). To manually trigger a workflow:Manual Dispatch with Inputs
Workflows can declare inputs that users provide when triggering a run manually. This is useful for deploy workflows, release workflows, or any workflow that needs runtime parameters.Defining Inputs
Use theon.manualDispatch trigger to declare the inputs your workflow accepts:
Input Types
Each input supports the following properties:
Triggering via CLI
Pass inputs using the--input (or -i) flag, one per key-value pair:
choice input:
Triggering via API
Send aPOST request to the workflow dispatches endpoint with inputs in the request body:
Request body:
The response returns the created workflow run object.
Accessing Inputs in Workflow Code
Inside any task, access inputs viactx.input:
ctx.input is an empty object.
View Runs
Scheduled Triggers
Workflows can run on a schedule using CRON expressions. This is useful for nightly builds, periodic reports, dependency checks, and any recurring automation.Defining a Schedule
Useon.schedule() in your triggers array with a standard CRON expression:
CRON Syntax
Schedules use standard five-field CRON syntax:Common Patterns
Timezone
All schedules run in UTC. Adjust your CRON expressions accordingly. For example, if you want a nightly build at midnight US Eastern (UTC-5), use0 5 * * *.
Multiple Schedules
A workflow can have multiple schedule triggers, and can combine schedules with other trigger types:How Scheduled Workflows Run
Scheduled workflows are managed by the JJHub scheduler on the server side, not triggered by push events or user actions. When a schedule fires:- The scheduler matches the CRON expression against the current UTC time
- A workflow run is created targeting the default bookmark (typically
main) - The run is queued and assigned to a runner pod from the warm pool
- Execution proceeds identically to any other workflow run (same logs, SSE streaming, commit statuses)
AI Agent Steps
Workflows can invoke AI agents as tasks using theagent prop:
Schema-Driven Workflows
For AI agent workflows that pass structured data between tasks, usecreateSmithers to define output schemas with Zod. This gives you type-safe ctx.output() for reading previous task results and automatic SQLite-backed persistence.
How It Works
The simple
export default (ctx) => <Workflow> pattern (shown earlier) works for compute tasks that just run shell commands. Use createSmithers when tasks need to pass structured data to each other.
Next Steps
- AI Agents Guide - Workflow agents, sandboxed runners, and workspaces
- Landing Requests Guide - full LR lifecycle
- CLI Reference - all available commands