Open sourceEarly access
Your agent, as code
Start with a simple bot and grow it into the agent your whole company runs on. Integrations, skills, and automations are plain TypeScript files in a sandbox: no framework to learn, nothing you can't read. Open source, in early access now.
How it grows
Start with a bot. End up running the company.
Everything your agent knows lives in files, so it grows the way software grows: review, history, rollback, ownership. One bot becomes a repo your whole company runs on.
Ship a simple bot
A bug bot, a QA bot, a digest before standup. One file, an afternoon, and it is answering in the channel.
Grow it like software
Add integrations, skills, memory, and schedules as plain files. Diff them in review, revert them in git, grep them at 2am.
Run the company on it
The same repo becomes the agent every team works in, from Slack to GitHub to cron, on Adapt Cloud or your own infrastructure.
The shape of it
Not a framework. Just code.
Slack, GitHub, Messages, or a schedule: every surface is the same small file. An event comes in, your code runs, an LLM call goes out. It is just code, so it can become anything.
Just code
No DSL, no lifecycle hooks, no magic imports. If you can read JavaScript, you already know exactly what these bots do.
A few small helpers
llm.complete() is a function you own, not an interface you implement. Change the prompt, the model, the context. It is your file.
Runs in your sandbox
Integrations, skills, and automations are all the same thing: code executing in your Firecracker sandbox with your filesystem mounted.
1// Slack bot webhook. Verifies signatures, listens for2// mentions and DMs, then answers with an LLM run.3import { App } from '@slack/bolt'4import { llm, fetchContext } from '@adapt/sdk'56const app = new App({7token: process.env.SLACK_BOT_TOKEN,8signingSecret: process.env.SLACK_SIGNING_SECRET,9})1011async function runLLM(history) {12const lines = ['You are a helpful assistant on Slack.']13for (const turn of history) {14lines.push(`${turn.role}: ${turn.content}`)15}16return llm.complete(lines.join('\n'))17}1819app.event('app_mention', async ({ event, say }) => {20const history = await fetchContext(event.channel)21await say(await runLLM(history))22})
The full file is ~200 lines, and every one is yours to read and change.
Inside the repo
Your company, as code.
One command scaffolds plain TypeScript. No framework to learn, no config screens. Every integration is a file you own, so each team meets the agent inside the tool they already live in.
acme/
Yours from the first commit. Read it, fork it, delete what you don't need.
Push and deploy.
Ship it to your own environment, or use Adapt Cloud's managed platform.
Trusted code
The code we run, handed to you.
This isn't a starter template. It's the code Adapt's managed cloud is built on, given to you the way shadcn/ui gives you components: as code, not a dependency. Run it, edit it, delete from it, make it your own. Here is all it takes to triage #bugs:
1// Watches #bugs. Every new report gets triaged:2// severity, area, owner, and a linked issue.3import { app, llm, linear } from '@adapt/sdk'45app.message({ channel: '#bugs' }, async ({ message, say }) => {6const triage = await llm.complete(7`Triage this bug. Severity, area, owner: ${message.text}`,8{ schema: Triage },9)1011const issue = await linear.createIssue({12title: triage.title,13priority: triage.severity,14team: triage.area,15})1617await say({18thread_ts: message.ts,19text: `${triage.severity} · ${triage.area} → ${issue.url}`,20})21})
21 lines. Ship it before lunch, tune the prompt in review.
bugs
Grace Hopper2:14 PM
Checkout is throwing 500s when a cart has a gift card. Started about 20 minutes ago, a few customers have written in already.

AcmeAPP2:14 PM
S1 · checkout · routed to @payments-eng
ACME-482 · Linearpossible duplicate of ACME-471
Own it from the
first commit.
It's early, and that's the point: come shape it. Show us what you build, tell us where it hurts.