Metadata-Version: 2.5
Name: pointiv-extension-sdk
Version: 0.4.1
Summary: Python SDK for building Pointiv WASM extensions
Project-URL: Repository, https://github.com/katkodeorg/pointiv-extension-sdk-python
Author: Katkode
License-Expression: MIT
License-File: LICENSE
Keywords: extension,plugin,pointiv,sdk,wasm
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# pointiv-extension-sdk

Python SDK for [Pointiv](https://pointiv.katkode.com) WASM extensions.

## Install

```sh
pip install pointiv-extension-sdk
```

## Setup

extism-py requires `@extism.import_fn` host bindings in the compiled entry file. Declare them in `host_bindings.py`, wire the SDK with `bind`, then build a merged entry:

```python
# host_bindings.py
import extism
from pointiv_extension_sdk import bind

@extism.import_fn("extism:host", "pointiv_storage_read")
def pointiv_storage_read(key: str) -> str: pass

@extism.import_fn("extism:host", "pointiv_storage_write")
def pointiv_storage_write(key: str, value: str): pass

@extism.import_fn("extism:host", "pointiv_storage_delete")
def pointiv_storage_delete(key: str): pass

bind.storage_hosts(pointiv_storage_read, pointiv_storage_write, pointiv_storage_delete)
```

```sh
cat host_bindings.py main.py > entry.py
extism-py entry.py -o extension.wasm
```

See the [Python starter](https://github.com/katkodeorg/pointiv-extension-starter-python.ptr) for a full example.

Build to WASM with [`extism-py`](https://github.com/extism/python-pdk), then set `runtime: "wasm"` and `main: "extension.wasm"` in `pointiv-extension.json`.

## APIs

| Module | Permission | What it does |
|--------|------------|--------------|
| `storage` | `storage` | Per-extension key/value store |
| `clipboard` | `clipboard_read` | Read clipboard |
| `ai` | `ai` | LLM completion |
| `http` | `network` | Outbound HTTP |
| `google_calendar` | `google_calendar` | Create Calendar events |
| `google_gmail` | `google_gmail` | Send Gmail |
| `log` | none | Log to `~/.pointiv/trace.jsonl` |

Calls without permission fail safely.

## Python/WASM limitations

extism-py cannot call zero-argument host functions reliably. These APIs raise `NotImplementedError` in Python/WASM builds:

- `storage.list()`
- `clipboard.read()`

Use `storage.read()` / `storage.write()` / `storage.delete()` instead. Host functions use the `extism:host` namespace (Pointiv registers both `extism:host` and `extism:host/user`).

## Tiles

Extensions can render a declarative tile widget beside the popup command bar. Declare a `"tiles"` block in `pointiv-extension.json` (requires `"runtime": "wasm"`) and export `render_tile` from your entry file. `render_tile` is a plugin export decorated with `@extism.plugin_fn`, so the host-import shims wired through `bind.py` stay exactly as they are:

```python
import json
import extism
from pointiv_extension_sdk import tile

@extism.plugin_fn
def render_tile():
    # input is {"now": "<RFC3339>"}: json.loads(extism.input_str())
    ui = tile.tile(
        "Todos",
        body=[
            tile.badge("2 open", tone="warn"),
            tile.row("Buy milk", actions=[tile.action("Done", "todo done 1")]),
        ],
        footer=[tile.action("Refresh", "todo list")],
    )
    tile.output_tile(ui)
```

```json
"tiles": { "height": 2, "zone": "right", "order": 1 }
```

The host calls `render_tile` when the popup opens and after a tile action runs, with a 3 second budget and storage-only host access. Action commands run through your normal `execute` function. Iterate with the playground in Pointiv Settings, Tiles: paste tile JSON for instant validation and preview, or live-render an installed extension's tile. Full schema, limits, and the component catalog are in TILES.md in the Pointiv repo.

## Manifest

```json
{
  "name": "My Extension",
  "description": "What it does",
  "version": "1.0.0",
  "author": "your-name",
  "keywords": ["tag"],
  "runtime": "wasm",
  "main": "extension.wasm",
  "permissions": ["storage", "network", "google_calendar", "google_gmail"]
}
```

## License

MIT
