Sign in
Developer tools
0%

Developer tools

The ? prompt

Type ? and a question at your zsh prompt and Io answers in a card under it, with a row of actions, follow-ups with ??, modes, your IO.md notes and, in a session, your Roles. What each part does, what is sent and what is released.

At your prompt, type ? and a question. Io answers in a card under it. The line is never run by the shell and never lands in your history, so a question is as cheap as a keystroke, and a line such as ?.txt still runs as it always did.

? why did cargo build fail
?? and how do I fix it       # a follow-up: the last question and answer come along
$ ? cargo build says it cannot find Cargo.toml
╭─ ◆ Io ─────────────────────── Claude Code (local) · haiku · manual mode · 1.2s
│
│ cargo could not find Cargo.toml here. The project is one folder down, in
│ my-shop/.
│
│ Change into it and build again:
│
│ ❯ cd my-shop && cargo build
│
│ Run · Copy · Follow up · Explain · Add folder ↓ to choose
╰─ ?? follows up.
A capture from iohr-preview, with the spinner before the card left out. The card is iohr's own output; the answer text is a fixed sample from a stand-in for the model, so the page shows the layout without sending a question.

Where each part stands

Everything on this page is in the release (0.1.0-alpha.39), except the chat box in the panel, which is only in iohr-preview, the next build.

PartBuild
? and ??, the card, every action under it, the questions Io asks back, the permission card, modes, folders Io may read and attached outputThe release
IO.md notes, your site as sources, --role, Roles answering in a session, bare iohr with its panel, and the asks count in your promptThe release
The chat box at the bottom of the panel (below)iohr-preview

Turn it on

? is a hook for zsh. Add this to ~/.zshrc:

eval "$(iohr shell hook zsh)"

To try the preview, use eval "$(iohr-preview shell hook zsh)" instead: the prompt then asks iohr-preview. Only zsh has the hook today; iohr shell hook bash and iohr shell hook fish print an error and exit 1. INORBIT_ASK=0 turns it off for one session. Inside the InOrbit app the hook asks the app to draw the answer instead of printing it.

The hook also puts a count such as "3 asks" in your right prompt when asks wait for you. It reads a number kept on disk and refreshes it in the background, so the prompt never waits for the network. INORBIT_ASKS_PROMPT=0 turns it off, and iohr asks list shows them (command line).

What the card is

Io answers by running Claude Code on your machine, under your own sign-in; it never uses an API key. The card says so. Its header is Io, with the agent, the model, the mode and how long it took on the right; a failed run shows a no answer badge. Without colour or a terminal, one plain line says the same: Io running on Claude Code, an AI model, under your own subscription.

A line under the header says what was read: "output not sent" when no command output went with the question, and "context: IO.md x3" when IO.md notes went with it. An AI answer can be wrong, so read a command before you run it. When Io needs to know something to answer, the card asks you, at most two questions, and answers again.

The actions under the card

If the answer holds a command, it is shown on its own line. Under the card, a row lists what you can do with the answer, and a key chooses:

ActionWhat it does
RunRuns the command at once, as a line you typed
CopyPuts the command on the clipboard
Follow upStarts a ?? question about this answer
ExplainAsks what the answer means, as a ?? question
OpenOpens the link or file the answer named. It refuses a program and a path outside the folder
UndoRemoves a permission rule this answer saved
Add folderKeeps one more folder for Io to read on every later question (below)
AllowShown when Io asked to read a folder: allows it, then puts the question on your prompt again
Next stepsNumbered entries Io suggests, at most four: Read X/, Read X/ (all) for its subfolders too, Search for X and Run X. Each is asked as a ?? question when you pick it
Attach outputAfter a failed command and a question such as "why did that fail": re-runs the command or takes pasted output (below)
AsksShown when asks wait for you

Run and Copy are there only when the answer has a command, and Open only when it names a link or a file. Run follows your rules before anything runs:

  • A command a deny rule matches never runs.
  • A command that deserves a second look (sudo, rm -rf, a download piped into a shell, a forced git change) or one iohr cannot check (a substitution, a redirect) asks "Run it?" first, starting on No, unless an allow rule covers it.
  • A command with a placeholder in it (path/to/..., <file>, YOUR_KEY, or a folder that does not exist) gets Copy only, so you fill it in yourself.

