Skip to main content

Client Adapters

Adapters translate between AI agent wire formats and SigmaShake's internal ToolCall type. They also handle hook installation and capability classification.

Adapter interface

interface ClientAdapter {
readonly name: string;
detect(): boolean;
parseInput(raw: string): ToolCall;
formatOutput(result: EvalResult): string;
toolCapability(toolName: string): Capability;
install(projectDir: string): Promise<void>;
uninstall(projectDir: string): Promise<void>;
healthCheck(): Promise<boolean>;
}

Built-in adapters

Claude Code Adapter

Name: claude-code

Detection: Looks for CLAUDE_CODE_VERSION, CLAUDE_CODE_API_KEY, or CLAUDE_CODE_ENTRYPOINT environment variables.

Tool capability mapping: Hardcoded map for 30+ Claude Code tools:

  • Bashexecute
  • Readread
  • Write, Edit, MultiEditwrite
  • Glob, Grepsearch
  • Agentagent
  • WebFetch, WebSearchnetwork

Hook installation: Uses ssg hook eval as a PreToolUse hook. Includes circuit breaker protection (auto-allow after 5 consecutive denies to prevent lockout).

Generic Adapter

Name: generic

Detection: Always matches (fallback).

Wire format:

{"tool": "toolName", "input": {"key": "value"}}

Capability classification: Keyword-based prefix matching on tool name.

Codex Adapter

Name: codex

Detection: SSG_CLIENT=codex environment variable.

Tool capability mapping:

  • bashexecute
  • shellexecute
  • commandexecute

Integration: Hybrid MCP + shell-wrapper. ssg init --client=codex installs:

  • ~/.codex/config.toml — Registers the ssg-governance MCP server under [mcp_servers.ssg-governance]
  • .ssg/bin/bash — A project-local shell wrapper used for enforced bash -c interception

The MCP registration gives Codex direct access to the SSG tools. The wrapper is still required for command-governance enforcement, because Codex does not expose native pre-tool-use hooks.

Setup:

ssg init --client=codex
SHELL=.ssg/bin/bash codex

Restart Codex after ssg init so it reloads ~/.codex/config.toml.

Codex Desktop Adapter

Name: codex-desktop

Detection: SSG_CLIENT=codex-desktop environment variable. This is deliberately distinct from the codex CLI adapter — both share ~/.codex/config.toml but the desktop variant uses the native [[hooks]] enforcement path added in the April 2026 Codex Desktop update.

Tool capability mapping:

Codex Desktop toolCapability
bash, shell, local_shell, unified_exec, commandexecute
apply_patch, update_planwrite
view_image, screenshotread
web_search, in_app_browsernetwork
computer_use, click, type, keyexecute

Integration: Two layers in one install — MCP and project MCP:

  • ~/.codex/config.toml[mcp_servers.ssg-governance] block — Same MCP registration as the CLI adapter; gives the agent access to ssg_evaluate and the rest of the SSG MCP toolset, gating every Codex tool call before it runs. This is the supported enforcement surface in the Codex family.
  • .codex/mcp.json (project-local) — Travels with the repo so a freshly-cloned project picks up the MCP server without re-running ssg init.

Note: SSG does not write a [[hooks]] entry. Codex's config schema has no array-of-tables hooks section — codex-cli ≥ 0.134.0 refuses to load a config containing one (invalid type: sequence, expected struct HooksToml). Earlier ssg releases wrote such a block; both the Codex Desktop and Codex CLI adapters now strip any legacy [[hooks]] entry from ~/.codex/config.toml on every ssg init, so upgrading installs heal automatically.

The Codex Desktop and Codex CLI adapters can be installed side-by-side without conflict — they share ~/.codex/config.toml, the strippers are content-addressed (the ssg-governance entry is detected by name, not by marker comments), and both migrate away the legacy [[hooks]] block.

Setup:

ssg init --client=codex-desktop # registers [mcp_servers.ssg-governance] (+ migrates away any legacy [[hooks]] block)
# Restart Codex Desktop so it reloads ~/.codex/config.toml

Gemini CLI Adapter

Name: gemini

Detection: SSG_CLIENT=gemini environment variable.

Note: GEMINI_API_KEY is intentionally not used for detection — it is set by any application using the Gemini API and would cause false positives.

Tool capability mapping:

