Skip to content

CLI

One binary serves the local UI and drives the same server-side workflow executor the canvas uses.

Install methods (curl · npm · clone): Install.

threadle [server-options]
threadle daemon
threadle export <graphId|file|recipe> [out.json]
threadle export --backup [file]
threadle import <file>
threadle run <file|recipe|template|graphId> [run-options]
threadle jobs|status [--all]
threadle attach <jobId>
threadle logs [jobId] [--follow]
threadle stop <jobId>
threadle services|health
threadle providers | agents | sessions | graphs | models | nodes | skills | templates | recipes
threadle skills [list|import|export|toggle] …
threadle open [target…]
threadle check
threadle check --providers
threadle mcp
threadle --list-templates
threadle help | -h | --help
InvocationEffect
threadleStart the API + UI on 127.0.0.1
threadle daemonSame as serve with --no-open. Arms triggers.json
threadle serveSame as bare threadle. The command name is optional
threadle export <id|file>Write portable threadle/graph@1 (same as canvas ⤒)
threadle export --backup [file]Pack threadle/backup@1 (graphs, payloads, nodes, settings, favorites, folders)
threadle import <file>Import graph@1 into saved graphs, or restore backup@1
threadle run <target>Import or load a graph and execute it (foreground, in-process)
threadle run <target> --detachStart on the running server. Print jobId and exit
threadle jobsList recent jobs (all statuses)
threadle statusList running jobs (--all = history)
threadle attach <jobId>Follow a job’s logs until it ends (same as logs -f)
threadle logs [jobId]Print logs (--follow / -f until the job ends)
threadle stop <jobId>Cancel a running job
threadle services / healthServer process + provider availability
threadle providersProvider adapters only
threadle agentsAgents discovered for --dir / cwd
threadle sessionsSessions (-q, --provider, --limit)
threadle graphs / workflowsSaved graphs
threadle modelsModels returned by /api/models
threadle nodesInstalled custom nodes
threadle skillsSkill libraries. List / import / export / toggle (parity with Skills view)
threadle open [target…]Open the UI to a view / workflow / session / skill deep link
threadle templatesBundled teaching examples
threadle recipesJob recipes (examples/recipes)
threadle checkPATH + providers + config + UI assets (offline)
threadle check --providersAlso probe inject-critical CLI flags in help (subcommand / aliases)
threadle mcpStdio MCP server. Workflows as tools (offline. See MCP)
threadle --list-templatesSame as templates
threadle help / --helpPrint help and exit