The key is the Down arrow on an empty line by default; [ask] menu_key in config.toml sets ctrl-g, alt-enter or off. Without a key, iohr ask --menu opens the same menu.

When Io wants to run a command

Io reads with read-only tools. Before it runs a command that your rules do not cover, it asks you on an Io card marked AI request: [1] Allow once, [2] Always in this project and [3] No, starting on No. Arrows and Enter, a number, or y, a and n choose; Esc, q and Ctrl-C mean no. Always saves the narrowest rule that fits, such as Bash(ls:*), in the project's .inorbit/permissions.toml. Without colour, without a terminal or in a window under 40 columns, the ask is one plain line: y once, a always in this project, n no.

iohr permissions list, allow, deny and remove show and change the rules, for the project or for you, and iohr permissions check Bash ls says what they decide for one call.

Folders Io may read

Io reads the folder you ask from. Asked from your home folder, the card first asks whether to trust it: yes and remember, this time only, or no. The answer is kept in trusted.toml, and folders that hold secrets stay closed either way.

When a question needs another folder (your home folder, the root, or one the question names), Io asks to read it instead of saying it cannot. Allow keeps that yes for the folder, and it is used only when a question needs that folder again. To name more folders yourself:

? what does the deploy script expect --read ../infra
WayScope
--read FOLDER (or --add-dir), repeatedOne question
IOHR_ASK_READEvery question in this shell: a list of paths, : apart (; on Windows)
[ask] read in config.tomlEvery question
Add folder in the menuEvery later question, kept in trusted.toml

At most 8 folders. Each must exist and be readable. iohr refuses the root, your home folder (only an explicit --read ~ names it) and every folder above it. Secret places stay closed whatever you allow: ~/.ssh, ~/.aws, ~/.gnupg, ~/.kube, ~/Library/Keychains, the sign-ins of gcloud, Azure, DigitalOcean and 1Password, and browser profiles. Each grant is written to iohr's permissions.log with where it came from (a flag, the environment, the config, trusted.toml or the card) and the path, never what was read.

Attach a failed command's output

A zsh hook cannot see what a command printed, so by default no output is sent. After a command fails and you ask something like "why did that fail", the menu offers two ways to add it:

  • Re-run with output shows the exact command and asks first, starting on No. It runs it once, for at most 10 seconds, and keeps the last 16 KiB of what it printed.
  • Paste output reads what you paste, up to Ctrl-D.

Either way the output is redacted (passwords, tokens, URLs, host names and IP addresses), cut to the last 8 KiB or 200 lines when it is sent, and goes with the next question only.

Modes

Press Shift+Tab on a ? line to switch the mode. The prompt says which one is on, and every question carries it.

ModeWhat Io may do
manualRead files, and ask you before each command it wants to run. The default at a terminal
planRead only: it reads files and answers with a plan, and changes and runs nothing
autoRun commands that your rules do not forbid, without asking. A deny rule and the secrets list still win

--mode, [ask] mode and IOHR_ASK_MODE set where it starts. Without a terminal there is nobody to ask, so only what a rule allows runs, and what it refused is said after the answer.

IO.md: notes for a folder

An IO.md (or io.md) holds what you want Io to know about a folder: what the project is, how to build and test it, rules to keep. ? and ?? read every IO.md from the folder you are in up to the project root (the nearest folder with inorbit.toml, .inorbit/ or atlas/, else the git root, and never past your home folder), and the nearest one wins. One more IO.md in iohr's config folder applies to every project.

Each file is cut at 4 KiB and all of them together at 8 KiB, nearest first, and secrets in them are scrubbed before they are sent. A file that is a symlink is skipped. The notes shape the answer but never widen what Io may read or run.

iohr context          # the IO.md files ? reads here
iohr context --full   # and the text that goes to the model

iohr project init writes a starter IO.md at the project root and never overwrites one you have; --no-io-md skips it.

Your site as sources

