Operator surface

Host Affordance Bridge

Status: Partially implemented — a host-owned attach client is opt-in behind JACKIN_HOST_ATTACH=1 and ships clipboard image paste (with chunked large-image transfer), explicit image-path staging, GitHub PR/CI open actions, visible-URL open with modifier-hover disclosure, minimal chunked container file export, and diagnostics/launch-failure reveal-or-open; the remaining gate before promoting the opt-in path to default is live end-to-end validation in Ghostty/OrbStack, not more implementation surface

Preflight gate: Host Affordance Bridge Preflight records the Phase 0 measurements that made the opt-in implementation slice safe to start, and now tracks the promotion evidence required before JACKIN_HOST_ATTACH=1 can become default behavior.

Design record: Host Affordance Bridge — Design Rationale has the problem statement, architecture decision, protocol shape, security model, and alternatives considered behind this implementation.

Shipped facts

Operator-facing usage and validation instructions live in Host Affordances, covering JACKIN_HOST_ATTACH=1, image paste, explicit image-path staging, GitHub PR/CI opening, visible URL opening, file export, and the live validation checklist. The binary attach protocol lives in jackin-protocol, shared by the host runtime and Capsule; jackin-capsule attach-proxy relays raw attach bytes for backends (Docker Desktop, OrbStack) where the host cannot open the mounted Unix socket directly, and jackin-runtime picks direct socket vs proxy transport automatically. JACKIN_HOST_ATTACH=1 opts foreground attach paths (hardline, reconnect, new shell/agent sessions) into the host-owned attach loop; the default path stays the in-container docker exec -it client until live validation proves parity.

Clipboard image paste is implemented end to end: the attach protocol has a bounded ClipboardImage frame (MAX_CLIPBOARD_IMAGE_BYTES = 16 MiB - 1) plus chunked ClipboardImageStart/ClipboardImageChunk/ClipboardImageEnd frames (1 MiB chunks, 64 MiB transfer cap, SHA-256 verification) for larger payloads. Capsule validates image magic bytes, stages under /jackin/run/clipboard/ (0700/0600), pastes the container path into the focused pane using bracketed-paste semantics, and renders transient staged/rejected/not-pasted feedback. The host attach loop treats a lone Ctrl+V as an image trigger (macOS osascript PNG then TIFF then Finder file-url; Linux wl-paste/xclip when the relevant display env var is present), and the command palette adds explicit Paste image from host clipboard, Stage image without pasting, and Stage image from clipboard path actions. A default-on paste-path auto-stage (JACKIN_PASTE_IMAGE_PATHS, opt-out via 0/false/no/off) turns a pasted absolute image path or file:// URL into a staged container path automatically, which covers screenshot tools (for example CleanShot) that copy a file path instead of raw image bytes.

GitHub context lookup stores a best-effort CI target URL (gh pr checks link fields, then statusCheckRollup.detailsUrl, then the PR checks tab) alongside PR metadata, and the dialog exposes separate copy/open-PR/open-CI actions for keyboard and mouse. The attach protocol has a host-open server frame handled by the host attach client (open / xdg-open / rundll32), restricted to http, https, and mailto; Alt/Ctrl modifier-click and passive hover on a visible or OSC-8 URL reuse the same URL-token rules as double-click selection, and the command palette adds Open link under cursor. JACKIN_OPEN_LINKS=deny/off/no disables host browser-open actions; host-open URL telemetry redacts query strings and fragments.

Minimal container file export landed: command-palette Export file plus reveal/open variants, under-cursor and selected-text variants, and modified-click visible-file export. Capsule canonicalizes the requested path, rejects symlink escapes outside the workspace and /jackin/run/, rejects non-regular files, caps the first implementation at 64 MiB, and streams FileExportStart/FileExportChunk/FileExportEnd frames with SHA-256 verification; the host attach client writes to ~/Downloads/jackin/<instance>/ with collision-resistant names and only reveals/opens the exported copy on an explicit post-export action. Debug info diagnostics rows and the launch-failure popup both have explicit R/O reveal/open actions for host-owned JSONL and docker-output artifacts. Construct image installs xclip/xauth/wl-clipboard so Linux CLIs (Amp included) see expected clipboard helper binaries, though this does not by itself expose a real host display/clipboard bridge — see the devcontainer parity research note for that distinction.

Tests cover the shared protocol round-trips, transport selection (direct/proxy/fallback), Capsule image staging/validation/feedback placement, chunked-transfer cancellation and idle cleanup, host clipboard trigger/fallback behavior, GitHub context dialog actions, URL scheme rejection and modifier-hover dispatch, file-export frame round-trips and digest verification, and launch-failure artifact reveal state.

Remaining work

  1. Live-validate JACKIN_HOST_ATTACH=1 in Ghostty against a new isolated throwaway jackin instance using the Host Affordances checklist: text paste, mouse routing, resize, focus, pane switching, bracketed paste, OSC 52 copy, clean detach, and image paste into Codex/Amp/Claude-style prompts.
  2. Live-validate the macOS clipboard paths: raw screenshot and copied browser image through osascript PNG/TIFF, and a copied Finder image file through the file-url fallback.
  3. Live-validate Linux image readers (wl-paste on real Wayland, xclip on real X11) and the three explicit command-palette image actions (Paste image from host clipboard, Stage image without pasting, Stage image from clipboard path) with valid, invalid, and missing-tool clipboard content.
  4. Live-validate the default-on pasted-image-path auto-stage (JACKIN_PASTE_IMAGE_PATHS): a real absolute image path (including shell-escaped spaces) stages and inserts the container path, while prose, relative paths, non-image files, missing files, and mixed pastes stay ordinary text; confirm the opt-out and the Ghostty cmd+vCtrl+V remap for raw image-only clipboards.
  5. Live-validate GitHub context and visible-URL actions through JACKIN_HOST_ATTACH=1: PR open, failing-CI open, no-CI disabled state, modifier hover/click, Open link under cursor, non-URL fallback, and host-opener failure logging.
  6. Live-validate container file export through JACKIN_HOST_ATTACH=1 with a new isolated throwaway instance: all export variants, rejected directory/symlink-escape cases, missing cursor/selection tokens, conflict-safe host filenames, and explicit reveal/open.
  7. Live-validate launch-failure artifact reveal from a fresh throwaway failed launch: diagnostics JSONL reveal, docker-output reveal, hover-selected vs fallback R, and reveal-path logging.
  8. After live validation, decide whether to promote host attach from opt-in to default, and whether the landed URL/export actions need richer runtime-specific behavior.
  9. Live-profile chunked image-transfer latency for 16 MiB through 64 MiB payloads and decide whether very large transfers need a negotiated side stream.
  10. Live validation must use a new isolated throwaway jackin instance; do not inspect or mutate existing jk-* containers.

Out of scope

  • Persistent host daemon, Desktop Agent Hub integration, remote Docker/Kubernetes/SSH relay.
  • Directory/archive export, generic arbitrary file paste, drag/drop upload, non-http(s)/mailto scheme opening.
  • Runtime-specific image-prompt adapters for individual agent CLIs as a foundation (can layer on top once the generic bridge is validated).
  • Windows host support.

On this page