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

# Packages

> Install, create, and manage integration packages

Integration packages bundle agents, functions, skills, components, templates, and other resources into a shareable YAML file that can be installed with one click.

**How packages work:**

1. **Create**: Select resources from your Sinas instance → export as `SinasPackage` YAML
2. **Share**: Distribute the YAML file (GitHub, email, package registry)
3. **Install**: Paste/upload the YAML → preview changes → confirm install
4. **Uninstall**: Removes all resources created by the package in one operation

**Package YAML format:**

```yaml theme={null}
apiVersion: sinas.co/v1
kind: SinasPackage
package:
  name: crm-integration
  version: "1.0.0"
  description: "CRM support agents and functions"
  author: "team@company.com"
  url: "https://github.com/company/sinas-crm"
spec:
  variables: [...]     # Install-time configuration (optional)
  agents: [...]
  functions: [...]
  skills: [...]
  connectors: [...]
  components: [...]
  templates: [...]
  queries: [...]
  collections: [...]
  stores: [...]
  webhooks: [...]
  schedules: [...]
  manifests: [...]
  databaseTriggers: [...]
  dependencies: [...]
```

**Key behaviors:**

* Resources created by packages are tagged with `managed_by: "pkg:<name>"`
* **Detach-on-edit**: Editing a package-managed resource clears `managed_by` — the resource survives uninstall
* **Uninstall**: Deletes all resources where `managed_by = "pkg:<name>"` + the package record
* **Upgrade**: Re-installing an existing package updates its resources in place (idempotent apply)
* **Excluded types**: Packages cannot include roles, users, LLM providers, or database connections (these are environment-specific)
* **Dependencies**: Packages can declare Python dependencies — these are recorded in the database and installed in containers on worker restart

## Install-time Variables

Packages can declare typed variables that are prompted during installation. Variables are substituted into the YAML before resources are persisted — the resulting resources contain literal values, no runtime template evaluation.

**Declaring variables:**

```yaml theme={null}
spec:
  variables:
    - name: APP_URL
      type: text
      description: Base URL where the app is reachable from containers
      example: http://host.docker.internal:8080
      required: true

    - name: PRIMARY_LLM
      type: resource_ref
      resource: llm_providers
      description: LLM provider for capable agents
      required: true

    - name: CHEAP_LLM
      type: resource_ref
      resource: llm_providers
      description: LLM provider for filtering/extraction agents
      required: true

    - name: ENABLE_LOGGING
      type: boolean
      default: false
      description: Enable verbose logging in functions

    - name: API_KEY
      type: secret
      description: External service API key
      required: true
```

**Variable types:**

| Type           | Description                    | Validation                                                                                          |
| -------------- | ------------------------------ | --------------------------------------------------------------------------------------------------- |
| `text`         | Free text input                | Optional `pattern` (regex)                                                                          |
| `boolean`      | True/false toggle              | —                                                                                                   |
| `enum`         | Fixed choices                  | `choices: [a, b, c]`                                                                                |
| `resource_ref` | Pointer to existing resource   | `resource: llm_providers\|database_connections\|collections\|secrets\|roles` — validated at install |
| `secret`       | Masked input, stored encrypted | Creates/upserts a Secret. Not re-prompted on upgrade if already exists.                             |

**Substitution syntax:**

Use `${{ vars.NAME }}` anywhere in the package spec. Resolved by simple string replacement before parsing — not Jinja2, so no conflicts with system prompt templates.

```yaml theme={null}
connectors:
  - baseUrl: "${{ vars.APP_URL }}"

agents:
  - llmProviderName: "${{ vars.PRIMARY_LLM }}"
```

**API:**

* `POST /api/v1/packages/preview` — response includes `variables` (declarations) and `requires_input` (bool). Pass `variables: {NAME: value}` in the request to preview with substitution.
* `POST /api/v1/packages/install` — pass `variables: {NAME: value}` in the request. Required variables must be present.

**Stored values:**

Variable values from the last install are stored in `Package.values`. On upgrade, the console pre-fills the form with previous values. Secret values are stored as `"***"` — the actual credential lives in the Secrets table.

**Endpoints:**

```
POST   /api/v1/packages/install       # Install package from YAML
POST   /api/v1/packages/preview       # Preview install (dry run)
POST   /api/v1/packages/create        # Create package YAML from selected resources
GET    /api/v1/packages               # List installed packages
GET    /api/v1/packages/{name}        # Get package details
DELETE /api/v1/packages/{name}        # Uninstall package
GET    /api/v1/packages/{name}/export # Export original YAML
```

**Creating a package from existing resources:**

```bash theme={null}
curl -X POST https://yourdomain.com/api/v1/packages/create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-package",
    "version": "1.0.0",
    "description": "My integration package",
    "resources": [
      {"type": "agent", "namespace": "support", "name": "ticket-bot"},
      {"type": "function", "namespace": "support", "name": "lookup-customer"},
      {"type": "template", "namespace": "support", "name": "ticket-reply"},
      {"type": "schedule", "namespace": "default", "name": "daily-digest"}
    ]
  }'
```

Supported resource types: `agent`, `function`, `skill`, `connector`, `manifest`, `component`, `query`, `collection`, `store`, `template`, `webhook`, `schedule`, `database_trigger`.
