Ten findings from a review of the first commit. The ones that bite in normal use:
An unchecked mktemp left EPHEMERAL empty, which becomes `--user-data-dir=` — and Chrome reads that as
"use the default profile", i.e. the browser the user actually signs into. `set -u` does not catch it,
because the variable is set, just empty. Now checked and refused. That branch also never exec'd and
had no way to reach the browser with a signal; it now backgrounds, records the pid, and traps.
Signal handlers registered AFTER a build that takes minutes, so a pm2 restart during a first start
killed this process and left cargo compiling as an orphan — then started a second one on the same
target directory. Handlers now register first and shutdown kills the build.
`which('iris')` treated presence as identity. A truncated binary from an interrupted install is
present, reports ready, and never rebuilds. It now runs `--version` and checks — the same lesson
os-deps.ts already learned as `identify`.
Cookies were copied without Cookies-wal. These are WAL databases, so the newest session may exist
only in the log — copy the .db alone and the capture is signed out for exactly the account that just
signed in. PLUGIN.md had this backwards, citing WAL as the reason it was safe; corrected there too.
Also: --password-store=basic was missing from the branch that actually runs, working only because
chromiumoxide's DEFAULT_ARGS happens to supply it; seeding failures were silent, so the skill's
"sign in again" advice was offered for an unreadable profile it cannot fix; only --user-data-dir=X was
detected and not the space-separated form; installWrapper was unguarded at top level and crash-looped
on an unwritable ~/.local/bin; and it truncated the wrapper in place rather than renaming over it.
The searchPath copy is gone — the platform now exports locateBinary and this asks it. That copy is
what made the manifest probe refuse a rustup-only machine the sidecar could build on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Iris
Website screenshots for your agents. Install this and every agent you talk to can see rendered web pages — any site's, and your own Officer's — instead of inferring them from source code.
Built around iris, a Rust CLI that renders pages in a real Chrome-family browser (Brave, Chromium and Chrome all work) and captures them as images: full pages, single elements, phone and tablet viewports, light and dark.
What installing gets you
- The
irisCLI, compiled from source on first start and put on the standard path. iris-browser, a launcher that lets captures reuse the web sessions you are signed into.- An affordance and a skill, so agents know the tool exists and how to drive it — you never have to explain it to them.
There is no screen and no dock tile: the consumer is the agent's shell, not you.
Authenticated captures
Sessions are yours to grant, by signing in — never by handing credentials to an agent. The desktop
plugin's browser keeps a persistent profile at ~/.config/officer/browser-profile; sign in to a site
there once, and captures ride a read-only copy of those cookies from then on. Each account's sessions
live in that account's own home, so nobody captures with anyone else's logins.
Requirements
- Rust 1.88 or newer. The install brings in your distribution's
cargo; if that is older than 1.88 (Ubuntu's currently is), the sidecar refuses with the exact rustup one-liner to run — checkpm2 logs officer-iris. - A Chrome-family browser. Not installed by this plugin: the desktop plugin is the intended source, since its browser is also where you sign in. Any Brave/Chromium/Chrome already on the machine works for unauthenticated captures.
State of this plugin, plainly
- The build-and-supervise sidecar, the wrapper, the affordance and the skill are written but not yet verified on a live install — this plugin has not been through the install table on a real machine.
- The wrapper's session-seeding (copying cookies into the capture profile) is a design that needs live verification against how iris launches its browser; if iris supplies its own profile directory the wrapper seeds that instead of overriding it, but neither branch has run yet.
- The desktop plugin this integrates with is not published yet; until it is, the persistent profile is
whatever you put at
~/.config/officer/browser-profileyourself. - No screen, no API, no database — deliberate for now, not missing.