Gemini CLI toolCapability
run_shell_commandexecute
read_fileread
write_file, edit_filewrite
search_files, list_filessearch

Integration: Unlike the Pi adapter's shell-wrapper-only interception, the Gemini CLI adapter uses Gemini CLI's native TOML-based policy system. This provides full governance coverage across all 6 tool types — not just shell commands.

Policy installation: Creates .gemini/policies/ssg-governance.toml with baseline rules covering execution injection safety, file access restrictions, and telemetry control. Maps the 12 rules from the rules-gemini-cli hub ruleset into Gemini CLI's toolName/commandPrefix/commandRegex/decision/priority format.

Decision mapping:

SSG decisionGemini CLI policy
DENYdeny
ASKask_user
ALLOW / LOGallow
FORCEdeny

Priority mapping: SSG severity error=100, warning=50, info=10.

Setup:

ssg init --client=gemini # generates .gemini/policies/ssg-governance.toml
ssg hub pull rules-gemini-cli # add the full Gemini CLI security ruleset
gemini # start Gemini CLI — policies load automatically

Hub ruleset: The rules-gemini-cli hub ruleset provides 12 rules covering the critical vulnerabilities discovered after Gemini CLI's June 2025 launch: README prompt injection, eval injection bypass (GitHub #5495), GDPR non-compliant telemetry, and sandbox disable bypass.

Antigravity Adapter

Name: antigravity

Detection: ANTIGRAVITY_AGENT=1 environment variable.

Tool capability mapping:

  • run_command, send_command_input, bashexecute
  • view_fileread
  • write_to_file, replace_file_content, multi_replace_file_contentwrite
  • list_dir, grep_searchsearch
  • read_url_content, search_webnetwork
  • browser_subagentagent

Integration Limitations: Unlike Claude Code or the Gemini CLI, the Antigravity agent does not currently natively support pre-tool hook configurations (e.g., settings.json or .toml policy manifests) inside its engine. As a result, the SSG antigravity adapter uses the shell wrapper fallback method (similar to the Pi and Codex adapters).

Warning: Full file I/O operations (such as write_to_file and view_file) execute natively within the Antigravity engine and bypass the shell wrapper completely. Only CLI shell operations routed through run_command or shell invocation are successfully captured and governed by SSG. You should structure your governance rules to focus on shell invocation integrity (e.g., preventing malicious execution) until native hooks are built for the agent.

Setup:

ssg init --client=antigravity # creates the .ssg/bin/bash wrapper
export SHELL=$PWD/.ssg/bin/bash
# Antigravity is now governed for shell commands

NemoClaw Adapter

Name: nemoclaw

Detection: SSG_CLIENT=nemoclaw, or the NEMOCLAW_AGENT / NEMOCLAW_SANDBOX_NAME environment variables that the nemoclaw CLI sets when launching a sandbox.

Tool capability mapping:

NemoClaw verbCapability
process_exec, shell_exec, bash, shellexecute
fs_read, file_readread
fs_write, file_write, fs_editwrite
net_egress, network_request, inferencenetwork
sandbox_spawnagent

Integration: NemoClaw runs every agent inside a hardened OpenShell sandbox with Landlock + seccomp + network namespaces and its own declarative YAML policy engine. SSG governance is complementary to that kernel-level isolation, not a replacement — it lives in the host-side ~/.nemoclaw/policies/ directory and is merged into every sandbox's baseline at launch time.

ssg init --client=nemoclaw installs:

  • ~/.nemoclaw/policies/ssg-governance.yaml — A declarative policy fragment (schema: nemoclaw.policy/v1) covering filesystem.writable / readonly / deny, network.default = deny with an allowlist of common AI inference + package endpoints, and process.deny_privileged plus a deny list for mount, umount2, ptrace, init_module, etc.
  • <ssg-hooks>/bin/bash — Host-side shell wrapper for defence-in-depth on the nemoclaw onboard / share mount paths that run outside the sandbox boundary.

Setup:

ssg init --client=nemoclaw # writes ~/.nemoclaw/policies/ssg-governance.yaml
nemoclaw <sandbox-name> policy-add \
--file=~/.nemoclaw/policies/ssg-governance.yaml # apply to an existing sandbox
ssg hub pull rules-nemoclaw # pull the full NemoClaw ruleset (optional)

Note: NemoClaw is in early preview (March 2026); the policy schema may evolve. The schema: nemoclaw.policy/v1 field pins the fragment to the v1 shape — re-run ssg init --client=nemoclaw after upgrading nemoclaw to regenerate against the current schema.

Claude Cowork Adapter

Name: claude-cowork

Detection: SSG_CLIENT=claude-cowork, or the CLAUDE_COWORK_VERSION environment variable (parallel to CLAUDE_CODE_VERSION for the terminal-native sibling). Detection is deliberately not triggered by the Claude Desktop app's mere presence — that app hosts both Cowork agent sessions and non-agent chat, and we don't want a chat session to fall under agent governance.

Tool capability mapping:

Cowork toolCapability
bashexecute
read, screenshot, file_readread
write, edit, multiedit, file_writewrite
glob, grepsearch
webfetch, websearchnetwork
computer_use, click, double_click, right_click, type, key, scroll, mouse_move, dragexecute

Cowork is distinct from Claude Code in that it adds a full computer-use surface — screen capture, mouse, keyboard — on top of the standard file + shell vocabulary. The capability map covers both surfaces plus the Open Cowork variant's file_read / file_write aliases.

Integration: Anthropic has not yet shipped a public PreToolUse hook API for Cowork (unlike Claude Code). The adapter therefore uses an MCP + governance-prompt approach:

  • CLAUDE_COWORK.md (project-local) — A markdown governance prompt wrapped in <!-- SSG_GOVERNANCE_START --> / <!-- SSG_GOVERNANCE_END --> markers. Tells the model to call ssg_evaluate (via the MCP server below) before any tool call, including computer-use actions. Idempotently appended to any existing file.
  • ~/.claude/mcp.json — Registers the ssg-governance MCP server under the user-scoped Claude Desktop config. Other MCP servers in the file are preserved.

Setup:

ssg init --client=claude-cowork # creates CLAUDE_COWORK.md + ~/.claude/mcp.json entry
# Restart Claude Desktop so Cowork loads the ssg-governance MCP server

Note: as Cowork's hook surface matures, the install path will gain a native PreToolUse hook entry (the same shape as the Claude Code adapter). The MCP layer keeps working either way.

Cursor Adapter

Name: cursor

Detection: Checks for CURSOR_SESSION_ID environment variable or the ~/.cursor/ directory.

Tool capability mapping:

Cursor toolCapability
run_terminal_commandexecute
edit_file, create_filewrite
read_fileread
codebase_search, grep_search, file_search, list_dirsearch
web_search, fetchnetwork

Integration: MCP-based, identical to the Copilot adapter architecture. ssg init --client=cursor writes two files:

  • .cursor/mcp.json — Registers the ssg-governance MCP server. Merges with any existing servers in that file.
  • .cursor/rules/ssg-governance.mdc — A Cursor rule file with alwaysApply: true that instructs the agent to call ssg_evaluate before every tool use.

Setup:

ssg init --client=cursor # creates .cursor/mcp.json + .cursor/rules/ssg-governance.mdc
# Restart Cursor to load the MCP server

Token cost: By default the MCP server exposes only the 4 core governance tools (~428 tokens). Use SSG_MCP_TOOLS in your .cursor/mcp.json env block to opt-in to more:

{
"mcpServers": {
"ssg-governance": {
"command": "ssg",
"args": ["mcp-server"],
"env": {
"SSG_CLIENT": "cursor",
"SSG_MCP_TOOLS": "onboarding"
}
}
}
}

See MCP Server → Token Budget for the full breakdown.

Aider Adapter

Name: aider

Detection: SSG_CLIENT=aider environment variable.

Tool capability mapping:

Aider toolCapability
bash, shell, runexecute
edit, write, createwrite
readread
grep, findsearch

Integration: Shell-wrapper + Python sitecustomize hook. ssg init --client=aider installs:

  • ~/.sigmashake/hooks/bin/bash — Shell wrapper that intercepts every bash -c command aider runs.
  • ~/.sigmashake/hooks/hooks/ssg-node-hook.cjs — Node runtime hook.
  • ~/.sigmashake/hooks/hooks/python/sitecustomize.py — Python runtime hook.
  • .aider.conf.yml — Written to the project root when absent. Sets lint-cmd: ["ssg check ."] and auto-lint: true so aider's own edit loop surfaces governance violations inline in the chat output.

The .aider.conf.yml file is only written when it does not already exist; ssg leaves a user-authored file unchanged.

Setup:

ssg init --client=aider
SSG_CLIENT=aider \
NODE_OPTIONS="--require ~/.sigmashake/hooks/hooks/ssg-node-hook.cjs" \
PYTHONPATH="~/.sigmashake/hooks/hooks/python:${PYTHONPATH}" \
SHELL=~/.sigmashake/hooks/bin/bash \
aider

Copilot Adapter

Name: copilot

Detection: GITHUB_COPILOT_TOKEN environment variable, or presence of ~/.vscode/ on the local machine.

Tool capability mapping: Keyword-based matching on VS Code tool names — tools containing terminal, command, or run map to execute; edit, insert, or replace to write; read, open, or get to read; search, find, or list to search. Falls back to the shared keyword classifier.

Integration: Three layers installed by ssg init --client=copilot:

  • .vscode/mcp.json — Registers the ssg-governance MCP server (type: "stdio") under VS Code's project-local MCP config. Used by Copilot Chat in the editor. Merges with any existing servers in the file.
  • .github/copilot-instructions.md — Appends a governance block (wrapped in SSG_GOVERNANCE_START / SSG_GOVERNANCE_END markers) that instructs the agent to call ssg_evaluate before every tool call and explains how to handle each decision verdict. Idempotent; only appended if the file does not already contain SSG Governance.
  • ~/.copilot/hooks/ssg-governance.json — Writes a user-scoped Copilot CLI hooks file that wires both preToolUse and postToolUse lifecycle hooks to ssg hook copilot. This is the enforced pre-exec gate for Copilot CLI (GA Feb 2026). Copilot Chat in the editor does not read this file — it uses the MCP path above. Note: Copilot CLI has no failClosed flag for hook errors; hook failures fail-open by design, so this is a best-effort gate. Older Copilot CLI builds that predate the hooks system ignore the file.

Setup:

ssg init --client=copilot
# Restart VS Code to load the ssg-governance MCP server (Copilot Chat)
# Restart your shell session to pick up the Copilot CLI hooks

Pi Adapter

Name: pi

Detection: SSG_CLIENT=pi environment variable.

Tool capability mapping:

Pi toolCapability
bashexecute
readread
write, editwrite
grep, find, lssearch

Integration: Shell-wrapper + Node hook + Python sitecustomize hook + optional MCP. ssg init --client=pi installs the same hook trio as the Aider adapter, and also:

  • ~/.pi/mcp.json — Registers the ssg-governance MCP server. If aider is on $PATH, a second ssg-coder MCP entry is registered to expose aider as a tool inside Pi (this fixes Pi's "little coder extension" mode when Pi's native read/write/bash tools are toggled off).

Setup:

ssg init --client=pi
NODE_OPTIONS="--require ~/.sigmashake/hooks/hooks/ssg-node-hook.cjs" \
PYTHONPATH="~/.sigmashake/hooks/hooks/python:${PYTHONPATH}" \
SHELL=~/.sigmashake/hooks/bin/bash \
pi
# Restart Pi to load the ssg-governance MCP server

OpenCode Adapter

Name: opencode

Detection: SSG_CLIENT=opencode environment variable, or presence of ~/.config/opencode or ~/.local/share/opencode (created by OpenCode on first run).

Tool capability mapping:

OpenCode toolCapability
bash, shell, runexecute
edit, write, apply_patch, createwrite
readread
grep, glob, listsearch
webfetch, websearch, fetchnetwork
taskagent

Integration: Three layers installed by ssg init --client=opencode:

  • opencode.json — MCP + permission blocks — Merges an mcp.ssg-governance entry (type: "local") and a permission block that transpiles deny/ask rules from your .rules files into OpenCode's native per-tool allow/ask/deny policy. OpenCode uses last-match-wins ordering, so the catch-all "*" entry is placed first and specific overrides follow. Existing unrelated keys are preserved.
  • .opencode/plugins/ssg-governance.js — An in-process OpenCode plugin. Its tool.execute.before hook shells ssg hook opencode, passing a JSON envelope on stdin, and throws to block the call on a deny or force verdict. This is the live full-.rules enforcement layer. Tested on OpenCode 1.15.0+. Note: per sst/opencode#5894, tool.execute.before does not fire for tool calls inside task-spawned subagents — govern those via the MCP path.
  • AGENTS.md — governance block — OpenCode auto-loads AGENTS.md at the project root. ssg appends a governance block (wrapped in SSG_GOVERNANCE_START / SSG_GOVERNANCE_END markers) explaining the MCP server and the ssg_evaluate protocol. Idempotent; a pre-existing file is left intact except for the block.

