Skip to content

CLI ​

clipless ships with @clipless/react — it needs your JSX to extract a workflow. It runs on Bun (it loads your TSX file directly), so bunx clipless … — your app itself needs no Bun.

bash
export CLIPLESS_API_KEY=cls_test_…    # or --key; a secret key

It talks to the hosted engine, https://api.clipless.dev. To point it at another one, such as an engine running locally, pass --url or set CLIPLESS_URL.

manifest ​

bash
bunx clipless manifest expense-claim.tsx            # print the manifest
bunx clipless manifest expense-claim.tsx -o m.json  # write it

Extraction refuses what only the JSX can get wrong: an <Action> outside every stage, a field action that cannot run (on="enter" on a field, or inside a <FieldGroup>), <Remarks> or a <Deadline> in the wrong place. What the manifest itself says — a transition to a stage that does not exist, an action nothing runs, a blocking enter action, a {{placeholder}} that names nothing — the engine checks when you deploy, and deploy lists every problem it found.

deploy ​

bash
bunx clipless deploy expense-claim.tsx
bunx clipless deploy expense-claim.tsx --draft      # without publishing
bunx clipless deploy expense-claim.tsx --dry-run    # show what would be sent

A deploy lands in one environment: the key's (a cls_test_… key deploys to test), or the one picked with clipless env use when you are logged in. New sessions there start on it; every other environment keeps running what it had. To take a workflow from test to production, deploy the same file with a production key — an unchanged workflow is the same revision, now running in both.

build ​

bash
bunx clipless build expense-claim.tsx --out dist/clipless

One bundle per role, <workflowId>.<role>.js with a .d.ts: the file with every other role's <Stage> removed and every <Action> reduced to its id, on, type, blocking and title, then bundled and tree-shaken. @clipless/react and your packages stay external. A reviewer's panel, an AI prompt, a webhook URL never reach a browser that does not need them. <Stage actor> must be a string literal, and a field's <Action> needs an id.

With the bundler plugin, a ?role= import does the same inside your own build, and you don't need this step.

sessions / session ​

bash
bunx clipless sessions expense_claim_v1                    # in flight, newest first
bunx clipless sessions expense_claim_v1 --status completed
bunx clipless sessions supplier_check_v1 --user acme --period 2026

bunx clipless session expense_claim_v1 Xk2…               # the ledger, event by event, and the state
bunx clipless session expense_claim_v1 Xk2… --reveal      # show pii and vault values

Read-only. pii and vault values are masked unless --reveal. Rounds are listed when a stage came round more than once.

secrets ​

bash
bunx clipless secrets                                   # names, and the signing secret's prefix
printf %s "$KEY" | bunx clipless secrets set ANTHROPIC_API_KEY
bunx clipless secrets delete ANTHROPIC_API_KEY
bunx clipless secrets signing-secret                    # create or rotate; printed once

Values come from stdin (or --value) so they stay out of your shell history.