Skip to content
Install

Command plugins

Connect Python, JavaScript, native programs, and Docker over JSONL.

Use Command when a plugin needs a local model, native library, or container. Pentect starts one process and keeps it alive for the protected session.

Manifest

toml
schema = "pentect.plugin.v1"
name = "my-model"
command = ["python", "{plugin}/server.py"]
hooks = ["inspect"]
required = true

The first item is the executable. Pentect resolves its exact path and executes the argv directly without a shell. {plugin}/server.py marks a distributed file: Pentect downloads it, stores its SHA-256, and checks the hash before launch. A plugin-owned native executable can use the same prefix:

toml
command = ["{plugin}/scanner", "--stdio"]
hooks = ["inspect"]

Python, native programs, and Docker use the same field:

toml
command = ["docker", "run", "--rm", "-i", "example/policy@sha256:..."]

Docker images are not a separate plugin type. Pin the image digest and review the mounts and network flags in the displayed argv.

If executable names differ by OS, replace command with a small platform map:

toml
hooks = ["inspect"]

[commands]
windows = ["py", "{plugin}/server.py"]
macos = ["python3", "{plugin}/server.py"]
linux = ["python3", "{plugin}/server.py"]

Only the current OS command runs. If its entry is missing, Pentect reports the plugin as unsupported instead of guessing another executable.

Protocol

Read one JSON object per line from stdin and write one response per line to stdout. Requests include schema, id, hook, payload, optional metadata, and the plugin's own config object. Pentect discards stderr so an untrusted plugin cannot copy values into the protected client's terminal; use value-free Pentect activity logs for runtime diagnostics.

json
{"schema":"pentect.plugin.v1","id":1,"hook":"inspect","payload":{"kind":"text","text":"hello"},"metadata":null,"config":{}}

The response must repeat the schema and id:

json
{"schema":"pentect.plugin.v1","id":1,"type":"result","action":"next","spans":[]}

Pentect stops and restarts a process after invalid JSON, a wrong id, a timeout, an oversized response, or an unexpected exit.

Python

Install the small helper or copy its dependency-free source:

sh
python -m pip install pentect-plugin
python
from pentect_plugin import serve

def inspect(request):
    text = request["payload"]["text"]
    return {"spans": []}

serve(inspect)

JavaScript

sh
npm install @pentect/plugin
js
import {serve} from '@pentect/plugin';

await serve(request => ({spans: []}));

Both helpers preserve the request id and turn an uncaught handler error into a protocol error. They do not add a web server or network dependency.

Set Command plugin configuration with the normal CLI:

sh
pentect plugins config my-model model.threshold=0.8

The handler reads it from request["config"] in Python or request.config in JavaScript. Command is native, so it receives the complete plugin-specific configuration object. Wasm keeps the narrower key-by-key c.config(...) API.

Managed environment setup

Command plugins that need a model, virtual environment, or device-specific runtime can declare [setup] in plugin.toml. The command is displayed as part of the native approval and runs during plugins add and plugins setup. Platform-specific commands use [setup.commands].

toml
[setup]
command = ["python", "{plugin}/setup.py"]
profiles = ["auto", "cpu", "cuda"]
profile_arg = "--profile"
download = "CPU: about 3 GB; CUDA: about 6 GB"
disk = "CPU: about 5 GB; CUDA: about 8 GB"
sh
pentect plugins add ./my-model --profile auto
pentect plugins setup my-model --profile cpu

Setup is still native code, not a sandboxed package hook. Pentect never invokes a shell, locks every distributed {plugin}/... setup file, and rolls managed command state back when setup fails. The setup program should stage and replace its own external environment atomically.

Security boundary

Command is native. It runs with the current user's OS permissions. Pentect clears most inherited environment variables, avoids a shell, locks distributed files and the resolved executable into the approval, limits protocol I/O, and enforces a deadline, but it is not a sandbox.

Use Wasm when Pentect must enforce exact file, environment, storage, command, or network permissions. Use Command only for code you trust and inspect the complete argv before approval.

Pentect is open source.