The .tron document
A tron as one JSON document: export it, check it, import it, change a tron from it, and pack everything into a zip. Never a secret, only the slots to fill.
The routes
/trons/:id/exportThe vibetron.tron/2 document of the tron: same rows, same bytes. ?memory=include adds the memories./trons/:id/export?complete=1Export complete: a .tron.zip with tron.json (memories included), workspace/, libraries/<name>/ (the original documents) and manifest.json (every file with its sha256). Streamed; capped by your plan's disk, 413 beyond./trons/import?mode=check|strict|lenientA NEW tron from { document, name? }. check only reports; strict (the default) creates nothing and answers 409 unresolved if a model, plugin, skill, MCP server, pinned version, library or callable tron is not in your catalogue; lenient creates it and leaves those empty./trons/import?complete=1Import complete: multipart with the .tron.zip. Every file is checked against the manifest before anything is created; then the document is imported (same modes) and the files restored, library documents queued for indexing./trons/:id/documentChanges an EXISTING tron from a document, even a partial one: { document, prune?, mode? }. Agents are matched by uid, then by name; a matched agent is replaced as a whole, a new one is added, the others stay unless prune: true./trons/:id/secretsThe secret slots of the tron, each with set: true|false and where it is filled./v1/trons/:id/documentTron API (scope trons:read): the document of a tron the key covers./v1/trons/:id/documentTron API (scope trons:write): the same as PUT /trons/:id/document./v1/trons/:id/export?complete=1Tron API (scope files:read): the Export complete package.The report
Every import, check and update answers with the same report: resolved, unresolved (what stops a strict import, each with its reason — not_found, ambiguous, version_not_found…), needs (the secret slots) and warnings (what came in but not as it was, for instance left_empty in lenient mode). agents pairs each new agent id with the source_id it had in the exported tron.
Secret slots
A document never carries a value. secrets[] lists every slot to fill, as { name, kind, for, required, hint }: vault_key (a reference of the tron or an agent), plugin_key, bridge_token (a credential of a bridge), mcp_header, oauth_account (a connected account), caller (given by whoever calls, with each turn). At import a connected account or a caller credential is created «to be set» in the references; the tron's Overview lists them all with a link to where each is filled.
What the document carries
Agents (model as provider/model, soul, settings, plugins and skills by name with their version, MCP servers by name and registry entry, memories, links, libraries, the stable uid), memories, schedules, the interface with its schema, bridges without their tokens, libraries without their documents, startup commands, Python requirements, caps, layout. The schema is public: GET /public/v1/tron-schema.
A form, filled from your code
A tron whose interface is a form takes inputs instead of message — on POST /v1/trons/:id/messages and in the chat: { "inputs": { "city": "Turin" } }. The server fills the template exactly as the site does; a required field left empty is a 422 form_incomplete that names it.
From the account's MCP server
The same door from POST /mcp with an MCP key: export_tron, validate_tron (an import with mode check: nothing is written), import_tron with mode strict, lenient or check, and update_tron, which changes a tron from its document (PUT /trons/:id/document, without prune).
Squeez is gone
The old Squeez package promised a tron that runs outside Vibetron; the runtime needs the Vibetron gateway, a signed manifest and a private image, so it could not. Export complete replaces it: for archiving, moving a tron between accounts and restoring it.