$npx -y skills add butterbase-ai/butterbase-skills --skill journey-functionsUse as the functions build stage of the Butterbase journey. Implements the Functions section of 02-plan.md by delegating to function-dev for each function. Calls deploy_function per function; smokes each with invoke_function. Skipped if the plan has no functions.
| 1 | # Journey: Functions |
| 2 | |
| 3 | Stage 3e of the guided journey. Implement and deploy each function in the plan. |
| 4 | |
| 5 | ## When to use |
| 6 | |
| 7 | - Dispatched by `journey` when `current_stage: functions`. |
| 8 | - Directly via `/butterbase-skills:journey-functions`. |
| 9 | - Skipped (annotated `(n/a)`) if the plan lists no functions. |
| 10 | |
| 11 | ## Preflight |
| 12 | |
| 13 | If `docs/butterbase/03-preflight.md` is missing, older than 24 hours, or `00-state.md` has `app_id: null`, invoke `butterbase-skills:journey-preflight` first. Wait for it to return successfully before proceeding. |
| 14 | |
| 15 | ## Inputs |
| 16 | |
| 17 | - `docs/butterbase/02-plan.md` — the Functions section. |
| 18 | - `docs/butterbase/00-state.md` — for `app_id`. |
| 19 | |
| 20 | ## Procedure |
| 21 | |
| 22 | 0. **Refresh docs.** Call `butterbase_docs` with `topic: "functions"`. For trigger types and ctx shape, also WebFetch `https://docs.butterbase.ai/functions`. Skip if cache is fresh. |
| 23 | |
| 24 | 0.5. **Check built-in integrations first.** Before writing function code that calls an external SaaS for email / messaging / calendar / CRM / payments: |
| 25 | - Email / Slack / etc. → invoke `butterbase-skills:integrations`. The function should call `manage_integrations` `execute_action` rather than installing a third-party SDK. |
| 26 | - Payments → invoke `butterbase-skills:payments`. The function should use Stripe Connect via `manage_billing` unless the plan has explicitly chosen a regional gateway. |
| 27 | |
| 28 | ### `@butterbase/sdk` works server-side too |
| 29 | |
| 30 | Inside a function, prefer `ctx.db` / `ctx.storage` / `ctx.user` for the common cases — those are pre-wired and authenticated against the calling user. But for cross-app calls, scripts, or scheduled jobs that operate on multiple apps, instantiate `@butterbase/sdk` with a service key (`bb_sk_`) and use the same client surface as the frontend. |
| 31 | |
| 32 | Example for a cron function that aggregates from another app: |
| 33 | ```ts |
| 34 | import { createClient } from '@butterbase/sdk'; |
| 35 | |
| 36 | export async function handler(_request: Request, ctx: { env: Record<string,string> }) { |
| 37 | const other = createClient({ |
| 38 | apiUrl: ctx.env.OTHER_APP_API_URL, |
| 39 | apiKey: ctx.env.OTHER_APP_SERVICE_KEY, |
| 40 | }); |
| 41 | const { data } = await other.db.from('events').select('*').gte('created_at', ...); |
| 42 | // ... |
| 43 | return new Response('ok'); |
| 44 | } |
| 45 | ``` |
| 46 | |
| 47 | For server-side patterns, `butterbase_docs` `topic: "sdk"`. |
| 48 | |
| 49 | ### Build each function |
| 50 | |
| 51 | For each function in the plan, in order: |
| 52 | |
| 53 | 1. Print: `"About to build function: <name> (trigger=<trigger>). Proceed?"`. Wait for `yes`. |
| 54 | 2. Invoke `butterbase-skills:function-dev` via the Skill tool with the function spec (name, trigger, behaviour, dependencies) and `app_id`. The wrapped skill scaffolds the handler, writes tests where appropriate, and calls `deploy_function`. Reminder it must enforce: handler signature `(request, { db, env, user })` and must return `new Response(...)`. |
| 55 | 3. Smoke: call `invoke_function` for HTTP/cron functions and confirm a 2xx + expected body. For WebSocket, defer the smoke to frontend integration. |
| 56 | 4. Append one line per function to `docs/butterbase/04-build-log.md`: |
| 57 | `<ISO timestamp> functions deploy_function <fn-name> ok` |
| 58 | 5. After all functions are done, tick `- [x] functions` in `00-state.md`, set `current_stage:` to the next unchecked stage. |
| 59 | 6. Return to `journey` orchestrator (or ask `"Continue to the next stage? (yes/no)"`). |
| 60 | |
| 61 | ## Outputs |
| 62 | |
| 63 | - Deployed functions in the Butterbase app. |
| 64 | - One line per function in `04-build-log.md`. |
| 65 | |
| 66 | ## Anti-patterns |
| 67 | |
| 68 | - ❌ Letting a handler return a plain object — must be `new Response(...)`. |
| 69 | - ❌ Skipping the smoke invocation. Cron functions in particular are easy to deploy and forget. |
| 70 | - ❌ Forgetting per-function env vars — use `manage_function action: update_env`. |