From flmux
Write dart_monty Python scripts that drive the flmux terminal multiplexer via the fl_* host functions — open/split panes, stream text into them, read their screens, show source, and REACT to live UI notifications (pane splits/closes/focus, agent status). Trigger when a Monty plan should render sub-agent output in live flmux panes or respond to what the user does in the flmux UI.
How this skill is triggered — by the user, by Claude, or both
Slash command
/flmux:flmux-montyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Drive a running **flmux** (Flutter terminal multiplexer) from a Monty plan over
Drive a running flmux (Flutter terminal multiplexer) from a Monty plan over
its Unix-domain JSON-RPC control plane (FLMUX_SOCKET_PATH, default
/tmp/flmux.sock). The host owns the socket; the script just calls verbs.
FFI only — dart:io sockets have no WASM equivalent, so these functions are
absent on the WASM backend.
import 'package:dart_monty/dart_monty.dart';
import 'package:pi_agent/pi_agent.dart';
final runtime = MontyRuntime(extensions: [FlmuxExtension()]);
requires([
"fl_split", "fl_send", "fl_read", "fl_focus", "fl_code",
"fl_subscribe", "fl_events", "fl_wait",
])
fl_split(direction: str = 'column', kind: str = 'shell', surface_id: int = None) -> intOpen a new pane and return its integer surface_id. direction is 'column'
(stacked) or 'row' (side by side). kind is 'shell' (real PTY) or
'monty' (in-process REPL). Pass surface_id to split a specific pane instead
of the focused one. Give each sub-agent its own pane so their output streams
side by side.
fl_send(surface_id: int, text: str) -> boolType text into a pane as if typed at the keyboard. To submit, end with \r
(carriage return — what the Enter key sends), not \n. A shell accepts either,
but a TUI (e.g. pi) treats \n as a literal newline in its editor and only
submits on \r — so \n will pile your input up unsubmitted. Streaming output
appears live; \r-terminated sends are recorded in the pane's durable History.
fl_read(surface_id: int) -> strReturn the pane's current visible screen as plain text.
fl_focus(surface_id: int) -> boolFocus a pane.
fl_code(title: str, source: str, direction: str = 'row', surface_id: int = None) -> intOpen a pane showing source as syntax-highlighted Python (via bat) — use it
to SHOW the Monty script a level is executing. Returns the new surface_id.
flmux pushes notifications; subscribe once, then poll. Two shapes:
{"kind": "state", "tree": {…}} — on split / close / focus / maximize.{"kind": "event", "type": "status", "surface_id": int, "status"?: str, "progress"?: float, "label"?: str} — on a status update.fl_subscribe() -> boolOpen the persistent subscription. Call once before polling (the poll verbs auto-subscribe too).
fl_events() -> list[dict]Return and clear every notification received since the last call (non-blocking;
[] if none).
fl_wait(timeout_ms: int = 2000) -> dict | NoneBlock up to timeout_ms for the next notification and return it, or None on
timeout. Use to react without busy-looping.
Stream an agent's work into its own pane:
requires(["fl_split", "fl_send"])
sid = fl_split(direction="column")
fl_send(sid, 'printf "\\033]0;search\\007"\r') # title the pane (\r submits)
fl_send(sid, "echo searching kagi...\r")
# Submitting to a pi/TUI pane: end with \r, NOT \n —
fl_send(sid, "What is the flmux skill?\r")
React to the UI / agent status (no busy-loop):
requires(["fl_subscribe", "fl_wait"])
fl_subscribe()
while True:
ev = fl_wait(3000)
if ev is None:
continue
if ev["kind"] == "event" and ev.get("status") == "done":
print("pane", ev["surface_id"], "finished:", ev.get("label"))
break
if ev["kind"] == "state":
pass # tree changed (split/close/focus)
See the pi-agent skill to combine these: one pi sub-agent per pane,
streaming its output with fl_send.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub runyaga/flmux --plugin flmux