Skip to content

asyncdotengineering/thodare

Repository files navigation

Thodare mascot — chibi character holding a chain of workflow blocks

Thodare

Typed, durable workflows for AI-driven internal ops.

alpha npm @thodare/engine npm @thodare/api npm @thodare/cli License: MIT

🔥 Straight out of the oven. Active development, alpha-grade. Things will break, signatures will change. Star the repo and yell at us in Issues when they do.

Connector-shaped DSL + an LLM-native patch surface that explains its own failures, executed on openworkflow's Postgres-durable runtime. Multi-tenant from day one (better-auth organizations + API keys).

The name Thodare ([toh-DA-REE]) carries the Tamil தொடர் (thodar) — chain, sequence, continuity. A workflow IS a thodar.


Install

# the engine — DSL + durable runtime
npm install @thodare/engine

# the HTTP control plane (Hono app you mount on Bun / Node / Workers)
npm install @thodare/api

# the CLI for first-time setup + key management
npm install -g @thodare/cli

60-second quickstart

# 1. Run @thodare/api somewhere reachable. (See packages/api/README.md.)
#    For local dev, the Postgres-backed example boots in <1s.

# 2. Sign in / sign up + mint an API key. One command.
thodare login --api http://localhost:3000

# 3. The key is saved in ~/.thodare/credentials.json.
curl -H "Authorization: Bearer $(thodare token)" \
     http://localhost:3000/api/connectors

# 4. Patch a workflow with EditOp[]. Bad ops come back as `skipped_items[]`
#    you feed straight to your LLM as tool output.
curl -X POST http://localhost:3000/api/workflows/<id>/operations \
     -H "Authorization: Bearer $(thodare token)" \
     -H 'content-type: application/json' \
     -d '{"ops":[
        {"operation_type":"add","block_id":"trg","type":"trigger_webhook","params":{}},
        {"operation_type":"add","block_id":"n","type":"slack","params":{"channel":"#x","text":"hi"}},
        {"operation_type":"connect","block_id":"trg","target_block_id":"n"}
     ]}'

# 5. Run it.
curl -X POST http://localhost:3000/api/workflows/<id>/run \
     -H "Authorization: Bearer $(thodare token)" \
     -H 'content-type: application/json' \
     -d '{"input":{"hello":"world"}}'

Full guide: thodare.dev (or pnpm --filter @thodare/docs dev to read locally).

Why Thodare

You need… Thodare?
Workflows the LLM can build, edit, run, and read back
Multi-step pipelines that survive deploys, crashes, restarts
Cron triggers, webhook ingestion, signal-driven waits
Multi-tenant SaaS (orgs, members, API keys per org)
Typed skips on bad LLM ops — feedable as tool output
Fire-and-forget pub/sub Use a queue
Streaming data pipelines Wrong tool

The patch endpoint is the load-bearing piece. Bad ops are skipped, not rejected. The response carries { ok, version, skipped_items, summary } — every field is feedable directly back to the LLM. That's why single-shot LLM workflow construction works: the API doesn't reject the LLM, it explains what's wrong.

Packages

Package npm Purpose
@thodare/engine npm Workflow runtime, EditOp model, durable runs.
@thodare/api npm HTTP control plane (Hono). Workflows CRUD, runs, schedules, webhooks, auth.
@thodare/cli npm Command-line client (login, token, env, key).
@thodare/docs Astro + Starlight documentation site.

Develop

git clone https://github.com/asyncdotengineering/thodare.git
cd thodare

# One-time: a Postgres database the tests can write to.
createdb wfkit_durable_test

pnpm install
pnpm test                  # 196 tests: 117 engine + 43 api + 36 cli
pnpm --filter @thodare/docs dev   # docs at http://localhost:4321

Requires Node 22+ (native fetch, node:sqlite) and a local Postgres reachable at postgresql://localhost:5432/wfkit_durable_test. Override with WFKIT_DURABLE_PG_URL.

Status

  • 🟠 Alpha. Active development. APIs may shift between minor versions.
  • 🟢 Tests pass. 196 across the workspace.
  • 🔴 Production? Not yet. Run it in staging; report what breaks.

Issues, PRs, ideas: github.com/asyncdotengineering/thodare.

Built on the work of

  • openworkflow (Apache-2.0) — the durable-execution substrate. Every step in every Thodare run is one step.run() call against openworkflow's worker; replay determinism, crash recovery, and signal-driven waits are its contributions, not ours. We're a thin DSL + control-plane layer on top. (Vendored as @thodare/openworkflow for version pinning — see packages/openworkflow/UPSTREAM.md for the relationship.)

If you find Thodare useful, please give openworkflow a star too — none of this works without it.

License

MIT © 2026 asyncdotengineering. Vendored components retain their original licenses; see NOTICE.

About

Typed, durable workflows for AI-driven internal ops. Connector-shaped DSL + LLM-native patch surface, executed on openworkflow's Postgres-durable runtime. Alpha — straight out of the oven.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages