Journey functions
Skill butterbase-ai/butterbase-skills/skills/journey-functions
Plugin for Butterbase.ai
npx -y skills add butterbase-ai/butterbase-skills --skill journey-functionsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Use 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.
SKILL.md
3.9 KB, as published. Nobody here has run it
Journey: Functions
Stage 3e of the guided journey. Implement and deploy each function in the plan.
When to use
- Dispatched by
journeywhencurrent_stage: functions. - Directly via
/butterbase-skills:journey-functions. - Skipped (annotated
(n/a)) if the plan lists no functions.
Preflight
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.
Inputs
docs/butterbase/02-plan.md— the Functions section.docs/butterbase/00-state.md— forapp_id.
Procedure
- Refresh docs. Call
butterbase_docswithtopic: "functions". For trigger types and ctx shape, also WebFetchhttps://docs.butterbase.ai/functions. Skip if cache is fresh.
0.5. Check built-in integrations first. Before writing function code that calls an external SaaS for email / messaging / calendar / CRM / payments:
- Email / Slack / etc. → invoke
butterbase-skills:integrations. The function should callmanage_integrationsexecute_actionrather than installing a third-party SDK. - Payments → invoke
butterbase-skills:payments. The function should use Stripe Connect viamanage_billingunless the plan has explicitly chosen a regional gateway.
@butterbase/sdk works server-side too
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.
Example for a cron function that aggregates from another app:
import { createClient } from '@butterbase/sdk';
export async function handler(_request: Request, ctx: { env: Record<string,string> }) {
const other = createClient({
apiUrl: ctx.env.OTHER_APP_API_URL,
apiKey: ctx.env.OTHER_APP_SERVICE_KEY,
});
const { data } = await other.db.from('events').select('*').gte('created_at', ...);
// ...
return new Response('ok');
}
For server-side patterns, butterbase_docs topic: "sdk".
Build each function
For each function in the plan, in order:
- Print:
"About to build function: <name> (trigger=<trigger>). Proceed?". Wait foryes. - Invoke
butterbase-skills:function-devvia the Skill tool with the function spec (name, trigger, behaviour, dependencies) andapp_id. The wrapped skill scaffolds the handler, writes tests where appropriate, and callsdeploy_function. Reminder it must enforce: handler signature(request, { db, env, user })and must returnnew Response(...). - Smoke: call
invoke_functionfor HTTP/cron functions and confirm a 2xx + expected body. For WebSocket, defer the smoke to frontend integration. - Append one line per function to
docs/butterbase/04-build-log.md:<ISO timestamp> functions deploy_function <fn-name> ok - After all functions are done, tick
- [x] functionsin00-state.md, setcurrent_stage:to the next unchecked stage. - Return to
journeyorchestrator (or ask"Continue to the next stage? (yes/no)").
Outputs
- Deployed functions in the Butterbase app.
- One line per function in
04-build-log.md.
Anti-patterns
- ❌ Letting a handler return a plain object — must be
new Response(...). - ❌ Skipping the smoke invocation. Cron functions in particular are easy to deploy and forget.
- ❌ Forgetting per-function env vars — use
manage_function action: update_env.