When a project was made with iohr project init --crawl and a site's address, ? and ?? also give Io the five passages of that site that best match the question, each with its page address, so an answer about the site can say where it came from. The crawl and its index stay on your machine. iohr atlas search searches the same index yourself. How the crawl works is in Reading your site.

Answers from your Roles

On macOS and Linux. A project's Roles are the agents in its atlas/roles/ folder, such as security and an engineer for its language. On a terminal, iohr on its own joins the project's session, starting it if none runs, and gives you your shell with a floating panel over it. iohr session joins it without the panel. iohr stop ends the session and closes the panel, and your shell stays open.

The session runs as a runner of its own, signed in as the profile session. Set it up once:

iohr login --profile session
iohr --profile session runner register --name my-mac-session

Without them the session stops at once and says which one is missing.

While the session runs, every ? and ?? asked in the project's folder also goes to each of its Roles. They answer at the same time as Io, and each answer is drawn as its own card under Io's as it arrives. --role security,go on the ? line asks only those Roles. A Role that fails says why in its card. Ctrl-C stops the wait without stopping the Roles; iohr stop ends them. With no session, or with --json, --menu, --dry-run, --allow-edits, --mode auto or a --role the session does not run, Io answers alone, as before.

A Role answers read-only, and in plan mode when you asked in plan mode. Each Role keeps two plain files in the project, sent nowhere:

  • a handoff note, .inorbit/handoff/<role>.md, with what it was last asked and what it said, replaced after each turn;
  • a memory folder, .inorbit/memory/<role>/, where you can add memories by hand. Every Role turn reads the note and the newest 8 memories.

To have one question answered in a Role without a session, name it:

iohr ask --role security "is this config safe to commit"

iohr looks for the Role in the project, then in your account, then in the built-in ones, so the built-in Roles work offline. A name it cannot find stops the run (exit 2). The Role brings its own text and model (--model and [ask] model still win) and never widens what Io may read or run. --job ID with --role gives the Role its brief for that job.

The chat box in the panel

Only in iohr-preview, zsh only. The panel gets a framed box at the bottom of the terminal for ? and ??:

  • ? at an empty prompt moves to the box, and one Enter sends the question. It still lands in your shell history.
  • While Io answers, a row shows what it is doing, such as "reading 3 files", with a moving bar and the time. Esc or a click on Stop stops the answer, and Ctrl-C still does.
  • Shift+Tab changes the mode, and Up brings back the last question.
  • Option+h (⌥h) folds the box to a corner chip and brings it back, in every terminal. On Linux it is Alt+h. Ctrl-G then c does the same.
  • [panel] chat in config.toml ("on", "hidden" or "off") or IOHR_PANEL_CHAT sets how it starts.
  • While the box shows, the panel takes the mouse for its buttons, so hold Option or Shift to select text.

What is sent

To your provider, and nothing else:

WhatLimit
Your question2 KiB
The folder's path1 KiB
The names at the top of the folder60 names and 2 KiB. Dotfiles are left out except .inorbit, .github, .gitignore and .claude, and so are names the folder's own .gitignore hides. Never file contents
The last command and its exit statusThe command at 1 KiB
In a project: the branch and last commitsThe branch, the last 5 commits and the change counts, at most 2 KiB
Output, only when attachedThe last 8 KiB or 200 lines, redacted
IO.md notes8 KiB, secrets scrubbed
Your site's passages, when crawledThe best five for the question
The whole message24 KiB

That message holds names, never file contents. While it answers, Io's read-only tools can open files in the folders it may read, and what they read goes to your provider as part of the answer. iohr sends nothing to InOrbit and keeps no record of your questions or answers; the only copies are a Role's handoff note in a session and, in a project, your answers to the questions the card asked you.

From a script

iohr ask "question" is the same thing without the hook: it streams the answer to the terminal. It works with Claude Code, or with Codex when you set [ask] agent; the card and the ? hook are Claude Code only.

iohr ask "what does this error mean" --output-file build.log

With --json you get the answer, the command it suggested, the questions it asked back and what of your context was sent, as data, never the text of your output or notes.