Skip to main content
A project bundles your job definitions, their generated SDK, and a small config file that links them to the Terse platform. You scaffold one with terse init, write jobs inside it, and run terse deploy to ship the whole project at once.

On disk

my-project/
  src/
    terse.jobs.ts        # job manifest (entry point): one side-effect import per job
    jobs/
      sample-job.ts      # each job lives in its own file here
    terse.generated.ts   # typed SDK (regenerated by `terse generate`)
  terse.config.json      # links the directory to a Terse project
  package.json
  tsconfig.json
  .env.example
The config file is the only thing the platform needs to recognize the directory:
{
    "projectId": "cmpn2w26d001ibpmx8kr00yc7",
    "name": "deal-automation"
}
projectId is assigned the first time the project is created and ties this code to a specific project in the Terse app. Commit terse.config.json to your repo so anyone cloning it can run terse deploy without re-creating the project.

Lifecycle

  1. Create. Run terse init <name> to scaffold a new project. The CLI sets up the files, installs dependencies, opens the browser to authenticate you, and runs terse generate against your connected integrations.
  2. Develop. Define each job in its own file under src/jobs/ and import it for side effects from the src/terse.jobs.ts manifest. Run terse generate again whenever you add or reconfigure an integration.
  3. Test. Run terse test to execute jobs locally against sample events.
  4. Deploy. Run terse deploy to ship the project. New jobs are created, existing jobs are updated, and removed jobs are cleaned up in a single pass.
  5. Monitor. Open the project in the Terse app to see runs, actions, and failures.
To register an existing codebase as a project without scaffolding, run terse attach in its root.

Where the project runs

Terse splits into a control plane (orchestrator, triggers, dashboard, history) and a data plane (the runtime that executes your onTrigger code). Each can run on Terse Cloud or in your own infrastructure. A project’s terse.config.json controls only the data plane choice; the control plane choice is set by TERSE_BACKEND_URL at the CLI/SDK level. By default, terse deploy zips your code and the Terse Cloud data plane runs it serverlessly. No infrastructure to manage. To route execution to a data plane you operate, add two fields to terse.config.json:
{
    "projectId": "cmpn2w26d001ibpmx8kr00yc7",
    "name": "deal-automation",
    "selfHosted": true,
    "remoteServerUrl": "https://terse.your-company.com"
}
In this mode, the control plane calls your server when triggers fire instead of running the handler itself. See Self-hosting the data plane for the full setup, or Self-hosting the control plane to run the orchestrator inside your network too.

Where to go next

Jobs

The trigger-plus-handler unit you write inside a project.

CLI reference

Every terse command and its flags.