> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useterse.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Skills & Tools

> All available skills and the tools they expose to your workflows.

Skills define what integrations your workflow can interact with. Each skill exposes a set of tools that the agent can call (via agentic loops) or that you can call deterministically (via `agent.tools.*`).

In TypeScript, `terse generate` writes a single `Skills` object in `src/terse.generated.ts`. Import it and call the nested factory for the integration you want (for example `Skills.github({ repos: [...] })`). Built-in capabilities like `Skills.web()`, `Skills.imageEdit()`, and `Skills.memory()` are documented in their sections below.

## GitHub

Read-only access to repositories.

```ts theme={null}
skills: [Skills.github({ repos: [Repos.MyOrg.MyRepo] })]
```

| Tool                             | Description                              | Access |
| -------------------------------- | ---------------------------------------- | ------ |
| `searchGitHubCode`               | Semantic code search across repositories | Read   |
| `grepGitHubCode`                 | Exact-match code search (grep-like)      | Read   |
| `readGitHubFile`                 | Read file contents                       | Read   |
| `listGitHubDirectory`            | List directory contents                  | Read   |
| `listGitHubPullRequests`         | List pull requests                       | Read   |
| `listGitHubCommits`              | List commits                             | Read   |
| `summarizeGitHubPullRequestDiff` | Summarize PR changes                     | Read   |

## Slack

Send messages and read conversations.

```ts theme={null}
skills: [Skills.slack({ channel: SlackChannel.Engineering })]
```

| Tool                      | Description                                                                      | Access |
| ------------------------- | -------------------------------------------------------------------------------- | ------ |
| `slack_send_message`      | Send to a channel, an existing DM (`channelId`), or a member 1:1 (`slackUserId`) | Write  |
| `slack_list_users`        | List workspace users                                                             | Read   |
| `slack_list_channels`     | List channels                                                                    | Read   |
| `slack_read_conversation` | Read conversation history                                                        | Read   |

For `slack_send_message`, pass either `channelId` (a public or private channel id, or an existing DM channel id) or `slackUserId` (a member id, `U…`). Terse opens the DM if needed. If you pass both, `channelId` wins and the message goes there. After `terse generate`, use `SlackChannel.*.channelId` and `SlackUser.*.userId` from `src/terse.generated.ts` instead of hand-copying ids.

## Linear

Create, update, and search issues.

```ts theme={null}
skills: [Skills.linear()]
```

| Tool                   | Description               | Access |
| ---------------------- | ------------------------- | ------ |
| `linear_search_ticket` | Search tickets            | Read   |
| `linear_get_teams`     | List teams                | Read   |
| `linear_get_states`    | Get issue states          | Read   |
| `linear_get_labels`    | Get available labels      | Read   |
| `linear_get_projects`  | List projects             | Read   |
| `linear_get_users`     | List team members         | Read   |
| `linear_read_ticket`   | Read ticket details       | Read   |
| `linear_create_ticket` | Create a new ticket       | Write  |
| `linear_update_ticket` | Update a ticket           | Write  |
| `linear_add_comment`   | Add a comment to a ticket | Write  |

## Attio

Query and manage CRM records.

```ts theme={null}
skills: [Skills.attio({ object: AttioObject.People })]
```

| Tool                  | Description               | Access |
| --------------------- | ------------------------- | ------ |
| `attio_list_objects`  | List available objects    | Read   |
| `attio_query_records` | Query records             | Read   |
| `attio_upsert_record` | Create or update a record | Write  |

## Notion

Read and write databases and pages. Optionally scope to specific databases or pages.

```ts theme={null}
import { NotionDatabase, NotionPage, Skills } from "./terse.generated"

skills: [Skills.notion({ databases: [NotionDatabase.Roadmap], pages: [NotionPage.OnCallRunbook] })]
```

`databases` and `pages` are both optional. Omit them to give the model access to every database and page the integration can reach.

| Tool                                   | Description                       | Access |
| -------------------------------------- | --------------------------------- | ------ |
| `notion_get_schema`                    | Get database schema               | Read   |
| `notion_query_database`                | Query a database                  | Read   |
| `notion_query_page`                    | Query page content                | Read   |
| `notion_list_users`                    | List workspace users              | Read   |
| `notion_create_or_update_database_row` | Create or update database rows    | Write  |
| `notion_create_or_update_page`         | Create or update standalone pages | Write  |
| `notion_modify_blocks`                 | Modify page blocks                | Write  |

## Gmail

Send emails (auto-send, no human review).

```ts theme={null}
skills: [Skills.gmail()]
```

| Tool               | Description                     | Access |
| ------------------ | ------------------------------- | ------ |
| `gmail_send_email` | Send emails or reply to threads | Write  |

## Gmail Draft

Create draft emails for a human to review and send manually.

```ts theme={null}
skills: [Skills.gmailDraft()]
```

| Tool                 | Description                          | Access |
| -------------------- | ------------------------------------ | ------ |
| `gmail_create_draft` | Create draft emails for human review | Write  |

## Snowflake

Read-only SQL query execution.

```ts theme={null}
skills: [Skills.snowflake()]
```