Unknown commands exit 2. Override the server base with THREADLE_URL (default http://127.0.0.1:<port> from --port).

Most inventory commands require a running server (threadle --no-open). templates, recipes, check, mcp, export, and import work offline. skills and open need the server.


Same threadle/graph@1 JSON as the canvas ⤒ download. Share a single workflow without the rest of the machine.

Terminal window
threadle export hello ./hello.json
threadle export <graphId>
threadle import./hello.json # saves under ~/.config/threadle/graphs/

threadle run./hello.json still imports implicitly before executing.


Machine move or disaster recovery. Not the same as exporting one portable graph.

Terminal window
threadle export --backup # →./threadle-backup-<stamp>.json
threadle export --backup ~/Desktop/backup.json
threadle import ~/Desktop/backup.json

Schema threadle/backup@1 packs graphs/, payloads/, nodes/, settings.json, favorites.json, and workflow-folders.json (skips live graphs/versions/ snapshots). Restore writes original ids under ~/.config/threadle. Bare threadle export out.json still works as a legacy alias for --backup when out.json is not a resolvable graph.

UI: Workflows list Backup. See also Portable graphs · Files & config.


Terminal window
threadle daemon # serve --no-open + triggers.json
threadle run <id> --watch --approve-all # poor-man's trigger (see Watch mode)

Full trigger schema and launchd/systemd examples: Triggers & daemon.


Parity with the canvas Skills view. List / import / export / toggle skill libraries (SKILL.md packs). Needs a running server.

Terminal window
threadle skills # list
threadle skills import./review.SKILL.md # → threadle-imported (default)
threadle skills export review-diff./out.md
threadle skills toggle review-diff --manual # or --auto
FlagWhere
--scope globalDefault import scope (or a project dir with sessions)
--location threadle-importedDefault. Also threadle-custom / agent homes
--auto / --manualExactly one required for toggle

See Skills & rules.


Deep-link into the running UI (browser). Needs a running server.

Terminal window
threadle open # home
threadle open skills | rules | sessions | …
threadle open workflow <id|name> # /graph/:id
threadle open session cursor:abc123 # /blueprint/…
threadle open skill review-diff # Skills tab + focus
threadle open rules CLAUDE.md # Rules tab + focus
threadle open run <jobId>
threadle open map | timeline | lineage
threadle open --print skills # print URL only

Override base with THREADLE_URL / --port.


First-run / support diagnostics. Runs offline. No UI server required.

Terminal window
threadle check
threadle check --providers

Use --providers (two dashes). A single dash (-providers) is parsed as short -p and fails.

What it verifiesNotes
Node.js ≥ 22Critical (system Node, or the portable binary from curl install)
~/.config/threadle writableCritical
Baked web-distCritical after curl install / npm run build / publish
Bundled workflow templatesCritical
Agent CLIs on PATH (claude, opencode, Cursor agent, agy, codex, copilot)Soft. Print location / version when found
Provider storage readableSoft. Sessions list only when storage exists
--providers. Inject-critical tokens in CLI helpSoft skip when the binary is missing. fails if an installed CLI’s help no longer mentions a probed string

With --providers, probes are not always top-level --help:

  • Some flags live on a subcommand (e.g. opencode run --help for --format).
  • Help may use bracket aliases (e.g. Claude --append-system-prompt[-file]). Those count as a match.

Exit 0 when critical checks pass and (with --providers) no installed CLI is missing a probed token. Rows print as ok / !!.

Plain check = install readiness (does not parse transcripts). Use --providers after an upstream CLI update if injects look broken. See Providers. Full detail in the app repo: provider-freshness.md.


threadle mcp exposes each saved workflow as tool wf_<graphId> over stdio (optional publish allowlist in Settings). Hosts configure it in .mcp.json. The canvas ◈ MCP tool node is the client direction (stdio · HTTP · SSE).

Manual: MCP. Run, connect, work · node page: MCP tool.

Terminal window
threadle run examples/workflows/mcp-brief.json
threadle mcp

FlagDefaultMeaning
--port <n>4570TCP port. The host is always 127.0.0.1
--no-openoffDon’t open a browser tab
--dir <path>cwdProject directory highlighted for agents and discovery
-h, --helpShow help
Terminal window
threadle --port 4600 --no-open

Keep this process up for UI ▶ / ≫, run --detach, and every job / inventory command below. Startup also begins the read-only filesystem watchers over Claude Code, opencode, Cursor, Antigravity, Codex, Copilot, and Grok storage. SIGINT / SIGTERM shut down managed helper processes and exit 0.


Same registry as the Runs view and UI server runs.

CommandEffect
threadle jobsRecent jobs. Running, done, failed, cancelled
threadle statusRunning only. Pass --all for the same history jobs shows
threadle attach <jobId>Follow that job’s logs until it ends
threadle logs [jobId] [-f]One job’s log, or recent lines across jobs. -f = attach
threadle stop <jobId>Cancel a running job
Terminal window
threadle run knot-concat --detach
threadle attach job_….…
threadle jobs
threadle stop job_….…

Read-only probes against the live server (except templates / recipes, which use the local catalogs when the server is down).

CommandEffectUseful flags
threadle services / healthHealth, process info, and every provider’s availability
threadle providersProvider adapters only
threadle agentsAgents discovered for a project--dir <path>
threadle sessionsRecent sessions-q / --query, --provider, --limit, --dir
threadle graphs / workflowsGraphs under ~/.config/threadle/graphs/
threadle modelsModels from /api/models
threadle nodesCustom nodes under ~/.config/threadle/nodes/
threadle skillsSkill libraries (list / import / export / toggle)--auto / --manual. Import --scope / --location
threadle openOpen UI deep link--print
threadle templatesBundled teaching examplesalso --list-templates
threadle recipesJob recipes (examples/recipes)offline
threadle checkPATH + providers + config + UIoffline
threadle check --providers+ inject flag presence in CLI helpoffline
threadle mcpWorkflows as MCP tools (stdio)offline. MCP
Terminal window
threadle services
threadle agents --dir.
threadle sessions -q auth --provider cursor --limit 20
threadle graphs
threadle models
threadle nodes
threadle skills
threadle open skills
threadle templates
threadle recipes

Same executor as UI server jobs: prompts, converters, custom nodes, agents, sessions, iterators, merges, circuit breakers, frames, mute/bypass, retry, error policy, and {{param:…}} substitution. Results are written back into the graph under ~/.config/threadle/graphs/.

<target> is resolved in this order. The first match wins.

#KindMatched when
1Recipe idA job recipe (repo-brief, diff-review-panel, …). threadle recipes
2Template idA bundled teaching example (hello, plan-implement-review, …)
3Portable graph fileThe path exists as a file. Parsed as threadle/graph@1 and imported
4Example / recipe pathexamples/recipes/<target>[.json] or examples/workflows/<target>[.json] relative to cwd
5Saved graph idA graph with that id exists under ~/.config/threadle/graphs/
FlagMeaning
--param <name>=<value>Fill {{param:name}}. Repeatable. Name must match [a-zA-Z0-9_-]{1,64}. Value capped at 100 000 characters
--approve-allAuto-pass approval gates, live handoffs, and circuit-breaker parks
--dir <path>Project directory for agent CLI runs (default: cwd)
--detachPOST /api/run/workflow on the running server. Print jobId. Exit. Requires threadle already listening
--watchAfter a successful run, re-run on portable graph file mtime and/or git changes under --dir (fs fallback when not a git repo). Not with --detach / --ephemeral. Prefer triggers + threadle daemon for multi-graph automation
--keepKeep an imported graph after a foreground run (default for files/templates)
--ephemeralDelete the imported graph after a foreground run (--keep wins. Refused with --detach / --watch)
Terminal window
threadle run./flow.json --watch --approve-all --dir.
threadle run hello --watch --approve-all --dir ~/code/my-project
  1. Graph file mtime. Portable / example .json targets reload into the same graph id when the file changes.
  2. Git changes. If --dir is a git work tree, poll HEAD + git status --porcelain and re-run on change.
  3. Fallback. Non-git project and no graph file → directory fs watch (ignores .git, node_modules, build dirs).

The first run must succeed before watching starts. Graph id stays stable across re-runs.

ModeBehaviorAppears in Runs / threadle jobs?
Foreground threadle runBlocks the terminal. Streams logs to stdoutNo (unless you later open the kept graph)
threadle run --detachHands the job to the live server and exitsYes. Same registry as UI ▶ / ≫
Terminal window
# terminal A
threadle --no-open
# terminal B — several workflows in parallel
threadle run detached-delay --detach
threadle run knot-concat --detach
threadle jobs
threadle attach <jobId>
threadle logs <jobId> --follow

The executor preflights the graph and refuses before any agent work happens.

SituationBehavior
Approval gate / live handoffNeeds --approve-all / UI approve-all, otherwise refused
Context node with no payload and no session sourceBlocks. Wire a session / agent, Library payload, or mute
Payload hash present but blob deleteddetached run blocked — context "<label>" payload is missing
Agent node with no modelBlocks. Pick a model in the inspector
Required input not wiredBlocks. See Graph lint
Cycle in the graphcycle detected — workflow can never finish

Muted and bypassed nodes are exempt. Muting is the escape hatch for a node you don’t want in this run.


Foreground log lines are prefixed by lane. A space for node output, · for meta, ! for stderr. Banner lines bracket the run:

❯ running "Starter workflow" (a1b2c3d4) [imported]
✓ done — 2 output node(s) updated
· graph kept as a1b2c3d4 — open with: threadle
Exit codeMeaning
0Workflow finished (or detach accepted)
1Execution / server error
2Usage error. Missing target, bad --param, unknown command

Terminal window
threadle recipes
threadle run repo-brief --dir ~/code/unfamiliar-project --approve-all
threadle --list-templates
threadle run plan-implement-review \
--param task="Add a regression test for the login race" \
--approve-all --dir.
# or background it on a running server
threadle run plan-implement-review \
--param task="Add a regression test for the login race" \
--approve-all --detach
threadle jobs
threadle services