Fruitctlxoxd.ai

Agent adapters

Fruitctl has one portable skill at 0 and an adapter registry at 1. The skill uses the Agent Skills specification: YAML metadata and Markdown instructions with references loaded when needed. TOON inventories can supplement that contract. They do not replace a harness's native skill or MCP configuration format.

All seven adapters currently have documented configuration formats and offline installer tests. End-to-end image rendering, input and lease qualification is pending for each frontend. A successful configuration check means configured; it does not mean a desktop session or native binary has been qualified.

Install a pinned release

The immutable v0.1.0-alpha.1 runtime preview is pinned to source commit 7064d349890a9b18717b62a142452363629681ee. Use an operator-configured target profile. The preview provides the runtime, skill and adapters; it requires an existing Darwin native controller and normal macOS consent.

The Linux x64 public download and bootstrap passed anonymous HTTPS acceptance on Rocky Linux 10.2 using isolated home and project paths containing spaces. Codex user and Claude project installation, the bundled Node.js 24.21.0 launcher, all runtime file hashes, doctor and uninstall passed. Both uninstalls restored unrelated configuration exactly. This evidence covers packaging and configuration; each real frontend still needs image, input and lease acceptance.

fruitctl install --agent codex --scope user --version v0.1.0-alpha.1 --target <profile> --dry-run
fruitctl install --agent codex --scope user --version v0.1.0-alpha.1 --target <profile>
fruitctl doctor --agent codex --scope user
fruitctl doctor --json
fruitctl rollback --agent codex --scope user
fruitctl uninstall --agent codex --scope user

For a source checkout, run the same command with node bin/fruitctl.mjs; dry-run does not download a release or write configuration. --project-dir selects a project other than the current directory. --config supplies the Fruitctl profile configuration pathname; it is passed as FRUITCTL_CONFIG_PATH, without copying credentials or profile contents into an MCP configuration.

The rootless 0 bootstrap needs curl, tar, awk, mktemp, and sha256sum or shasum. It downloads an exact-tag runtime archive and SHA256SUMS over HTTPS, verifies the archive, rejects unsafe archive paths and links, and uses the bundled Node 24 runtime. Before editing an agent config, the installer verifies GitHub's manifest asset digest, release identity, platform and archive checksum again. Missing assets or a missing manifest digest fail explicitly. No agent or GUI is launched and no root access or package-manager install scripts are needed.

This block pins the published source and runtime preview and can be pasted as one terminal operation. Replace default with your configured profile:

(
  FRUITCTL_SOURCE_SHA='7064d349890a9b18717b62a142452363629681ee'
  FRUITCTL_RELEASE_TAG='v0.1.0-alpha.1'
  FRUITCTL_SCRIPT=$(mktemp)
  trap 'rm -f "$FRUITCTL_SCRIPT"' EXIT
  curl --disable --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
    "https://raw.githubusercontent.com/xoxd-ai/fruitctl/$FRUITCTL_SOURCE_SHA/scripts/install.sh" \
    -o "$FRUITCTL_SCRIPT" &&
  FRUITCTL_ACTUAL_SHA=$(if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$FRUITCTL_SCRIPT"
  else
    shasum -a 256 "$FRUITCTL_SCRIPT"
  fi) &&
  [ "${FRUITCTL_ACTUAL_SHA%% *}" = '6e05a7a62f57491cfbda1f8d9212291f6237f04f4ac396bc04d183b88747cd58' ] &&
  sh "$FRUITCTL_SCRIPT" --agent codex --scope user \
    --version "$FRUITCTL_RELEASE_TAG" --target default
)

The GitHub HTTPS origin authenticates the script and checksum inventory. SHA-256 detects differing release bytes; it is not a substitute for Apple signing, notarization, runtime acceptance or the release publisher's account security.

Configuration destinations

All generated entries launch the installed absolute bin/fruitctl path with mcp --target <profile>. Configuration uses local stdio; Linux reaches the Darwin broker through the separately configured SSH relay. The execution host must have that relay socket and the intended SSH configuration.

