This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/PACKAGES.md
Jeffrey Smith 5883cb50e2 Changeset 0.30.2 cs2 (#202)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-03-18 18:05:58 +00:00

276 lines
7.7 KiB
Markdown

# Package Format & Manifest Reference
> v0.30.2
A `.pkg` file is a ZIP archive containing a `manifest.json` and optional
assets. Packages extend Chat Switchboard with surfaces (routable UIs),
extensions (server-side hooks/tools), or workflows.
## Archive Structure
```
manifest.json required — package metadata and configuration
js/ optional — JavaScript assets (served at /surfaces/:id/js/)
main.js entry point (loaded by surface template)
css/ optional — stylesheets
assets/ optional — images, icons, etc.
script.star optional — Starlark script (extension/sidecar tiers)
migrations/ optional — Starlark migration scripts (keyed by version)
1.star
2.star
```
## Building & Installing
```bash
# Build from packages/ directory
bash packages/build.sh my-package # one package
bash packages/build.sh # all packages
# Install via API
curl -X POST http://localhost:3000/api/v1/admin/packages/install \
-H "Authorization: Bearer $TOKEN" \
-F file=@dist/my-package.pkg
# Install via admin UI
# Admin → System → Packages → Upload
```
## Manifest Schema
### Required Fields
| Field | Type | Description |
|-------|------|-------------|
| `id` | `string` | Unique package identifier (kebab-case). Used as directory name and DB key. |
| `title` | `string` | Human-readable display name. |
### Optional Fields
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `type` | `string` | `"surface"` | Package type (see below). |
| `version` | `string` | `""` | Semver version string. |
| `description` | `string` | `""` | Short description shown in admin UI. |
| `author` | `string` | `""` | Author name or org. |
| `tier` | `string` | `"browser"` | Execution tier: `browser`, `starlark`, `sidecar`. |
| `route` | `string` | — | URL path for surface routing (e.g. `/s/my-surface`). |
| `auth` | `string` | `"authenticated"` | Auth requirement: `authenticated` or `public`. |
| `layout` | `string` | `"single"` | Page layout template. |
| `permissions` | `string[]` | `[]` | Required permissions (see Permissions below). |
| `tools` | `object[]` | — | Server-side tool declarations for AI tool-use. |
| `hooks` | `string[]` | — | Lifecycle hooks: `surface`, `on_install`, `on_uninstall`. |
| `settings` | `object` | — | Settings schema for admin-configurable options. |
| `schema_version` | `integer` | `0` | Current data schema version (for migrations). |
| `migrations` | `object` | — | Starlark migration scripts keyed by target version. |
| `network_access` | `string[]` | — | Allowed external hostnames (sidecar tier). |
| `api_routes` | `object[]` | — | Custom HTTP routes handled by Starlark `on_request`. |
| `db_tables` | `object[]` | — | Extension-owned database tables. |
| `pipes` | `object` | — | Filter pipeline registrations. |
| `components` | `string[]` | — | UI component identifiers. |
| `workflow_definition` | `object` | — | Embedded workflow definition (type `"workflow"` only). |
## Package Types
### `surface` (default)
A routable page served at the `route` path. The browser loads
`js/main.js` and renders into `#extension-mount`.
```json
{
"id": "my-dashboard",
"title": "My Dashboard",
"type": "surface",
"route": "/s/my-dashboard",
"auth": "authenticated",
"layout": "single",
"version": "1.0.0"
}
```
### `extension`
Server-side logic without a routable UI. Runs Starlark code with
granted permissions.
```json
{
"id": "auto-tagger",
"title": "Auto Tagger",
"type": "extension",
"tier": "starlark",
"version": "1.0.0",
"permissions": ["filters.pre_completion"],
"tools": [
{
"name": "tag_message",
"description": "Auto-tag messages based on content"
}
]
}
```
### `full`
Both a surface and an extension. Has a routable page and server-side
hooks/tools.
```json
{
"id": "analytics",
"title": "Analytics Suite",
"type": "full",
"tier": "starlark",
"route": "/s/analytics",
"version": "1.0.0",
"permissions": ["db.read", "db.write"],
"db_tables": [
{ "name": "events", "columns": { "ts": "text", "event": "text", "data": "text" } }
]
}
```
### `workflow`
A packaged workflow definition with optional surfaces and handlers.
See [WORKFLOW-PACKAGES.md](WORKFLOW-PACKAGES.md) for details.
```json
{
"id": "onboarding-flow",
"title": "Employee Onboarding",
"type": "workflow",
"version": "1.0.0",
"workflow_definition": {
"name": "Employee Onboarding",
"slug": "employee-onboarding",
"entry_mode": "public_link",
"stages": [...]
}
}
```
## Permissions
Declared in `manifest.permissions`. Admins grant/revoke per-package in
the admin UI.
| Permission | Description |
|-----------|-------------|
| `secrets.read` | Read secrets from the vault |
| `notifications.send` | Send push notifications |
| `filters.pre_completion` | Intercept messages before AI completion |
| `db.read` | Read from extension-owned tables |
| `db.write` | Write to extension-owned tables |
| `api.http` | Make outbound HTTP requests (sidecar tier) |
| `provider.complete` | Call LLM completion APIs |
| `forms.validate` | Validate workflow form submissions |
| `workflow.access` | Access workflow definitions and stage data |
## Settings Schema
Packages can declare admin-configurable settings. The schema drives a
form in the admin UI under System → Packages → Settings.
```json
{
"settings": {
"api_key": {
"type": "string",
"label": "API Key",
"description": "External service API key",
"required": true
},
"max_results": {
"type": "number",
"label": "Max Results",
"default": 10
},
"enabled": {
"type": "boolean",
"label": "Enable Feature",
"default": true
}
}
}
```
Settings are stored in the `package_settings` column and accessible from
Starlark via `settings.get("key")`.
## Data Migrations
Packages with `db_tables` can version their schema using Starlark
migration scripts. The engine runs migrations sequentially on
install/upgrade and rejects downgrades.
```json
{
"schema_version": 2,
"migrations": {
"1": "def migrate(db):\n db.query('CREATE TABLE ...')\n",
"2": "def migrate(db):\n db.query('ALTER TABLE ...')\n"
}
}
```
Or reference files in the archive:
```
migrations/
1.star # def migrate(db): ...
2.star # def migrate(db): ...
```
## Extension Database Tables
Tables are namespaced to `ext_{pkg_id}_{table}` to prevent collisions.
Platform views provide read-only access to core data:
| View | Columns |
|------|---------|
| `ext_view_users` | `id`, `display_name`, `email` |
| `ext_view_channels` | `id`, `title`, `type`, `team_id` |
The `ext_data_tables` catalog tracks all extension-owned tables for
install/uninstall lifecycle management.
## Server-Side Tools
Extensions can declare tools for AI tool-use. The `on_tool_call` entry
point in the Starlark script handles dispatching.
```json
{
"tools": [
{
"name": "lookup_customer",
"description": "Look up customer by email",
"parameters": {
"email": { "type": "string", "required": true }
}
}
]
}
```
```python
# script.star
def on_tool_call(tool_name, params):
if tool_name == "lookup_customer":
result = http.get("https://api.example.com/customers?email=" + params["email"])
return {"name": result["name"], "plan": result["plan"]}
```
## User-Installable Packages
Packages can be scoped to individual users or teams (v0.30.0). Only
`browser`-tier packages support user installation. Scope options:
| Scope | Visibility |
|-------|-----------|
| `global` | All users (admin-installed only) |
| `team` | Team members only |
| `personal` | Installing user only |