Skip to main content

Module: repl

An embedded Python REPL pane with a small SDK (dash) for scripting the dashboard — panes, widgets, workspaces, window operations — programmatically.

Status: implemented. The repl.console panel is a cell-based interpreter (not a PTY): you type Python, Enter runs the cell, a trailing expression echoes its repr, and state persists across cells. Each console is backed by a per-/ws kernel on the backend whose injected dash object relays UI operations to the same browser. It is the programmatic twin of the agent orchestrator: both drive the UI through the one shared executeTool relay surface, so anything the agent can do, the REPL can do.

Contributions to the layout shell

  • Panels: repl.console (one kernel per instance, default: bottom dock tab group; non-singleton — open as many as you like, tab/split/float them).
  • Commands: repl.new ("Python REPL: New console").
  • Workflow layout: the console is part of the built-in Scripting layout (files · editor · REPL + terminal) in the shell rail — see windowing.

The dash SDK

Every session's namespace is seeded with one object, dash. Calls are ordinary synchronous Python — under the hood each blocks the cell on a round-trip to the browser, but you write it like a normal function call. The table below is the quick map; the Python SDK reference is the canonical doc (return shapes, error handling, recipes, how to extend it).

CallRelayed toolDoes
dash.panes.available()list_available_panesEvery openable pane (panel + widget)
dash.panes.open_list()list_open_panesPanes open in the active workspace
dash.panes.open(id)open_paneOpen a panel/widget by id
dash.panes.close(id)close_paneClose an open pane
dash.workspaces.list()list_workspacesNamed workspaces + which is active
dash.workspaces.create(name)create_workspaceNew workspace, switched to
dash.workspaces.switch(id)switch_workspaceSwitch workspace tab
dash.context(instanceId)get_pane_contextRead a live widget's state snapshot
dash.call(name, **args)anyEscape hatch: relay any tool by name

dash.call reaches every per-widget agentTool and agent-exposed command, so new capabilities are scriptable the moment they exist — no SDK change needed.

dash.panes.available() # discover ids
dash.panes.open("settings.home") # open Settings
ws = dash.workspaces.list() # inspect workspaces
panes = dash.panes.open_list() # find a live instanceId
dash.context(panes["panes"][0]["instanceId"]) # read its state

Backend surface

backend/modules/repl/ owns the interpreter — backend implemented. A ReplManager lives per /ws connection (like TerminalManager) and routes the repl channel; kernels are dropped when the socket closes.

  • kernel.pyReplKernel: one persistent namespace per session. A cell is parsed with ast; a trailing bare expression is split off and eval'd for its repr (IPython-style echo), the rest exec'd. Errors come back as a formatted traceback (the kernel's own frame stripped), never raised.
  • manager.py — runs each cell in a worker thread (asyncio.to_thread) so a slow line never stalls the event loop; stdout/stderr stream live to the pane.
  • sdk.py — the dash facade. Each method calls a synchronous bridge that hops to the event loop with run_coroutine_threadsafe, sends a tool_call, and blocks the worker thread on the browser's tool_result — reusing WsConnection.pending (the same future map the agent uses, keyed by a unique callId).

Channel protocol ({channel:'repl', event, data}):

Directioneventdata
client→serverstart / exec / close{id, code?}
server→clientstarted / stdout / stderr{id, banner?/data?}
server→clientresult{id, ok, repr?, error?}
server→clienttool_call{id, callId, name, args}
client→servertool_result{id, callId, ok, result, error}

Agent integration

The REPL pane exposes its recent transcript via getAgentContext(), so the agent can read what a console has been doing. The REPL does not declare gated agent tools of its own.

Browser vs desktop

ConcernBrowserDesktop
Where Python runson the backend host (local dev: your machine; remote backend: the server)localhost backend = your machine
UI operationsrelayed to the originating tab via executeTool (identical surface)identical
Console UXidentical (shared frontend pane)identical

Security note

The REPL is arbitrary backend code execution plus ungated UI mutation — by design, matching the trusted, local-app posture (the same trust model as the terminal pane: a console is the user's own direct intent, so its dash.* calls are not routed through the agent permission gate). This is safe while the backend is bound to localhost. Any future remote-access story must address auth at the backend boundary — exposing the backend beyond localhost exposes a Python interpreter on that host.