Build with the CLI

Install ww-cli, scaffold a TypeScript app, test locally, then push and promote versions yourself.

The Whippy Workflows CLI (ww-cli) is how developers and partners build custom Workflow Apps. You write a small TypeScript package on your machine; the CLI talks to Whippy's hosted workflows platform at https://workflows.whippy.ai. You do not need the Whippy monorepo.

📘

You deploy your own apps

Whippy does not automatically publish apps you build. ww-cli push, promote, deprecate, make-global, and secrets set are your deploy actions. Run them only when you intend to change what your organization (or every organization) can see.

Prerequisites

  1. Rust — install from rustup.rs so you can cargo install.
  2. Node.js — required for ww-cli build (esbuild bundling).
  3. A Whippy account and API key — create a key under Developer → API keys. There is no anonymous sandbox for publishing apps.
  4. Optional: Wrangler 3.x for local invoke (npm install -g [email protected]).

Install

cargo install --git https://github.com/hellowhippy/ww-cli --locked

That installs two binaries (usually under ~/.cargo/bin):

  • ww-cli — short name
  • whippy-workflows-cli — full name
ww-cli --help

Upgrade later with the same command plus --force. Release binaries are also published at github.com/hellowhippy/ww-cli/releases.

Quick start

ww-cli login
# paste your Whippy API key when prompted

ww-cli init my-app --language typescript --auth custom
cd my-app

# edit src/** …

ww-cli build
ww-cli validate
ww-cli invoke <action_key> --data test-data.json

# When you are ready to publish (humans only):
ww-cli push --create    # first publish only
ww-cli push             # later version bumps
ww-cli promote <semver>

Default API base URL is https://workflows.whippy.ai. Override with WHIPPY_WORKFLOWS_API_URL only for local or preview environments — a stale api_url in ~/.whippyrc is a common cause of silent 404s on push.

What an app is

Each app is a TypeScript (or JavaScript) package. src/index.ts default-exports:

  • version and platform_version
  • authentication
  • maps of triggers, creates, and/or searches
  • optionally hydrators and ingress

ww-cli build bundles the code with esbuild, writes a Cloudflare Worker wrapper, and extracts metadata into app.json. At runtime the workflows engine POSTs to the worker with a function path and a bundle of input, auth, and meta data. Handlers are always shaped like this:

async (w, bundle) => { /* … */ }

Do not import w; the worker wrapper injects it.

Authentication types

Pick one when you scaffold (--auth), then edit src/index.ts as needed:

TypeWhen to use
customRecommended for API-key vendors. Renders a Connect form in Whippy. Scaffolding with api_key alone does not show a Connect form — change the type to custom and keep an API-key field.
oauth2OAuth 2 providers. Implement get_access_token (and usually refresh_access_token / test).
basic_authUsername/password style credentials.
sessionLogin that returns a session token via session_config.perform.
api_keyScaffold default only — switch to custom before shipping if users need a Connect form.
noneNo credentials (rare; public APIs).

Triggers, creates, searches, hydrators

KindPurposeNotes
TriggersStart a workflow from the vendorWebhook only (operation.type: 'webhook'). Implement perform_subscribe, perform_unsubscribe, and optional perform_list for builder samples. Some vendors use central_ingress (one webhook URL per app).
CreatesMutate remote stateperform returns a single object (build wraps it under a data key).
SearchesRead / list / look upperform returns an array. Searches also feed dynamic dropdowns.
HydratorsFetch file bytes on demandRegister under hydrators. Searches (and trigger perform_list) can return a dehydrate pointer with w.dehydrateFile instead of downloading up front.

Runtime helper w

HelperUse it for
w.requestAll outbound HTTP. Supports JSON bodies, multipart uploads, and raw: true for binary. Never call fetch directly.
w.stashFileUpload bytes/URL to Whippy storage and get a hosted URL (creates, searches, hydrators — not trigger subscribe/unsubscribe/list).
w.dehydrateFile / w.dehydrateReturn a lazy file pointer for later hydration.
w.consoleLog to worker logs.
w.errorsThrow ExpiredAuthError / RefreshAuthError when OAuth tokens need refresh; also HaltedError, ThrottledError.
w.JSONSafe parse/stringify.

Deployed apps run on Cloudflare Workers — no Node.js globals (Buffer, process, require, node:fs). Local invoke may polyfill some of those, so a green local run is not proof the deployed worker will work.

Local testing

  1. Copy test-data.example.json to test-data.json (gitignore it) and fill in real auth_data.

  2. Build and validate:

    ww-cli build && ww-cli validate
  3. Invoke one handler:

    # Creates / searches / hydrators — short key
    ww-cli invoke create_contact --data test-data.json
    
    # Triggers — use perform_list (webhook triggers have no perform handler)
    ww-cli invoke triggers.new_file.operation.perform_list --data test-data.json

Without --data, the CLI uses placeholder auth. That is fine for structure checks; w.request will not send real credentials.

You can also run ww-cli test if your package defines an npm test script.

Deploy and versions

CommandWhat it does
ww-cli login / logoutStore or clear the API key in ~/.whippyrc.
ww-cli push --createFirst publish: creates the app and writes .whippyapprc. Commit .whippyapprc.
ww-cli pushPush a new draft version (set package.json version first).
ww-cli logo [path] --color '#RRGGBB'Upload a logo (default assets/logo.png).
ww-cli versionsList versions.
ww-cli promote <semver>Publish a draft version so org users can select it.
ww-cli deprecate <semver>Deprecate a published version (--date, --reason optional).
ww-cli make-globalRestricted. Promotes a private app into the global catalog every organization can see.
ww-cli secrets …Set encrypted vendor-side secrets for the app. See ww-cli secrets --help.

After push + promote, connect the app under Workflows → Auth and add it as a step in a workflow.

Command cheat sheet

ww-cli init <name> --language typescript --auth custom
ww-cli build
ww-cli validate
ww-cli invoke <key> --data test-data.json
ww-cli test
ww-cli login
ww-cli push --create
ww-cli push
ww-cli promote <semver>
ww-cli deprecate <semver>
ww-cli versions
ww-cli logo
ww-cli make-global
ww-cli secrets list
ww-cli secrets set
ww-cli secrets unset
ww-cli secrets clear

Next steps


Did this page help you?