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

# Create & Publish

> Learn how to create and publish your tools to the Compozy registry.

## Repository-Based Tools

Repository-based tools are standalone projects that can be published and shared with other Compozy users. You can create tools using either TypeScript (running on Deno runtime) or Python, which can be compiled into platform-specific binaries for efficient distribution.

### Repository Structure

<Tabs>
  <Tab title="TypeScript">
    ```
    my-tool/
    ├── deno.json          # Deno configuration and tasks
    ├── manifest.yaml      # Tool metadata and schema definitions
    ├── README.md          # Documentation
    ├── src/               # Source code directory
    │   ├── index.ts       # Main entry point
    │   └── lib/           # Additional modules
    ├── tests/             # Test files
    │   └── index.test.ts
    ├── dist/              # Compiled binaries
    └── my-tool
    ```
  </Tab>

  <Tab title="Python">
    ```
    my-tool/
    ├── pyproject.toml    # Python project configuration
    ├── manifest.yaml     # Tool metadata and schema definitions
    ├── src/             # Source code directory
    │   ├── main.py      # Main entry point
    │   └── lib/         # Additional modules
    ├── tests/           # Test files
    │   └── test_main.py
    ├── README.md        # Documentation
    └── dist/            # Compiled binaries
        └── my-tool
    ```
  </Tab>
</Tabs>

### Project Configuration

<Tabs>
  <Tab title="TypeScript">
    The `deno.json` file configures your development environment and build process:

    ```json theme={"dark"}
    {
      "tasks": {
        "dev": "deno run --allow-read --allow-net src/index.ts",
        "test": "deno test --allow-read --allow-net tests/",
        "compile": "deno compile --allow-read --allow-net --output dist/stock-price src/index.ts",
      },
    }
    ```

    <Warning>
      The `compile` task is required in your `deno.json` file. Compozy uses this task to compile your tool into a platform-specific binary during the publishing process.
    </Warning>
  </Tab>

  <Tab title="Python">
    The `pyproject.toml` file configures your Python project:

    ```toml theme={"dark"}
    [project]
    name = "stock-price"
    version = "1.0.0"
    description = "Fetch real-time stock prices from various financial markets"
    requires-python = ">=3.8"
    dependencies = [
        "stock-api",
        "pydantic"
    ]

    [project.optional-dependencies]
    test = ["pytest", "pytest-asyncio"]

    [tool.pytest.ini_options]
    asyncio_mode = "auto"
    ```
  </Tab>
</Tabs>

### Manifest File

The `manifest.yaml` defines your tool's metadata, configuration, and I/O schema. Here's a comprehensive example:

<Note>
  The `type` field is required and must be set to `tool`. For Python projects, set `main: src/main.py` instead of `src/index.ts`.
</Note>

```yaml [expandable] theme={"dark"}
type: tool
name: stock-price
version: 1.0.0
license: MIT
description: Fetch real-time stock prices from various financial markets
repository: https://github.com/your-org/stock-price
main: src/index.ts  # Use src/main.py for Python projects

tags:
  - stocks
  - finance

author:
  name: Your Name
  email: your.email@example.com
  organization: Your Organization

schema:
  config:
    type: object
    properties:
      api_key:
        type: string
        description: "API key for accessing stock data"
      rate_limit:
        type: number
        description: "Maximum API calls per minute"
        default: 60
    required: [api_key]

  input:
    type: object
    properties:
      symbol:
        type: string
        description: "Stock symbol (e.g., AAPL, GOOGL)"
        pattern: "^[A-Z]{1,5}$"
      market:
        type: string
        description: "Stock exchange (e.g., NYSE, NASDAQ)"
        enum: ["NYSE", "NASDAQ", "LSE", "TSE"]
        default: "NYSE"
    required: [symbol]

  output:
    type: object
    properties:
      price:
        type: number
        description: "Current stock price"
      currency:
        type: string
        description: "Price currency (ISO 4217)"
        pattern: "^[A-Z]{3}$"
      timestamp:
        type: string
        description: "Last update timestamp (ISO 8601)"
        format: "date-time"
      change_24h:
        type: number
        description: "Price change in the last 24 hours (%)"
    required: [price, currency, timestamp]
```

