Announcing Workspace Widgets
Today we're shipping Workspace Widgets, a way to put live, interactive apps directly onto the Robutler workspace canvas, side by side with your agents and chats.
What changed
Up until today the workspace was a great place to talk to your agents and pin content for later. With Widgets, it becomes a real desktop you build out of small composable pieces:
- A Python kernel that runs in your tab: numpy + matplotlib preinstalled. Plot a chart and it lands as a sibling widget on the canvas, not buried in a terminal pane.
- A Local shell attached to a daemon on your own machine.
- An SSH widget for the production boxes you keep coming back to. Same key + host management as the legacy terminal, just cleaner.
- A Browser embed for the dashboards you live in.
- A CodeMirror editor for fast text + code edits.
- Sticky notes, shapes, and connectors for sketching plans on the canvas (like Figjam, but right next to your agent).
- And a handful of arcade-style games (Snake, Tetris, Space Invaders) because workspaces should be fun.
Spin one up from the + button → Widget → search the
catalogue.
What's new for agent builders
Widgets aren't just for humans. Agents can:
- Spawn widgets onto the canvas through the
present.*tool family.present.image,present.code,present.url,present.chart,present.note, and a genericpresent.widgethelper let agents post visual artefacts alongside the conversation. - Drive Python kernels through
workspace_widgets_invoke(id, 'eval' | 'run', ...). Subscribe tostdout/stderr/displayevents and matplotlib figures stream directly back into the canvas in real time. - Run shell commands on daemon + SSH widgets through the same
workspace_widgets_invoke(id, 'run', ...)tool. Every command writes an auditedwidget.agent_commandnotification so you can see exactly what ran.
The agent factory is aware of the new surface: it can build
widgets from a few prompt hints, wire host.kv for state, and
emit DSL projections for the native iOS / Android Robutler apps.
Trust by default, opt-in for risk
Letting an agent run shell commands is dangerous if the toggle is always ON. So we ship the opposite default: every daemon + SSH widget starts with Allow agents to run commands OFF. Flip it ON per widget when you're ready, flip it OFF when you're done.
Python kernels default ON because they're sandboxed inside your tab: even a wildly misbehaving agent can't escape Pyodide. The toggle is still there if you want to lock the kernel down for a shared session.
Every accepted AND rejected agent command writes an audit row.
Open the notifications feed and grep for widget.agent_command
to see your weekly history.
Cross-platform widgets
Widgets can optionally ship a projection, a tiny declarative tree compiled from a JS function. Projections power three things:
- A lightweight preview that renders on the canvas without loading the full iframe (huge win for performance with dozens of widgets pinned).
- A native widget render in the iOS / Android Robutler apps coming later this year. The app polls the projection periodically and renders it as a real iOS / Android widget tile.
- A dock projection: pin a widget to the dock and the projection takes over so you can read state at a glance without committing the full iframe to memory.
If you're writing a widget today, returning a projection is optional but encouraged. See the host SDK guide for the DSL grammar.
Try it
Open your workspace, tap the + button, and pick
Widget. Or just ask your agent: "Show me a stock chart for
NVDA" and watch the Python kernel boot, the matplotlib figure
spawn, and the agent caption it next door.
We can't wait to see what you build.
The Robutler team