Typed ports
How data flows between nodes automatically — no agent in the loop.
Typed ports
Connections do two different things in Riggr. The first is granting permission to the agent — covered in Connections and permissions. The second is moving data between nodes automatically, with the agent out of the picture. That second mode uses a typed port system.
When two nodes have compatible ports and are connected, Riggr wires it up for you. You wired it. You stopped thinking about it.
How it works
Every node declares the ports it has — inputs (consume data) and outputs (emit data). Each port has a type (what it carries) and a mode (how it delivers).
Available types (from src/renderer/src/ports/portTypes.ts):
string— plain text (current webview URL, selected file path).string-stream— continuous text events (log lines, terminal output).number,boolean— scalars.filepath— absolute path.logLine— structured line{ timestamp, level, text }.rows— tabular query result.json— serializable object.
Modes:
value— last write wins. State, like "which file is selected right now".stream— pub/sub events. Each event delivered once, not held.
Integrations that happen on their own
Wire up two compatible nodes and the connection's chip shows the typed integration — it starts running. Ones that ship by default:
| From → To | What happens |
|---|---|
| Terminal → Text | Every line of terminal output is appended to the text node. |
| File Explorer → Code | Clicked a file in the explorer? Code opens it. |
| File Explorer → Text | Loads the selected file into the text node. |
| Code → Git | Saved the file? Git refreshes status. |
| Process Manager → Text | Process logs stream live into the text. |
| Process Manager → Agent Terminal | A process crashed? The agent gets an auto-debug prompt. |
| Process Manager → Webview | Browser console error? Restart processes. |
| Docker → Text | Container logs land in the text. |
| Env → Process Manager | Variables become each process's env. |
| Env → HTTP Client | Variables become request headers. |
| Database → JSON | The latest query result shows up as a JSON object. |
| Database → Text | The result becomes a markdown table; history goes to the text. |
| JSON → HTTP Client | The JSON becomes the request body. |
| HTTP Client → JSON | The last response shows up as JSON. |
| HTTP Client → Code | The last response as text in the editor. |
| Webview → HTTP Client | The browser's current URL becomes the request URL. |
| Webview → Text | Console errors become text. |
| Task → Agent Terminal | A scheduled prompt fires as a message to the agent. |
The full list lives in Connector list — all the ports:*->* integrations.
Why this isn't the same as agent permissions
| Agent permission (chip) | Typed port |
|---|---|
| Agent decides when and how to act | Happens on its own, no agent |
Explicit tool calls (riggr_run_db_query) |
Direct dataflow between nodes |
| You pick the permission | They just need compatible ports |
The two systems share a connection. You can wire Code → Agent (permission) and Code → Git (port) — the UI separates them on the chip.
Adapters
Some combinations don't match the type exactly, but Riggr converts them:
logLine (stream)→string-stream (stream)— only the.textfield flows through.string (value)→string-stream (stream)— re-emitted once.number/boolean→string— coerced for display.
No magic beyond that. Different types without an adapter just don't connect — the chip won't show.
In practice
Build a log-streaming flow with no agent involved:
- Process Manager running
npm run dev. - Text right next to it.
- Wire the two. The chip shows the
ports:logs->appendTextintegration active. - Every line from the server, the Text grows.
Now wire an Agent Terminal to the Text. When something in the log looks off, ask the agent "check the last error in this text and tell me what happened". The agent reads via permission (text-read); the Text receives logs via port. Both mechanisms run in parallel.