Better code for private libraries

In this tutorial we'll help you create a usage spec for a private library and share it with a Tessl user.

👉 Closed beta notice

The full framework is currently part of Tessl’s closed beta program. You can request access here.

Private usage specs are useful for documenting how to use internal libraries. They let your agent work with them as reliably as with open-source dependencies documented in the Spec Registry. You can store these specs in a private workspace and control who has access.

Creating a new private usage spec

Start with creating a directory for your usage spec:

<usage-spec-name>/
  └── <usage-spec-version>/
      ├── docs/
      │   └── index.md
      └── spec.json

In spec.json, add:

{
  "name": "<workspace-name>/<usage-spec-name>",
  "version": "<usage-spec-version>",
  "docs": "docs/index.md",
  "describes": "<link-to-util>",
  "summary": "<brief-desciption>",
  "private": true
}
  • you can find your workspace name using tessl workspace list

  • In docs/index.md, focus on how to consume your utility, not how it’s implemented. Include examples of imports, function calls, CLI commands, or common workflows. This helps both developers and agents use the utility correctly.

  • The describes link follows Purl syntax

As an example, let’s create a color-formatter utility to reuse across a project.

utils/formatter.py
"""
util_log_formatter.formatter

A colorful logging formatter for pretty terminal output.
"""

import datetime
import logging

# ANSI color codes
RESET = "\033[0m"
COLORS = {
    "DEBUG": "\033[90m",   # gray
    "INFO": "\033[92m",    # green
    "WARNING": "\033[93m", # yellow
    "ERROR": "\033[91m",   # red
    "CRITICAL": "\033[95m" # magenta
}


class ColorLogFormatter(logging.Formatter):
    """
    Custom log formatter with colors and a clean format.
    Example: [2025-09-15 14:33:01] 🔹 INFO: Server started
    """

    default_format = "[%(asctime)s] %(levelname)s: %(message)s"
    default_datefmt = "%Y-%m-%d %H:%M:%S"

    def __init__(self, fmt: str | None = None, datefmt: str | None = None):
        super().__init__(fmt or self.default_format, datefmt or self.default_datefmt)

    def format(self, record: logging.LogRecord) -> str:
        log_message = super().format(record)
        color = COLORS.get(record.levelname, "")
        icon = {
            "DEBUG": "⚙️",
            "INFO": "🔹",
            "WARNING": "⚠️",
            "ERROR": "❌",
            "CRITICAL": "🔥"
        }.get(record.levelname, "")
        return f"{color}{icon} {log_message}{RESET}"


def format_log(level: str, message: str) -> str:
    """
    Format a log message manually with colors.
    """
    timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    level = level.upper()
    color = COLORS.get(level, "")
    icon = {
        "DEBUG": "⚙️",
        "INFO": "🔹",
        "WARNING": "⚠️",
        "ERROR": "❌",
        "CRITICAL": "🔥"
    }.get(level, "")
    return f"{color}[{timestamp}] {icon} {level}: {message}{RESET}"

The directory will look like this:

The index.md should include sample usage code – see the formatter util example for reference.

util-formatter/0.0.1/docs/index.md
# Formatter Util

A colorful logging formatter for pretty terminal output.

## Package Information

- **Package Name**: util-formatter
- **Language**: Python
- **Installation**: `pip install git+https://github.com/<username>/<repo>.git`
- **Requirements**: Python 3.8+

## Core Imports

```python
from util_log_formatter import format_log
from util_log_formatter.formatter import ColorLogFormatter
```

## Usage

### Use as a print formatter

```python
from util_log_formatter import format_log

print(format_log("info", "Server started"))
print(format_log("warning", "High memory usage"))
print(format_log("error", "Something went wrong"))
```

### Use as a logging formatter

```python
import logging
from util_log_formatter.formatter import ColorLogFormatter

logger = logging.getLogger("myapp")
handler = logging.StreamHandler()
handler.setFormatter(ColorLogFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)

logger.info("Application started")
```

The spec.json should contain metadata about the usage spec.

{
  "name": "<workspace-name>/util-formatter",
  "version": "0.0.1",
  "docs": "docs/index.md",
  "describes": "pkg:github/<user>/<repo>",
  "summary": "A colorful logging formatter for pretty terminal output.",
  "private": true
}

Note: you can only publish private usage specs for now.

Publishing a usage spec

tessl registry publish util-formatter/0.0.1/

This publishes util-formatter to the workspace defined in spec.json.

Sharing a usage spec

Add a Tessl user to your workspace to share private specs with them. The viewer role is (Read-Only).

tessl workspace add-member --user <tessl-user-id> --role viewer --workspace <workspace-name>

To validate if they have been added to the workspace run:

tessl workspace list <workspace-name>

The user added to a workspace will automatically have access to all usage specs published there.

Using a private usage spec

Private specs for your workspaces are searchable just like public specs.

For example, to install the util-formatter usage spec with Claude Code:

Search and install the util-formatter usage spec.

Claude Code will find it in the Spec Registry and install it into your project using Tessl’s MCP tools.

Updating your spec to a new version

Simple bump the version and publish again

{
  "name": "<workspace-name>/util-formatter",
  "version": "0.0.2",
  "docs": "docs/index.md",
  "describes": "pkg:github/<username>/<reponame>",
  "summary": "A colorful logging formatter for pretty terminal output.",
  "private": true
}

Note: you currently will only find 1 version per Major version in tessl search . If you make major changes, don't forget to bump the Major version.

Archive and unpublish a private usage spec

To remove a usage spec from search results without deleting it, archive it with:

tessl registry archive --spec <workspace-name>/[email protected] --reason "replaced by a new library"

This will return a message confirming that the usage spec has been archived.

Private specs can be unpublished within 2 hours of upload. Use:

tessl registry unpublish <workspace-name>/[email protected]

This will return a message confirming that the usage spec has been unpublished.

Last updated