Skip to main content

v0.4.0

iota tells its terminal what it is doing, and the config says which model a chat starts on. Inside a herdr pane the chat is listed from the moment it is up — working, blocked, idle, released on exit — and the host is named in the harness prompt and on the banner. An agent now writes model: for the model it starts on and choices: for what /model and -M offer, a breaking change to the config file. The startup banner is a logo and three facts.

Added

  • iota reports its state to herdr. Inside a herdr pane — HERDR_ENV=1, a pane id and the socket herdr injects — iota tells herdr what the chat is doing, over that socket, and herdr stops guessing from the screen: idle from the moment the chat is up, working while a turn runs, blocked at an approval or a question, idle again when it is your move (after a failed turn too), the session the chat writes into (at start-up, after /save, after a /session switch), and a release on exit. A headless iota run <agent> -m … in a pane reports too: working from the start, idle with the reply, released on exit. Every report is bounded and best-effort; nothing herdr does, or fails to do, reaches the chat. The notification and the background answer stay the terminal's — herdr words its own from the state, and its pane answers OSC 11 itself. Hosts nest, and iota talks to the innermost one only: a herdr pane inside a cmux window reports to herdr and never runs cmux (X-47).
  • The harness prompt names the host. A detected host adds its facts to the <environment> block, after the run's own: host: herdr, herdr pane: w1:p2, and the workspace and tab when the pane has them; host: cmux, cmux surface: <id> under cmux. A plain terminal adds nothing.
  • The banner names the host. Inside herdr or cmux the mode row ends with · in herdr or · in cmuxchat · session 01J… · in herdr. A plain terminal's row is unchanged.

Changed

  • agents.<name>.models is two keys now — a breaking change. model: is the model a run starts on (a models: entry by name, or provider:id); choices: is what /model and -M pick from, in the three forms the old list took. Leave model: out to start in the picker; leave choices: out and the picker offers every models: entry, in the order you declared them. A provider:* under model: is refused (agents.a.model: "openai:*" is a wildcard — put it in choices: and leave model: unset to start in the picker), a model: outside the choices warns and runs anyway, and a config that still says models: on an agent stops with agents.a.models: `models` is now `choices:` (what /model and -M pick from) plus `model:` (the one the run starts on). Headless with neither -M nor model: now says no model chosen: set agents.<name>.model or pass -M. iota list agents shows each agent's model and how many choices it has; iota list models <agent> marks the one the run starts on with *. The starter config writes model: gpt (X-48).
  • The banner is a logo and three facts. A chat opens on three rows: the iota wordmark on the left and, beside it, the version, the mode row — agent or chat, then session <id>, resumed <id> or not saved · /save keeps it — and the directory the chat runs in (the project root in agent mode, else the current directory, ~ for home). The Chat started, Commands:, Session: and Agent mode: rows are gone: the commands are one / away in the composer, the model is on the status row. A directory longer than the row is cut in the middle (/Volumes/build/…/packages/cli) rather than wrapped; a terminal too narrow for the wordmark, the gutter and the mode row (57 columns in a plain terminal, more when the row names a host) gets the three facts alone; NO_COLOR gets them bare (X-46).