AdapterUser MCP fileProject MCP fileShapeSkill root used by installer
claude~/.claude.json.mcp.jsonmcpServers.fruitctl, command + args.claude/skills/fruitctl
codex~/.codex/config.toml.codex/config.toml[mcp_servers.fruitctl].agents/skills/fruitctl
pi~/.pi/agent/mcp.json.pi/mcp.jsonmcpServers.fruitctl, command + args.agents/skills/fruitctl
junie~/.junie/mcp/mcp.json.junie/mcp/mcp.jsonmcpServers.fruitctl, command + args.junie/skills/fruitctl
opencode~/.config/opencode/opencode.jsonopencode.json or existing .jsoncmcp.fruitctl, type:local, command array.agents/skills/fruitctl
vscode~/.copilot/mcp-config.json.mcp.jsonPortable mcpServers.fruitctl, type:stdio.agents/skills/fruitctl
kimi~/.kimi-code/mcp.json.kimi-code/mcp.jsonmcpServers.fruitctl, command + args.agents/skills/fruitctl

User config resolution honors CODEX_HOME, PI_CODING_AGENT_DIR, KIMI_CODE_HOME, and OpenCode's OPENCODE_CONFIG/XDG_CONFIG_HOME. Run installation in the same environment as the harness. Custom Claude account directories and enterprise-managed destinations need their owning configuration surface; review the generated fragment instead of assuming the default user path is active.

Sources: Claude MCP, Codex MCP, Codex environment, Pi MCP, Pi configuration, Junie MCP, OpenCode MCP, VS Code MCP, Kimi MCP.

Frontend boundaries

Pi: native MCP requires 0.99.0 or later. An extension that registers /mcp replaces native MCP behavior, so inspect the extension's actual registration before claiming native configuration will be read. Pi changelog, Pi MCP.

IntelliJ and Junie: Junie CLI, standalone Junie IDE plugin and integrated AI Assistant/ACP are separate frontends. The installer writes the documented CLI/standalone config and also returns an ideSettingsSnippet. Integrated AI Assistant users add that snippet through Settings → Tools → AI Assistant → MCP. The installer does not edit JetBrains internal XML or download/open an IDE. Current Junie documentation describes IDE skills, while older AI Assistant documentation lists a narrower support matrix; qualify the exact IDE build and agent frontend. Junie skills, standalone plugin, AI Assistant MCP.

VS Code: the adapter uses current portable MCP files. Existing .vscode/mcp.json uses servers, a different root. Merge through the documented legacy surface if that file already owns the Fruitctl entry. Remote SSH can move MCP execution to the remote host; configure the runtime and relay there. Codex through VS Code Agent Host is experimental and requires qualification separate from the official Codex extension. VS Code MCP, VS Code skills.

OpenCode: this adapter targets v1. The experimental v2 format nests servers under mcp.servers and uses different enablement fields; the installer does not silently emit that schema. OpenCode v2 MCP.

Kimi: native Kimi uses its own adapter. Kimi used as the provider inside Claude Code inherits Claude's adapter, while image/model capabilities still need their own acceptance run. Kimi in Claude.

Preservation and recovery

The installer changes only its fruitctl MCP entry and creates a symlink to the release's canonical skill. It preserves unrelated JSON/JSONC settings and comments, and unrelated TOML sections. Inline/dotted TOML server declarations that cannot be safely merged require a manual or declarative fragment. Junie enabled/disabled and OpenCode enabled remain user-controlled on updates.

Symlinked, store-managed or read-only config files yield declarative-required and a fragment without being overwritten. Use Home Manager to apply it. Existing unowned or changed launch entries are never adopted silently. No AGENTS.md, instruction override, .junie/AGENTS.md, agent binary or IDE setting is created or launched.

Private receipts and backups live under ~/.local/state/fruitctl/install with owner-only permissions. Release bundles live under ~/.local/share/fruitctl/releases/<tag>/<platform>-<arch>. The convenience launcher is ~/.local/bin/fruitctl; MCP configurations use the absolute versioned path. Rollback restores the previous recorded entry and skill after checking the prior bundle's integrity. A shared .mcp.json entry or skill cannot pin conflicting versions; such upgrades require the common configuration surface. The convenience launcher can advance independently while every MCP entry retains its absolute release path. Uninstall retains unrelated edits and shared installations; verified release caches remain so recovery is possible. Doctor checks receipts, owned config, links and every recorded runtime file hash. Uninstall and rollback restore their previous file state if a later filesystem operation fails. Doctor never launches an agent, contacts a target or verifies desktop pixels.

Workspace trust, model credentials, Screen Sharing and any macOS consent remain the owning client's and host's normal prerequisites. Capture a complete frame, inspect the actual returned image, perform an authorized reversible action, capture its result, release the lease, and test reconnect before recording an adapter as qualified. A source-pinned skill or passing configuration check alone is insufficient evidence.