Terse compiles your workspace into a typed SDK. Workflows reference real resources by name, and coding agents build against ground truth instead of guesses.
Use this file to discover all available pages before exploring further.
Most automation platforms treat your workspace as runtime data: every execution rediscovers which channel is which, which list is which, which repo is which. That’s fragile for humans and invisible to coding agents.Terse inverts that. terse generate reads your connected integrations and compiles your workspace into typed code. Your workflows import real resources by name, and your coding agent (Cursor, Claude Code, Windsurf) sees the full surface as autocompletions and types.
This adds latency, wastes tokens, and silently breaks when someone renames a channel.At build time, coding agents have no idea what lives in your workspace. They guess at channel names, hallucinate list IDs, and produce workflows you have to manually correct. There’s no autocomplete, no type check, and no way for the agent to know what’s actually connected.
Compile your workspace into typed code once, then write workflows against it. Resource IDs become constants. Trigger builders and skills become namespaces. Tool wrappers become typed methods on agent.tools.*.
import { TerseAgent, createJob } from "terse-sdk"import { Attio, AttioList, Slack, SlackChannel } from "./terse.generated"createJob({ name: "new-deal-enrichment", triggers: [Attio.onRecordCreated({ list: AttioList.Pipeline.NewDeals })], onTrigger: async event => { const agent = TerseAgent.create({ prompt: "You enrich new deals and alert the deal desk.", skills: [Attio.skill({ lists: [AttioList.Pipeline.NewDeals] }), Slack.skill({ channel: SlackChannel.DealDesk })] }) /* your logic */ }})
No runtime discovery. No hardcoded IDs. If an agent or a human references a resource that doesn’t exist in your workspace, the TypeScript compiler rejects it and terse deploy refuses to ship.