### Implementation

<Tabs>
  <Tab title="TypeScript">
    Your `src/index.ts` should implement the schema defined in the manifest:

    ```typescript theme={"dark"}
    // You can use imports as usual with Deno
    import { StockAPI } from 'npm:stock-api';
    import { validateInput } from 'jsr:@std/validation';

    interface Config {
      api_key: string;
      rate_limit?: number;
    }

    interface Input {
      symbol: string;
      market?: 'NYSE' | 'NASDAQ' | 'LSE' | 'TSE';
    }

    interface Output {
      price: number;
      currency: string;
      timestamp: string;
      change_24h?: number;
    }

    export async function run(input: Input, config: Config): Promise<Output> {
      // Validate input
      validateInput(input);

      // Initialize API with rate limiting
      const api = new StockAPI({
        apiKey: config.api_key,
        rateLimit: config.rate_limit ?? 60
      });

      // Fetch stock data
      const data = await api.getPrice(input.symbol, input.market);

      return {
        price: data.price,
        currency: data.currency,
        timestamp: new Date().toISOString(),
        change_24h: data.change_24h
      };
    }
    ```
  </Tab>

  <Tab title="Python">
    Your `src/main.py` should implement the schema defined in the manifest:

    ```python theme={"dark"}
    from typing import TypedDict, Optional
    from datetime import datetime
    from stock_api import StockAPI
    from validation import validate_input

    class Config(TypedDict):
        api_key: str
        rate_limit: Optional[int]

    class Input(TypedDict):
        symbol: str
        market: Optional[str]  # 'NYSE' | 'NASDAQ' | 'LSE' | 'TSE'

    class Output(TypedDict):
        price: float
        currency: str
        timestamp: str
        change_24h: Optional[float]

    async def run(input: Input, config: Config) -> Output:
        # Validate input
        validate_input(input)

        # Initialize API with rate limiting
        api = StockAPI(
            api_key=config['api_key'],
            rate_limit=config.get('rate_limit', 60)
        )

        # Fetch stock data
        data = await api.get_price(input['symbol'], input.get('market'))

        return {
            'price': data.price,
            'currency': data.currency,
            'timestamp': datetime.now().isoformat(),
            'change_24h': data.change_24h
        }
    ```
  </Tab>
</Tabs>

### Publishing Process

<Steps>
  <Step title="Prepare Your Repository">
    * Initialize a GitHub repository
    * Set up CI/CD workflows for testing and releases
    * Include comprehensive documentation in README.md
  </Step>

  <Step title="Quality Checks">
    * Write unit tests covering main functionality
    * Add integration tests for API interactions
    * Ensure proper error handling and input validation
  </Step>

  <Step title="Version and Release">
    * Use semantic versioning (MAJOR.MINOR.PATCH)
    * Create GitHub releases with detailed changelogs
    * Tag releases (e.g., `v1.0.0`)
  </Step>

  <Step title="Build and Distribution">
    <Tabs>
      <Tab title="TypeScript">
        ```bash theme={"dark"}
        # Compile for all platforms
        deno task compile
        ```
      </Tab>

      <Tab title="Python">
        ```bash theme={"dark"}
        # Build Python package
        python -m build
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Submit to Registry">
    Once your tool is ready for distribution:

    ```bash theme={"dark"}
    # Login to Compozy CLI
    compozy login

    # Submit your tool
    compozy publish
    ```

    After submission, our team will review your tool to ensure it meets our quality and security standards. You'll receive notifications about the review process and when your tool is approved and listed in the registry.

    <Note>
      Make sure your repository is public and the latest release tag matches the version in your manifest.yaml before publishing.
    </Note>
  </Step>
</Steps>