| Tool                    | Description                                | Access |
| ----------------------- | ------------------------------------------ | ------ |
| `snowflakeExplainQuery` | Explain query execution plan               | Read   |
| `snowflakeExecuteQuery` | Execute SELECT queries (requires approval) | Read   |

## Datadog

Read-only access to logs and RUM events. Optionally scope to specific log indexes.

```ts theme={null}
import { DatadogIndex, Skills } from "./terse.generated"

skills: [Skills.datadog({ indexes: [DatadogIndex.Main] })]
```

`indexes` is optional. Omit it to search across every index the integration can reach.

| Tool                 | Description              | Access |
| -------------------- | ------------------------ | ------ |
| `searchDatadogLogs`  | Search logs              | Read   |
| `listRumEvents`      | List RUM events          | Read   |
| `searchRumEvents`    | Search RUM events        | Read   |
| `aggregateRumEvents` | Aggregate RUM event data | Read   |

## PostHog

Read-only access to product analytics. Supports US PostHog Cloud (`us.posthog.com`) only; EU-hosted PostHog is not supported.

```ts theme={null}
import { PosthogProject, Skills } from "./terse.generated"

skills: [Skills.posthog({ project: PosthogProject.MyTeam })]
```

`terse generate` also emits a `PosthogEventName` union of the custom event names observed in your project over the last 180 days, so `eventName` filters are checked at compile time. Built-in `$`-prefixed events like `$pageview` are always accepted.

| Tool                      | Description                             | Access |
| ------------------------- | --------------------------------------- | ------ |
| `searchPosthogLogs`       | Search logs                             | Read   |
| `searchPosthogSessions`   | Search sessions                         | Read   |
| `getPosthogSessionEvents` | Get events for a session                | Read   |
| `listPosthogEventNames`   | List event names with occurrence counts | Read   |
| `searchPosthogEvents`     | Search events                           | Read   |

## LaunchDarkly

Read-only access to feature flags.

```ts theme={null}
import { LaunchDarklyProject, Skills } from "./terse.generated"

skills: [Skills.launchDarkly({ project: LaunchDarklyProject.MyFlags, environmentKeys: ["production"] })]
```

| Tool                         | Description        | Access |
| ---------------------------- | ------------------ | ------ |
| `listLaunchDarklyFlags`      | List feature flags | Read   |
| `getLaunchDarklyFlagDetails` | Get flag details   | Read   |

## WorkOS

Read-only access to users and organizations.

```ts theme={null}
skills: [Skills.workOS()]
```

| Tool                      | Description        | Access |
| ------------------------- | ------------------ | ------ |
| `listWorkOSUsers`         | List users         | Read   |
| `listWorkOSOrganizations` | List organizations | Read   |
| `getWorkOSUser`           | Get user details   | Read   |

## Web (built-in)

Web search and research tools available to all workflows.

```ts theme={null}
skills: [Skills.web()]
```

Pass `allowedDomains` to restrict the agent to a whitelist of sites. When set, `web_search` results and `web_extract` page fetches are limited to those domains and their subdomains; requests to any other domain are blocked.

```ts theme={null}
skills: [Skills.web({ allowedDomains: ["example.com", "docs.acme.com"] })]
```

| Tool           | Description                             | Access | Respects `allowedDomains` |
| -------------- | --------------------------------------- | ------ | ------------------------- |
| `web_search`   | Search the web                          | Read   | Yes                       |
| `web_extract`  | Extract and process web page content    | Read   | Yes                       |
| `web_research` | Research and synthesize web information | Read   | No (not domain-limited)   |

## Image Edit (built-in)

Edit and generate images.

```ts theme={null}
skills: [Skills.imageEdit()]
```

| Tool         | Description                | Access |
| ------------ | -------------------------- | ------ |
| `image_edit` | Edit and manipulate images | Write  |

## Memory (built-in)

Gives a job a persistent `/memories` directory it can read and write across runs. With the skill added, the agent checks `/memories` before starting and records progress, context, and learnings as it works, so later runs pick up where earlier ones left off.

```ts theme={null}
skills: [Skills.memory()]
```

| Tool     | Description                                                                                                             | Access |
| -------- | ----------------------------------------------------------------------------------------------------------------------- | ------ |
| `memory` | Read, write, edit, and organize files under `/memories` (`view`, `create`, `str_replace`, `insert`, `delete`, `rename`) | Write  |

### What persists between runs

Only files under `/memories` carry over. Every run otherwise starts fresh from your deployed code, so anything written elsewhere in the run is discarded. Anything the agent saves to `/memories` is still there on the next run.

### How memory is organized

* **Per project** — each project has its own isolated memory. Jobs in different projects never share memory.
* **Per job** — within a project, every job gets its own private space; one job cannot see another job's memory.
* **Scoped to `/memories`** — all paths stay inside the `/memories` directory.

Cleanup is automatic: deleting a job removes that job's memory, and deleting a project removes all memory for the project.

`terse test` runs against a separate, isolated test memory, so local testing never touches what your deployed job has saved.

### Inspecting memory

Use the [`terse memory`](/reference/cli#memory) commands to list, read, write, and delete a job's memory files from the terminal. Add `--test` to any of them to target the isolated `terse test` memory instead of production.
