Skip to content
Download

Agents ​

insensical learns a coding agent's state in two ways.

  • With no setup, from what agents already write to their terminal: progress, notifications and the bell, as described in States and attention.
  • Exactly, from the agent's own hooks, which call isc status. insensical can add those hooks for Claude Code, Codex, Gemini CLI, opencode and pi.

Only the Claude Code integration has been used. The other four are written from each agent's documentation and source code as of October 2026, and tested with the events those describe. They haven't been tried against the agents themselves.

Setting up from the window ​

When the window opens and there's an agent on the system that doesn't report yet, the top bar says so. For example: "Codex does not show its state yet · Set up".

  • Press it to list those agents, with the file each change goes in.
  • Press Enter to add them. Nothing is ever added without that Enter.
  • Press Escape to leave it for later. The notice stays.
  • Press N, or click the cross on the notice, to say never. Those agents aren't offered again.
  • After adding, a line tells you what's still yours to do. For Codex, that's trusting the hooks with /hooks.
  • "Have the agents on this system say what they are doing" in the palette asks at any time, and includes the agents you declined.

The agents you declined are kept in ~/.local/state/insensical/agents-declined, one per line. Delete a line to be offered that agent again.

Setting up from the command line ​

CommandDoes
isc integrateFinds the agents on this system and offers each one. It says which were found and which weren't, then for each one found it shows what would change and asks.
isc integrate claudeThe same for one agent: claude, codex, gemini, opencode or pi.
isc integrate --yesAdds every agent that was found, without asking.
isc integrate --removeRemoves them all. If you name an agent, removes that one.
isc integrate --statusPrints what was found and what already reports, as JSON. Changes nothing.
  • An agent counts as found when its program is on PATH or its settings directory exists.
  • An agent that's already integrated says "nothing to change".
  • Nothing is added without asking, and nothing is added for an agent that isn't on the system.
  • When there's no terminal to ask on, isc integrate changes nothing unless you pass --yes, and exits with status 1.
  • You can't combine --status with --remove or --yes. For each agent it prints agent (the name used on the command line), title, found, integrated, file (where its hooks go) and then (what's left for you to do afterwards, or null).

The hooks name the isc binary by the full path it had when you ran integrate. If you move isc or reinstall it somewhere else, the hooks point at nothing. The agent's state stops being reported, --status says it isn't integrated, and the window offers to set it up again. Run isc integrate for that agent to rewrite the hooks so they name the isc you ran.

Claude Code ​

isc integrate claude adds hooks to Claude Code's settings: ~/.claude/settings.json, or under $CLAUDE_CONFIG_DIR.

  • Hooks that are already there are kept, and stay first.
  • A copy of your original settings is saved next to them, as settings.json.before-insensical. It's written once.
  • --remove takes the hooks out and leaves what was there before.
  • The hook prints nothing, never fails, runs separately from Claude's own work, and does nothing outside a pane.
Claude Code eventState
A prompt is submitted; a tool has runrunning
Permission is asked for; it asks a questionwaiting, with what it's asking
It has finished respondingdone, with the first line of what it said. It stays done no matter how long it then sits at its prompt.
It stopped on an errorfailed
A session starts or endsidle

Each event also names Claude's session. That's how the pane can offer claude --resume … after the daemon has stopped (Stopping, restarting and new versions).

Codex ​

isc integrate codex adds hooks to ~/.codex/hooks.json, or under $CODEX_HOME. A copy of the original file is saved next to it, as hooks.json.before-insensical. It's written once.

  • Codex does not run a hook until you have trusted it. After integrating, open Codex, run /hooks, and trust the new ones. Until you do, nothing is reported.
  • If isc moves and you add the hooks again, you have to trust them again.
  • A prompt or a finished tool gives running. A request for approval gives waiting. The end of a turn gives done, with the first line of what it said. An interrupted turn gives idle.
  • A turn that fails isn't reported, because Codex has no event for it.
  • The pane offers codex resume <session> after the daemon has stopped.

Gemini CLI ​

isc integrate gemini adds hooks to ~/.gemini/settings.json, or to $GEMINI_CLI_HOME/.gemini/settings.json. A copy of your original settings is saved next to them, as settings.json.before-insensical. It's written once.

  • A prompt or a finished tool gives running. Asking to use a tool gives waiting, with its question. The end of a turn gives done, with the first line of its answer.
  • A failed or cancelled turn isn't reported. Gemini CLI has no event for either, so the pane stays running until the next prompt.
  • No resume command is offered.
  • Gemini waits for its hooks. The hook answers at once. If the daemon is stuck, Gemini is held up for three seconds at most.

opencode ​

isc integrate opencode writes one file, ~/.config/opencode/plugins/insensical.js (under $XDG_CONFIG_HOME if that's set). opencode loads it when it starts. --remove deletes it.

  • Working gives running. Asking for permission or asking a question gives waiting. Going quiet after working gives done. An error gives failed, with its message. A turn you stopped gives idle.
  • Sessions that opencode starts itself (subagents) aren't reported.
  • The pane offers opencode --session <id> after the daemon has stopped.

pi ​

isc integrate pi writes one file, ~/.pi/agent/extensions/insensical.ts, or under $PI_CODING_AGENT_DIR. pi loads it when it starts. --remove deletes it.

  • Working gives running. A dialog that an extension puts up gives waiting, with its title (pi itself never asks before using a tool). Finishing gives done, with what it said last. Ending in an error gives failed. Stopping it yourself gives idle.
  • pi reports only when it's running with a screen. Its other modes don't report.
  • The pane offers pi --session <id> after the daemon has stopped.

Any other agent or script ​

Any agent or script can call isc status and isc notify from its own hooks.

sh
isc status running
isc status waiting -m "Allow \`cargo publish\`?"
isc status done
isc status running --resume "mytool --continue 42"
isc notify "Build" "Finished"
  • --resume says how to pick the work up again. The pane offers that command at its prompt after the daemon has stopped.
  • isc status and isc notify speak for a pane, and never guess which one. Inside a pane they need nothing more. Outside one they need --pane.
  • These two commands, and the agents' hooks, work even when isc and the daemon are different versions.