Plugin install methods:

There are three equivalent ways to get the plugin file:

  1. ssg init --client=opencode (recommended) — writes all three layers (opencode.json, .opencode/plugins/ssg-governance.js, and the AGENTS.md block) in one command.
  2. ssg plugins emit opencode — emits just the plugin file from your local binary, useful when you want to update the plugin without re-running full init:
    ssg plugins emit opencode > .opencode/plugins/ssg-governance.js
  3. CDN download — for machines where ssg is not yet on PATH, download the plugin directly and drop it into .opencode/plugins/:
    curl -fsSL https://download.sigmashake.com/plugins/opencode/latest/ssg-governance.js \
    -o .opencode/plugins/ssg-governance.js
    Versioned builds are also available at /plugins/opencode/<version>/ssg-governance.js; a latest.json pointer in the same CDN path identifies the current version. The plugin itself shells ssg hook opencode at runtime, so a local ssg binary on PATH is still required for the plugin to function — the CDN download only gets you the plugin file, not the governance engine.

Subscription required: The CDN download and the CLI binary are free to obtain. Governance enforcement (ssg hook opencode) fails closed without a valid SigmaShake subscription — the local ssg daemon will reject tool calls unless a license is active.

Setup:

ssg init --client=opencode
# Restart OpenCode to load the ssg-governance MCP server and plugin

See the OpenCode Integration guide for a full walkthrough, example rules, and troubleshooting.


Replit Adapter

Name: replit

Detection: SSG_CLIENT=replit environment variable, or Replit's own REPL_ID / REPLIT_DB_URL environment variables (set automatically inside any Replit container).

Tool capability mapping:

Replit toolCapability
bash, shell, run, executeexecute
read_fileread
write_file, edit_file, str_replace_editor, create_filewrite
search_filesystem, list_filessearch
web_search, web_fetch, fetchnetwork

Integration: The Replit adapter does not install a local shell wrapper because Replit agents run inside a remote container. Instead:

  • replit.md — Project-root customization file that Replit Agent auto-loads (like CLAUDE.md). ssg appends (or replaces) a <!-- SSG_GOVERNANCE_START --> / <!-- SSG_GOVERNANCE_END --> block instructing the agent to call ssg_evaluate before every action.
  • Remote MCP link — ssg generates a click-to-install URL pointing at https://mcp.sigmashake.com and writes it to .sigmashake/replit-install.url and .sigmashake/replit-install.md. Clicking the URL connects the hosted ssg MCP server to your Replit account.

Setup:

ssg init --client=replit
# ssg prints the Replit MCP install URL — click it to connect the MCP server
# Replit Agent will auto-load replit.md on the next prompt

Adapter selection

Priority order:

  1. SSG_CLIENT environment variable (explicit override)
  2. Known client environment variables (e.g., CLAUDE_CODE_VERSION)
  3. Generic adapter (fallback)

Creating custom adapters

Implement the ClientAdapter interface and register it in the adapter registry. Key considerations:

  • detect() should be fast — it runs on every eval
  • parseInput() must handle malformed input gracefully
  • toolCapability() should cover all tools the client uses
  • install() should be idempotent (safe to run multiple times)

Simulation testing

ssg certify validates governance rules by replaying synthetic scenarios through the full adapter path. Scenarios use Claude Code wire format (tool_name/tool_input) — the same format the PreToolUse hook sends — and assert the expected decision for each tool call.

The certify engine applies the same transformation as ssg hook eval:

{tool_name, tool_input} → {tool, input} → evaluate()

This means certification tests:

  • The jq wire format transformation
  • The ClaudeCodeAdapter.TOOL_MAP capability mapping
  • The evaluation engine's decision logic against real rules

Run certification before publishing a ruleset:

ssg certify --dir=.sigmashake/scenarios

See Certification for the full scenario format and report submission.