schemaVersion: "2" kind: mixin name: ori displayName: Ori — ACP web client for Claude Code description: > Starts the ori web server inside the sandbox. Ori is a browser client for ACP (Agent Client Protocol) code agents: a Go backend serves a React SPA (Zed-style agent panel: streamed answers, thoughts, tool calls, plans, permission prompts) plus a workspace panel (file tree with Material icons, Monaco preview/editor with rendered Markdown and AsciiDoc, interactive terminal). This kit only launches and describes the server; the binaries ship in the k33g/ori template image (template/Dockerfile in the ori repository), so use it together with `--template k33g/ori:0.0.1`. licenses: - MIT # This mixin only makes sense composed with the claude agent kit: the server # it starts drives Claude Code through the claude-code-acp adapter, and the # Anthropic credentials/egress come from that kit. requires: agent: claude args: port: default: "8888" description: TCP port the ori server listens on inside the sandbox pattern: "^[0-9]{2,5}$" # No extra network permissions: the Anthropic endpoints come from the claude # agent kit this mixin composes with, and the ACP adapter is baked into the # template image, so nothing is downloaded at runtime. # Auto-publishes an ephemeral localhost port at create (the create output # prints it: "Published web: localhost: -> /tcp"). Pin a fixed # host port instead with `-p 8888:8888` at create or `sbx ports … --publish`. # The unquoted arg reference decodes as the integer the schema expects. ports: - container: ${{ kit.args.port }} protocol: tcp name: web setup: startup: # Startup commands run on every container start through the detached # dispatcher, so the pgrep guard makes this idempotent. The server binds # 0.0.0.0 (empty host in --addr) so published ports reach it from the # host's browser. `user` is omitted: startup commands default to uid 1000, # the agent user. # # The PATH export is load-bearing: the dispatcher runs this via # `su -s /bin/sh -c … agent`, and su resets PATH to the login.defs # default — which does not contain the npm prefix where claude-code-acp # lives, nor ~/.local/bin where claude does. - command: - "sh" - "-c" - | export PATH="/usr/local/share/npm-global/bin:/home/agent/.local/bin:$PATH" pgrep -x ori >/dev/null 2>&1 && exit 0 nohup /usr/local/bin/ori \ --addr ":${{ kit.args.port }}" \ --agent-cmd claude-code-acp \ --cwd "${WORKSPACE_DIR:-/home/agent/workspace}" \ >> /home/agent/.ori.log 2>&1 & description: Start the ori web server (idempotent) agentInstructions: content: | ## Ori web server (kit `ori`) This sandbox runs **ori**, a web client for Claude Code over ACP. It was started automatically and serves on **port ${{ kit.args.port }}** (all interfaces). - Binaries: `/usr/local/bin/ori` (server) and `/usr/local/bin/ori-mock-agent` (a deterministic demo ACP agent that needs no credentials). - Log file: `/home/agent/.ori.log`. - The server drives its own Claude Code session through the `claude-code-acp` adapter (preinstalled); credentials are injected by the sandbox proxy, so no login is needed inside the container. - Restart it with: `pkill -x ori; nohup ori --addr ":${{ kit.args.port }}" --agent-cmd claude-code-acp --cwd "$PWD" >> /home/agent/.ori.log 2>&1 &` - To demo without consuming Claude usage, restart it with `--agent-cmd ori-mock-agent` instead. A localhost port for the UI was published on the host at create time (see the create output); the human can pin a different one with `sbx ports --publish :${{ kit.args.port }}/tcp`.