iris: screenshots for agents — manifest, cargo-building sidecar, session wrapper, affordance and skill
Designed 2026-08-20 in conversation; PLUGIN.md is the decision record. Nothing here has run yet: no live install, no build, no capture. The wrapper's two launch branches and the cookie-seeding are written against documented behaviour, not observed behaviour. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
# iris-browser — the Chrome-family launcher iris is pointed at (`iris --chrome ~/.local/bin/iris-browser`).
|
||||
#
|
||||
# Two jobs, both invisible to iris:
|
||||
#
|
||||
# 1. Pick the browser. Brave first — it is Chromium underneath, so CDP and the profile format are the
|
||||
# same — then Chromium, then Chrome. Iris only knows it asked for "a chrome".
|
||||
#
|
||||
# 2. Carry the user's sessions into the capture, read-only. The persistent profile is the one the
|
||||
# desktop's browser signs into (~/.config/officer/browser-profile); captures ride COPIES of its
|
||||
# cookies in a throwaway profile, so a capture can never corrupt or lock the profile that holds the
|
||||
# sessions, and the desktop browser being open never collides with a capture.
|
||||
#
|
||||
# Per-user isolation is $HOME: whoever runs iris gets their own profile, their own sessions, and nothing
|
||||
# of anyone else's. That is the kernel's answer, not this script's.
|
||||
#
|
||||
# The launcher (chromiumoxide) may pass its own --user-data-dir. If it does, we seed the sessions INTO
|
||||
# that directory and change nothing else — overriding it could break how the launcher finds the DevTools
|
||||
# socket. If it does not, we provide an ephemeral directory ourselves and clean it up.
|
||||
|
||||
set -u
|
||||
|
||||
PROFILE="${OFFICER_BROWSER_PROFILE:-$HOME/.config/officer/browser-profile}"
|
||||
|
||||
BROWSER=""
|
||||
for candidate in brave-browser brave chromium chromium-browser google-chrome google-chrome-stable; do
|
||||
if BROWSER="$(command -v "$candidate" 2>/dev/null)" && [ -n "$BROWSER" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -z "$BROWSER" ]; then
|
||||
echo "iris-browser: no Chrome-family browser found (looked for brave, chromium, chrome)" >&2
|
||||
echo "iris-browser: install the desktop plugin, or any of the above" >&2
|
||||
exit 127
|
||||
fi
|
||||
|
||||
# Cookies plus the key that decrypts them. Login Data rides along so "remembered" form logins survive.
|
||||
# Everything else in a profile is cache and preference noise a capture does not need.
|
||||
seed_sessions() {
|
||||
dest="$1"
|
||||
[ -d "$PROFILE/Default" ] || return 0
|
||||
mkdir -p "$dest/Default"
|
||||
cp "$PROFILE/Local State" "$dest/Local State" 2>/dev/null || true
|
||||
cp "$PROFILE/Default/Cookies" "$dest/Default/Cookies" 2>/dev/null || true
|
||||
cp "$PROFILE/Default/Login Data" "$dest/Default/Login Data" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Did the launcher already choose a profile directory?
|
||||
CALLER_DIR=""
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--user-data-dir=*) CALLER_DIR="${arg#--user-data-dir=}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$CALLER_DIR" ]; then
|
||||
seed_sessions "$CALLER_DIR"
|
||||
exec "$BROWSER" "$@"
|
||||
fi
|
||||
|
||||
EPHEMERAL="$(mktemp -d "${TMPDIR:-/tmp}/iris-profile.XXXXXX")"
|
||||
trap 'rm -rf "$EPHEMERAL"' EXIT INT TERM
|
||||
seed_sessions "$EPHEMERAL"
|
||||
|
||||
# --password-store=basic keeps cookie encryption portable between the profile and the copy — without it a
|
||||
# keyring-backed browser writes cookies the copy cannot decrypt. Appended AFTER the launcher's args, and
|
||||
# so is our --user-data-dir, because for a repeated switch Chrome honours the last occurrence.
|
||||
"$BROWSER" "$@" --user-data-dir="$EPHEMERAL" --password-store=basic
|
||||
exit $?
|
||||
Reference in New Issue
Block a user