> ## Documentation Index
> Fetch the complete documentation index at: https://docs.waniwani.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Flows

> A flow in a kit app is an @waniwani/sdk flow used unchanged. Default-export createFlow(...).compile() from flows/ and the runtime registers it as a tool.

A flow is an SDK primitive used unchanged. `createFlow(...).compile()` returns something the runtime registers directly, so everything the [SDK documents about flows](/sdk/flows/overview) applies here as written.

```ts flows/split-payment.ts theme={null}
import { createFlow, END, MemoryKvStore, START } from "@waniwani/sdk/mcp";

export default createFlow({ id: "split_payment", title, description, state })
  .addNode({
    id: "ask_amount",
    run: ({ interrupt }) => interrupt({ amount: { question: "How much is the basket?" } }),
  })
  .addNode({
    id: "show_plans",
    run: ({ state, showWidget }) =>
      showWidget({ tool: "select-plan", field: "selectedPlanId", data: { /* … */ } }),
  })
  .addEdge(START, "ask_amount")
  .addEdge("ask_amount", "show_plans")
  .addEdge("show_plans", END)
  .compile({ store: new MemoryKvStore() });
```

The tool name comes from the flow's `id`, so this one registers as `split_payment`. The filename only has to sit under `flows/`.

`showWidget({ tool: "select-plan" })` names a [widget](/kit/widgets) by its folder name, and the build check verifies that the folder exists. A typo fails `waniwani check` with the list of known widgets rather than a runtime error in a conversation.

## The store

`compile()` needs a store. `MemoryKvStore` keeps state in the process and is enough for local development. For production, pass one of the [KV store adapters](/sdk/flows/kv-store), or set `WANIWANI_API_KEY` in the app's `.env` to use the platform's hosted state. The env file is loaded before any module is imported, so a store built from `process.env` at the top of the file works; see [Deploy](/kit/deploy#secrets-and-environment-variables).

A flow whose store is missing fails the build check with the SDK's own message:

```text theme={null}
  flows/no-store.ts
  └ failed to load
    [waniwani] createFlow "no_store": no flow store configured. …
```

## Which SDK version an app gets

`@waniwani/sdk` is a peer dependency. The app's own `package.json` names the version, and the kit states only the floor underneath it, so an app that upgrades keeps that choice through every build. Nothing rewrites the range.

`waniwani init` writes the newest published SDK it can reach, capped with a caret, and falls back to the declared floor when npm is unreachable. Set `WANIWANI_OFFLINE=1` to skip the lookup entirely.

The SDK is 0.x, where a caret stops at the next minor. `^0.20.0` picks up 0.20.1 on the next install and never crosses to 0.21 on its own. When a newer minor is published, `waniwani check` says so and names the one-line edit. Taking it is the app's call, since under 0.x a minor is a breaking change.

## Further reading

<CardGroup cols={2}>
  <Card title="Flow engine" icon="diagram-project" href="/sdk/flows/overview">
    Nodes, edges, interrupts and state, in the SDK docs.
  </Card>

  <Card title="Build a funnel" icon="filter" href="/sdk/guides/funnels">
    Complete `createFlow` recipes: sales, lead generation, booking, quotes.
  </Card>
</CardGroup>
