Skip to content

Portable graphs

Workflows are plain JSON with the schema id threadle/graph@1. A graph can leave your machine, land on someone else’s, and run.


⤒ Export in the canvas topbar copies the workflow to your clipboard (falling back to a file download).

Export strips everything machine-local:

Stripped or clearedWhy
Run statuses, last-run idsRuntime state, not structure
Session ids and referencesThey mean nothing on another machine
Payload hashesThe other machine has a different content store
Absolute skill and rules pathsRe-resolved by name on import
Graph id and timestampsRegenerated on import

What survives is the part that matters: nodes, wiring, params, templates, node settings, frames.


Portable (threadle/graph@1)Backup (threadle/backup@1)
GoalShare or clone one workflowMove / restore this machine’s threadle config
ContentsStripped graph JSONgraphs/, payloads/, nodes/, settings.json, folders
IdsFresh id on importOriginal graph ids kept
CLIthreadle run./file.jsonthreadle export / threadle import
UICanvas ⤒ Export / Workflows importWorkflows Backup

⤓ Import on the Workflows page pastes a graph back in as a fresh copy. New id, idle statuses, edges re-validated against the schema. Errors point at the exact path that failed, so a hand-edited file tells you which node is malformed rather than failing opaquely.

Skills and rules nodes re-resolve by name against what’s installed locally. A graph that used review-diff finds your review-diff, wherever it lives.


{
"$schema": "threadle/graph@1",
"name": "Plan → implement → review",
"params": [
{ "name": "task", "type": "text", "description": "What to build" }
],
"nodes": [
{
"id": "n-prompt",
"type": "prompt",
"position": { "x": 120, "y": 200 },
"status": "idle",
"data": { "type": "prompt", "text": "Plan: {{param:task}}" }
}
],
"edges": [
{ "id": "e1", "source": "n-prompt", "target": "n-agent" }
]
}

No import step needed:

Terminal window
threadle run./my-flow.json --param task="..." --approve-all

By default an imported graph is kept in your library after the run. Pass --ephemeral to discard it.


TravelsDoesn’t
Structure, wiring, params, templatesSession history
Skill and rules nodes (by name)Materialized context payloads
Custom node references (by id)The custom node’s code. Ship that separately
Agent nodes (provider + name + model)Whether the recipient has that agent installed

A shared graph is a blueprint, not a finished run: the recipient needs the same ingredients installed. Missing agents and custom nodes are reported by the readiness check rather than failing mid-run.


A graph saved as a sub-workflow is a graph like any other, so it exports and imports the same way. A parent graph referencing it carries the link. Share both.