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:
Bash→executeRead→readWrite,Edit,MultiEdit→writeGlob,Grep→searchAgent→agentWebFetch,WebSearch→network
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:
bash→executeshell→executecommand→execute
Integration: Hybrid MCP + shell-wrapper. ssg init --client=codex installs:
~/.codex/config.toml— Registers thessg-governanceMCP server under[mcp_servers.ssg-governance].ssg/bin/bash— A project-local shell wrapper used for enforcedbash -cinterception
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 tool | Capability |
|---|---|
bash, shell, local_shell, unified_exec, command | execute |
apply_patch, update_plan | write |
view_image, screenshot | read |
web_search, in_app_browser | network |
computer_use, click, type, key | execute |
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 tossg_evaluateand 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-runningssg init.
Note: SSG does not write a
[[hooks]]entry. Codex's config schema has no array-of-tableshookssection — 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.tomlon everyssg 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_KEYis 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 tool | Capability |
|---|---|
run_shell_command | execute |
read_file | read |
write_file, edit_file | write |
search_files, list_files | search |
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 decision | Gemini CLI policy |
|---|---|
DENY | deny |
ASK | ask_user |
ALLOW / LOG | allow |
FORCE | deny |
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,bash→executeview_file→readwrite_to_file,replace_file_content,multi_replace_file_content→writelist_dir,grep_search→searchread_url_content,search_web→networkbrowser_subagent→agent
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_fileandview_file) execute natively within the Antigravity engine and bypass the shell wrapper completely. Only CLI shell operations routed throughrun_commandor 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 verb | Capability |
|---|---|
process_exec, shell_exec, bash, shell | execute |
fs_read, file_read | read |
fs_write, file_write, fs_edit | write |
net_egress, network_request, inference | network |
sandbox_spawn | agent |
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) coveringfilesystem.writable / readonly / deny,network.default = denywith an allowlist of common AI inference + package endpoints, andprocess.deny_privilegedplus a deny list formount,umount2,ptrace,init_module, etc.<ssg-hooks>/bin/bash— Host-side shell wrapper for defence-in-depth on thenemoclaw onboard/share mountpaths 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/v1field pins the fragment to the v1 shape — re-runssg init --client=nemoclawafter upgradingnemoclawto 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 tool | Capability |
|---|---|
bash | execute |
read, screenshot, file_read | read |
write, edit, multiedit, file_write | write |
glob, grep | search |
webfetch, websearch | network |
computer_use, click, double_click, right_click, type, key, scroll, mouse_move, drag | execute |
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 callssg_evaluate(via the MCP server below) before any tool call, including computer-use actions. Idempotently appended to any existing file.~/.claude/mcp.json— Registers thessg-governanceMCP 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 tool | Capability |
|---|---|
run_terminal_command | execute |
edit_file, create_file | write |
read_file | read |
codebase_search, grep_search, file_search, list_dir | search |
web_search, fetch | network |
Integration: MCP-based, identical to the Copilot adapter architecture. ssg init --client=cursor writes two files:
.cursor/mcp.json— Registers thessg-governanceMCP server. Merges with any existing servers in that file..cursor/rules/ssg-governance.mdc— A Cursor rule file withalwaysApply: truethat instructs the agent to callssg_evaluatebefore 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 tool | Capability |
|---|---|
bash, shell, run | execute |
edit, write, create | write |
read | read |
grep, find | search |
Integration: Shell-wrapper + Python sitecustomize hook. ssg init --client=aider installs:
~/.sigmashake/hooks/bin/bash— Shell wrapper that intercepts everybash -ccommand 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. Setslint-cmd: ["ssg check ."]andauto-lint: trueso 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 thessg-governanceMCP 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 inSSG_GOVERNANCE_START/SSG_GOVERNANCE_ENDmarkers) that instructs the agent to callssg_evaluatebefore every tool call and explains how to handle each decision verdict. Idempotent; only appended if the file does not already containSSG Governance.~/.copilot/hooks/ssg-governance.json— Writes a user-scoped Copilot CLI hooks file that wires bothpreToolUseandpostToolUselifecycle hooks tossg 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 nofailClosedflag 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 tool | Capability |
|---|---|
bash | execute |
read | read |
write, edit | write |
grep, find, ls | search |
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 thessg-governanceMCP server. Ifaideris on$PATH, a secondssg-coderMCP 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 tool | Capability |
|---|---|
bash, shell, run | execute |
edit, write, apply_patch, create | write |
read | read |
grep, glob, list | search |
webfetch, websearch, fetch | network |
task | agent |
Integration: Three layers installed by ssg init --client=opencode:
opencode.json— MCP + permission blocks — Merges anmcp.ssg-governanceentry (type: "local") and apermissionblock that transpiles deny/ask rules from your.rulesfiles 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. Itstool.execute.beforehook shellsssg 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-.rulesenforcement layer. Tested on OpenCode 1.15.0+. Note: per sst/opencode#5894,tool.execute.beforedoes not fire for tool calls inside task-spawned subagents — govern those via the MCP path.AGENTS.md— governance block — OpenCode auto-loadsAGENTS.mdat the project root. ssg appends a governance block (wrapped inSSG_GOVERNANCE_START/SSG_GOVERNANCE_ENDmarkers) explaining the MCP server and thessg_evaluateprotocol. 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:
ssg init --client=opencode(recommended) — writes all three layers (opencode.json,.opencode/plugins/ssg-governance.js, and theAGENTS.mdblock) in one command.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- CDN download — for machines where
ssgis not yet onPATH, download the plugin directly and drop it into.opencode/plugins/:Versioned builds are also available atcurl -fsSL https://download.sigmashake.com/plugins/opencode/latest/ssg-governance.js \-o .opencode/plugins/ssg-governance.js/plugins/opencode/<version>/ssg-governance.js; alatest.jsonpointer in the same CDN path identifies the current version. The plugin itself shellsssg hook opencodeat runtime, so a localssgbinary onPATHis 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 localssgdaemon 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 tool | Capability |
|---|---|
bash, shell, run, execute | execute |
read_file | read |
write_file, edit_file, str_replace_editor, create_file | write |
search_filesystem, list_files | search |
web_search, web_fetch, fetch | network |
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 callssg_evaluatebefore every action.- Remote MCP link — ssg generates a click-to-install URL pointing at
https://mcp.sigmashake.comand writes it to.sigmashake/replit-install.urland.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:
SSG_CLIENTenvironment variable (explicit override)- Known client environment variables (e.g.,
CLAUDE_CODE_VERSION) - 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 evalparseInput()must handle malformed input gracefullytoolCapability()should cover all tools the client usesinstall()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_MAPcapability 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.