Tutorial: Command node
Custom nodes do not require TypeScript. If a program already reads stdin and writes stdout, point command at its argv and you are done. This tutorial wraps sort -u. The sort-unique example in the repo.
1. Create the folder
Section titled “1. Create the folder”mkdir -p ~/.config/threadle/nodes/sort-uniqueNo node.ts. The descriptor is enough.
2. Descriptor only
Section titled “2. Descriptor only”{ "id": "sort-unique", "label": "Sort · unique", "glyph": "⇅", "description": "sorts input lines and drops duplicates (plain sort -u)", "command": ["sort", "-u"]}Rules that matter:
| Rule | Why |
|---|---|
command is an argv array | No shell, no interpolation, no globbing |
Relative argv[0] (e.g. ./tool) | Resolves inside the node directory |
| Absolute / PATH binaries | sort, jq, python3 work as usual |
Exactly one of entry or command | Class flavor vs command flavor |
3. Try it
Section titled “3. Try it”- Reload threadle.
- Drag Sort · unique from the custom section.
- Wire
prompt → Sort · unique → output. - Prompt text:
bananaapplebananacherryapple- ▶ Run → output:
applebananacherry4. Useful variants
Section titled “4. Useful variants”Uppercase with tr:
{ "id": "upper", "label": "Uppercase", "glyph": "⇧", "command": ["tr", "a-z", "A-Z"]}jq filter (JSON in, JSON out. Set "input": "json" / "output": "json" when chaining typed nodes):
{ "id": "jq-keys", "label": "jq keys", "glyph": "{}", "input": "json", "output": "json", "command": ["jq", "keys"]}Local script:
{ "id": "my-py", "label": "My script", "glyph": "π", "command": ["python3", "./run.py"]}Put run.py next to node.json. Working directory is the node folder.
Failure modes
Section titled “Failure modes”| Symptom | Cause |
|---|---|
| Node fails with stderr excerpt | Non-zero exit. Fix the tool or the input |
timed out after …ms | Raise timeoutMs (max 300000) |
| Command not found | Binary not on PATH for the server process (GUI launches often miss ~/.local/bin) |
stderr appears in the run log even on success. Useful for jq warnings.
When to prefer a class
Section titled “When to prefer a class”Use entry + node.ts when you need params, named ports, or logic that is awkward as a one-liner. Use command when the Unix toolbox already does the job.
Ready-made wrappers for jq, rg, git, and test runners ship in the
stdlib pack. Import those before reinventing them.
Related
Section titled “Related”- Custom nodes. Descriptor fields and trust model
- Stdlib pack.
jq,rg,git-*,test-run, … - Tutorial: Extract URLs. Class flavor
- Tutorial: Typed chain. Value types across nodes
- Sharing & importing