> For the complete documentation index, see [llms.txt](https://docs.tessl.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tessl.io/reference/configuration.md).

# Configuration files

## Plugin configuration

### plugin.json

The `.tessl-plugin/plugin.json` file is the configuration file for a plugin. It includes important metadata that helps Tessl identify, version and describe plugins.

Plugins can contain three types of content:

* **rules**: Rule files (markdown) that provide subjective guidance and instructions to agents, such as coding standards, best practices, and organizational policies.
* **skills**: Skill files (SKILL.md format) that extend AI coding agents with specialized knowledge, workflows, or tool integrations. Skills follow the [Agent Skills Specification](https://agentskills.io/specification).

A plugin can contain one or more of these content types. For example, a plugin might have only documentation, only rules, only skills, or any combination of the three.

Here's an example `.tessl-plugin/plugin.json`:

```json
{
  "name": "tessl/skill-optimizer",
  "version": "0.8.1",
  "description": "Optimize your skills and plugins: review SKILL.md quality, generate eval scenarios, run evals, compare across models, diagnose gaps, and re-run until scores improve.",
  "private": false
}
```

The following sections show examples of plugins with different content types. Remember that plugins can contain **rules** or **skills**.

For example, here's what the `./tessl-plugin/plugin.json` for a private, rules-only plugin might look like:

```json
{
  "name": "myorg/code-style",
  "version": "0.0.1",
  "description": "TypeScript code style guidelines for MyOrg",
  "private": true,
  "rules": "rules" // not needed, when rules is omitted, "rules" is used as the path by convention
}
```

Plugins can also contain skills, which are reusable capabilities that extend AI coding agents. Here's an example of a plugin with skills:

```json
  {
  "name": "myworkspace/my-skill",
  "version": "1.0.0",
  "description": "A skill that provides specialized functionality for my agent",
  "private": true,
  "skills": "skills" // not needed, when skills is omitted, "skills" is used as the path by convention
}
```

And here's a plugin that combines rules, and skills:

```json
{
  "name": "myorg/comprehensive-plugin",
  "version": "2.0.0",
  "description": "Complete plugin with rules, and skills",
  "rules": "rules",      // can be omitted, set to "rules" when missing
  "skills": "skills",    // can be omitted, set to "skills" when missing
}
```

`.tessl-plugin/plugin.json` supports the following fields:

`name (string, required)`: Name for the plugin in workspace/plugin-name format

`version (string, required)`: Semantic version of the plugin

`description (string, required)`: Brief description of the plugin

`private (boolean, optional)`: Controls plugin visibility in the registry. Set to false to make the plugin publicly discoverable by all users, or true to restrict access to your workspace only. Defaults to true if not specified. Note: Authentication with tessl login is required to publish plugins regardless of this setting.

`rules (string or string[], optional)`: Path to a directory of rule files, or an array of specific .md file paths. Rules are always-loaded guidance for agents — the plugin.json equivalent of steering. Omit to use convention discovery, which scans ./rules/ for .md files automatically.

`skills (string or string[], optional)`: Path to a directory containing skill subdirectories, or an array of specific skill directory paths. Each skill directory must contain a SKILL.md file. Skills are reusable capabilities that extend AI coding agents with specialized knowledge, workflows, or tool integrations. Omit to use convention discovery, which scans ./skills/ for subdirectories containing SKILL.md automatically.

A note on plugin.json validation:

1. `rules` and `skills` are all optional. A plugin with none of these relies entirely on convention discovery. There is no requirement that at least one content type be explicitly declared.

## Project configuration

### tessl.json

The `tessl.json` file is the manifest for your repository's plugin dependencies. It specifies which plugins are installed and their versions:

```json
{
  "name": "my-project",
  "dependencies": {
    "workspace/plugin-name": {
      "version": "1.0.0"
    }
  }
}
```

This file is created automatically when you run `tessl init` or `tessl install`. Tessl manages the dependencies in this file as you install or uninstall plugins.

### Tessl project link

`tessl.json` stores the Tessl configuration for this repository, including its project link.

A Tessl project gives Tessl a stable place to attach eval runs and other repository-connected data, so your results stay tied to your codebase over time.

For example:

```diff
{
-   "name": "my-project",
+   "name": "my-workspace/my-project",
    "dependencies": {
      "workspace/plugin-name": {
        "version": "1.0.0"
    }
  }
}
```

If the local project link is missing or no longer correct, use `tessl project link` or `tessl project repair`. See [Manage projects from the CLI](/projects/manage-projects-from-the-cli.md).

### Project Mode (Managed vs Vendored)

The `mode` field in `tessl.json` controls how plugin content is managed in your repository. You can choose between two modes depending on your workflow and requirements:

#### Managed mode

**Default for existing repositories** - plugin contents are gitignored like `node_modules`

```json
{
  "name": "my-project",
  "mode": "managed",
  "dependencies": {
    "workspace/plugin-name": {
      "version": "1.0.0"
    }
  }
}
```

**Behavior:**

* plugin contents in `.tessl/plugins/` are automatically added to `.gitignore`
* plugins are reinstalled from the registry based on `tessl.json`
* Works like package managers (npm, pip) - dependencies not committed
* Keeps repository clean and small
* Team members run `tessl install` after cloning the repository

**Best for:**

* Repositories with frequent plugin updates
* Teams who prefer lighter repositories
* Standard development workflows with internet access

#### Vendored mode

**Default for new repositories** - plugin contents are committed to your repository

```json
{
  "name": "my-project",
  "mode": "vendored",
  "dependencies": {
    "workspace/plugin-name": {
      "version": "1.0.0"
    }
  }
}
```

**Behavior:**

* Plugin contents in `.tessl/plugins/` are committed to version control
* Exact plugin versions are checked into the repository
* Works offline without registry access
* Team members get plugins automatically when cloning
* Ensures reproducible builds in all environments

**Best for:**

* Air-gapped or restricted network environments
* Repositories requiring complete offline capability
* Ensuring exact reproducibility without external dependencies
* Compliance requirements for vendoring all dependencies

#### Switching modes

You can change modes at any time by updating the `mode` field in `tessl.json`:

```json
{
  "name": "my-project",
  "mode": "vendored",  // Change to "managed" or "vendored"
  "dependencies": {
    "workspace/plugin-name": {
      "version": "1.0.0"
    }
  }
}
```

After changing the mode:

* Tessl will automatically update `.gitignore` accordingly
* In **managed mode**, `.tessl/plugins/` will be added to `.gitignore`
* In **vendored mode**, `.tessl/plugins/` will be removed from `.gitignore`
* Commit the changes to apply the new mode for your team

#### Default behavior

* **New projects** (running `tessl init` in a fresh project): Defaults to **vendored mode**
* **Existing projects** (running `tessl init` in a project with existing plugins): Defaults to **managed mode**
* You can explicitly set the mode in `tessl.json` to override the default

### .tessl directory

The `.tessl` directory contains Tessl's configuration and cached data:

```
.tessl/
|-- .gitignore                  # Ignores plugins/ and RULES.md (in managed mode)
|-- plugins/                      # Downloaded plugins
|   `-- workspace/
|       `-- plugin-name/
|           |-- .tessl-plugin/plugin.json
|           |-- evals
|           |-- rules/           # Rule files
|           `-- skills/          # Skill files
|               `-- skill-name/
|                   `-- SKILL.md
`-- RULES.md                    # Generated rules for agents (not committed to git)
```

The `.tessl/.gitignore` file is automatically managed based on your project mode:

* **Managed mode**: The `plugins/` directory and `RULES.md` are added to `.gitignore` (not committed to version control)
* **Vendored mode**: The `plugins/` directory is removed from `.gitignore` (committed to version control), but `RULES.md` remains ignored as it's generated from plugin content

### Plugin directory structure

Below we see a plugin structure as it's being authored:

<pre><code><strong>&#x3C;your-plugin/skill-name>/
</strong><strong>├── .tessl-plugin/
</strong>│     └── plugin.json
└── skills/&#x3C;your-skill-name>/SKILL.md
├── evals/
│     └── scenario-1/
│          ├── task.md
│          ├── criteria.json
│          └── scenario.json        # optional: fixtures, includes, setup scripts
│     └── scenario-2/
</code></pre>

* evals/ is only present if [scenarios](/improving-your-skills/overview-improving-skills-and-plugins.md) were generated
* skills/\<your-skill-name>/SKILL.md is suggested structure, otherwise plugin.json will need a specific pointer

### Agent rule files

Tessl creates and updates rule files for AI coding agents to help them understand your repository context and installed plugins. The location and format of these files varies by agent:

* **Cursor**:
  * `.cursor/rules/tessl__*.mdc` - plugin-specific rules (auto-generated, not committed to git)
  * `.cursor/rules/tessl_context.mdc` - Instructions for gathering context from Tessl MCP
* **Claude Code**:
  * `CLAUDE.md` - Context file with instructions for gathering context from Tessl MCP
  * `.tessl/RULES.md` - Consolidated rules from all installed plugins
  * `AGENTS.md` - If this file exists, Tessl adds a reference to `.tessl/RULES.md`

These files are created when you run `tessl init --agent <agent-name>` or when Tessl auto-detects an agent in your repository.

### MCP configuration files

When configuring AI agents, Tessl adds MCP (Model Context Protocol) server configuration to connect the agent to Tessl's MCP server. The location varies by agent:

* **Cursor**: `.cursor/mcp.json`
* **Claude Code**: `.mcp.json` in the repository root

These files configure the agent to run `tessl mcp start` as an MCP server, enabling the agent to access Tessl's tools and context.

### AGENTS.md

The `AGENTS.md` file provides repository context to AI coding agents. This file is similar to `CLAUDE.md` and other agent context files used by various AI coding assistants.

**Note**: Tessl does not create or manage `AGENTS.md` directly. However, if `AGENTS.md` exists in your repository, Tessl will automatically add a reference to `.tessl/RULES.md` when you configure an agent with `tessl init`. This allows your agent to access plugin-specific guidance and context.

If you're using `AGENTS.md` in your repository:

* Add your own repository context, coding conventions, and patterns
* Tessl will append a section linking to `.tessl/RULES.md` (marked with `<!-- tessl-managed -->`)
* The content is used by AI agents during code generation

### .tesslignore

Exclude files from plugin validation and packing.

**Purpose**

The `.tesslignore` file allows you to exclude files from orphaned file warnings and prevent them from being included in published plugin packages.

**Location**

Place a `.tesslignore` file in the root of your plugin directory (same level as `.tessl-plugin/plugin.json`).

**Syntax**

Uses gitignore-style patterns:

```gitignore
# Comments start with #

# Exact file names
notes.md

# Glob patterns
*.draft.md

# Directory patterns (trailing slash)
drafts/

# Recursive patterns
**/internal/**

# Path-specific patterns
docs/internal.md

# Negation patterns (exclude from ignore)
!important.md
```

**Default ignored files**

These files are always ignored, even without a `.tesslignore` file:

* `AGENTS.md`
* `CLAUDE.md`
* `GEMINI.md`

**Important rules**

* **Links to ignored files cause errors**: If your docs link to a file that's in `.tesslignore`, validation will fail. This prevents broken links in published plugins.
* **Manifest files can't be ignored**: You cannot put `docs`, `rules`, or `skills` entrypoints in `.tesslignore`.

**Example `.tesslignore`**

```gitignore
# Development notes
notes.md
TODO.md

# Draft files
*.draft.md

# Local testing
test-data/

# Keep this one even though it matches *.draft.md
!important.draft.md
```

## Eval scenario configuration

### scenario.json

`scenario.json` lives next to `task.md` and `criteria.json` in a scenario directory. It declares what the platform sets up in the working directory before an agent solves the task — fixtures to install, local files to copy in, and setup scripts to run.

`scenario.json` is **optional**. With nothing but `task.md` and `criteria.json`, conventional defaults take over (see [Conventional defaults](#conventional-defaults)).

```json
{
  "description": "Add a CSV import endpoint",
  "fixtures": {
    "codebase": {
      "type": "commit",
      "repoUrl": "https://github.com/org/repo.git",
      "ref": "abc1234",
      "exclude": ["*.mdc", "*.md", ".tessl/"]
    }
  },
  "include": ["./resources"],
  "setup": ["./seed-db.sh"]
}
```

#### Fields

* `description` (string, optional): Human-readable summary of the scenario.
* `fixtures` (object, optional): Named external content the platform installs into the working directory. Keys are arbitrary names; values are fixture objects (see [Fixture types](#fixture-types)). Order-independent.
* `include` (string\[], optional): Paths inside the scenario directory copied into the working directory at the **same relative path**. Each entry must be a directory.
* `setup` (string\[], optional): Paths to scripts inside the scenario directory, run **in order** after fixtures and includes are installed.

#### Fixture types

Two fixture types are supported in `scenario.json`:

`commit` — snapshot of a git repo at a specific ref.

```json
{
  "type": "commit",
  "repoUrl": "https://github.com/org/repo.git",
  "ref": "abc1234",
  "installPath": ".",
  "exclude": ["*.mdc"]
}
```

* `repoUrl` (string, required): HTTPS clone URL.
* `ref` (string, required): Commit SHA or any ref resolvable in the remote.
* `installPath` (string, optional, default `.`): Write destination, confined to the working directory.
* `exclude` (string\[], optional): Glob patterns of paths to exclude from the snapshot.

`directory` — content from a local path relative to the scenario.

```json
{
  "type": "directory",
  "path": "./fixtures/seed-data",
  "installPath": "data",
  "include": ["src/**/*.ts"],
  "exclude": ["**/*.test.ts"]
}
```

* `path` (string, required): Read source, resolved relative to the scenario directory but not confined to it; it may resolve to a location outside the scenario directory, including parent traversal.
* `installPath` (string, required): Write destination, confined to the working directory.
* `include` (string\[], optional): Glob patterns of files to keep from the directory. When omitted, the whole directory is installed; when present, only matching files are kept. Applied before `exclude`.
* `exclude` (string\[], optional): Glob patterns of files to remove from the directory. Applied after `include`.

#### Conventional defaults

Without explicit configuration, two on-disk conventions take effect:

* If a `resources/` directory sits alongside `task.md`, it's automatically copied into the working directory at `resources/`. Equivalent to `"include": ["./resources"]`.
* If a `setup.sh` file sits alongside `task.md`, it's automatically run after fixtures and includes install. Equivalent to `"setup": ["./setup.sh"]`.

A scenario directory containing only `task.md`, `criteria.json`, `resources/`, and `setup.sh` therefore needs no `scenario.json` at all.

#### Working directory assembly order

1. Install fixtures (all entries, order-independent).
2. Copy includes (paths preserved).
3. Run setup scripts in `setup` order, with auto-detected `setup.sh` last.

#### Legacy format

A singular `fixture` object (without the `s`) at the top level is read as a `commit` fixture named `codebase` for backward compatibility with scenarios generated before the `fixtures` plural form. Prefer the plural form for new scenarios.

## User preferences

Tessl stores user preferences globally to customize your experience. You can view and modify these preferences using the `tessl config` commands.

### Available preferences

* `shareUsageData` - Whether to share telemetry and usage data with Tessl (defaults to `true`)
* `agents` - Which agents to configure on `tessl init` (default to auto-detect when empty); see supported agents in `tessl init --help` .

### Managing preferences

View all current preferences:

```bash
tessl config get
```

View a specific preference:

```bash
tessl config get shareUsageData
```

Set a preference:

```bash
tessl config set shareUsageData false
```

### Opting out of telemetry

To opt out of sharing telemetry and usage data:

```bash
tessl config set shareUsageData false
```

For more information about data collection, see [Sharing Usage Data](/legal/sharing-usage-data.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tessl.io/reference/configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
