Skip to main content

Quickstart

Get a workflow live in under 5 minutes.

Context as Code

How generated helpers make workflows more stable.

Why Terse

Most AI workflows are easy to prototype and hard to keep running. An integration’s schema drifts, a prompt quietly regresses, a step that called an LLM now needs a guardrail, and the agent that wrote the workflow can’t fix it because it can’t see the audit log. Terse handles the long tail of that work in one place: a typed TypeScript SDK with deterministic ACL guardrails on every integration call (the Slack guardrail, for example, only lets the agent post in channels the workspace has explicitly approved), a sandboxed runtime you ship to with terse deploy, an audit log that unifies deterministic and agent steps, and a Claude Code plugin that lets the coding agent in your editor build and maintain workflows with you.

What a workflow looks like

A Terse workflow is a single TypeScript file. Triggers come from your generated SDK, so the GitHub repo and Slack channel referenced below resolve to typed constants your editor can autocomplete. The agent receives skills, the scope contract for integration access, and the runtime refuses any tool call outside what those skills declare. Deterministic SDK calls and agent runs share one audit log. The job below watches a repo for new pull requests, posts a deterministic Slack message announcing the PR, then threads a Block Kit summary under it:
import { GithubPRTrigger, createJob, generateText } from "terse-sdk"

import { Repos, Skills, SlackChannel, Triggers, toolbox } from "../terse.generated"

// ^^ Generated based on your workspace

createJob({
    name: "Summarize PR and send slack message",
    triggers: [Triggers.github.onPROpened({ repo: Repos.TerseAI.Terse })],
    onTrigger: async (event: GithubPRTrigger) => {
        // Deterministic call — fixed channel, fixed message. No agent needed.
        const message = await toolbox.slack.sendMessage({
            channelId: SlackChannel.AllTerseInc.channelId,
            message: "New PR from " + event.sender.login + "!"
        })

        // Outputs are strongly typed
        const parentId = message.message_ts

        // Agentic: one prompt in, the model uses the GitHub + Slack tools granted via skills
        await generateText({
            prompt: `
            Summarize this PR ${event.formatForAgentRunner()}.
            Keep it short. Format the summary in Block Kit; include screenshots or diagrams from the PR as image blocks.
            Reply in a thread to the Slack message (thread parent ts: ${parentId}).
            `,
            skills: [
                // Fine tune what the agent has access to. Impossible to touch anything outside this scope
                Skills.github({ repos: [Repos.TerseAI.Terse] }),
                Skills.slack({ channel: SlackChannel.AllTerseInc })
            ]
        })
    }
})
The skills passed to generateText are the only surface the model can reach: it can post in one Slack channel and read this one repo, nothing else. The deterministic toolbox.slack.sendMessage call returns a typed result you can thread on directly, and generateText picks up the GitHub and Slack tools without further wiring.

Supported integrations

GitHub

Slack

Attio

Linear

https://mintcdn.com/terse/QJxXNBQzMoUWeu_W/images/integrations/notion.png?fit=max&auto=format&n=QJxXNBQzMoUWeu_W&q=85&s=86d9155a38af51f60e3e03fc448f834d

Notion

https://mintcdn.com/terse/DYFm7KrHqTKQwqwJ/images/integrations/snowflake.png?fit=max&auto=format&n=DYFm7KrHqTKQwqwJ&q=85&s=d9136d4e8f9ebd3d9e0a50f3b007a987

Snowflake

https://mintcdn.com/terse/QJxXNBQzMoUWeu_W/images/integrations/gmail.png?fit=max&auto=format&n=QJxXNBQzMoUWeu_W&q=85&s=940b3fe8dd8097a7914e151f8670c3f7

Gmail

https://mintcdn.com/terse/DYFm7KrHqTKQwqwJ/images/integrations/posthog.png?fit=max&auto=format&n=DYFm7KrHqTKQwqwJ&q=85&s=5ca13bb8af96c1781221ea9284a53bd3

PostHog

https://mintcdn.com/terse/QJxXNBQzMoUWeu_W/images/integrations/datadog.png?fit=max&auto=format&n=QJxXNBQzMoUWeu_W&q=85&s=de2e582d50c16cfa0bd69863a9300cc5

Datadog

https://mintcdn.com/terse/QJxXNBQzMoUWeu_W/images/integrations/launchdarkly.jpeg?fit=max&auto=format&n=QJxXNBQzMoUWeu_W&q=85&s=684de3864f044769d756c943f72f921f

LaunchDarkly

Start building

Quickstart

Install the CLI, generate your typed SDK, and deploy a workflow that runs on the next GitHub PR. Five minutes, end to end.

Jobs

How createJob ties triggers, handlers, and agents together. The primitive every workflow is built on.