Skip to content

Harness Adapters

A harness is the coding environment Tuff emits into, such as .agents/ or .claude/. A harness adapter is Tuff’s agent-specific implementation layer for that environment.

The adapter decides where files are emitted, how native settings are updated, and where tool registration lives.

Tuff currently ships four adapters:

AdapterTarget idMain output root
Open Agentsopen-agents.agents/
Claudeclaude.claude/
Codexcodex.agents/
Cursorcursor.cursor/

open-agents remains the generic shared .agents/ adapter. Codex now has a dedicated adapter even though it currently emits the same directory family, because its hook coverage and native behavior are tracked independently.

Legacy aliases are also accepted:

  • claude-code resolves to claude

The same capability can be emitted differently depending on the agent.

AgentEmitted path
open-agents.agents/skills/<id>/...
claude.claude/skills/<id>/...
AgentEmitted pathMCP registration
open-agents.agents/tools/<id>/....agents/mcp.json
claude.claude/tools/<id>/....mcp.json
codex.agents/tools/<id>/....agents/mcp.json
cursor.cursor/tools/<id>/....cursor/mcp.json

Tuff writes the tool files and also registers the tool in the agent’s MCP config so the harness can discover it.

Hooks are where the adapter differences are most visible:

AgentEmitted pathFormat
open-agents.agents/hooks/<id>/run.sh plus .agents/hook.jsonNative JSON (development format)
claude.claude/hooks/<id>/... plus .claude/settings.jsonNative Claude JSON
codex.agents/hooks/<id>/run.sh plus .agents/hook.jsonCodex hook JSON
cursor.cursor/hooks/<id>/run.sh plus .cursor/hooks.jsonCursor Hooks JSON

For Claude, tuff add hook ... --hook-file settings.json reads a hooks-only native fragment, copies runtime files when needed, and merges the fragment into .claude/settings.json.

TargetEmitted path
open-agents.agents/workflows/<id>/workflow.toml
claude.claude/workflows/<id>/workflow.toml
codex.agents/workflows/<id>/workflow.toml
cursor.cursor/workflows/<id>/workflow.toml

All four adapters currently support:

  • skill
  • tool
  • hook
  • workflow

Manifest-style Tuff-standard hook event support is adapter-specific. Native hook fragments supplied with --hook-file keep their harness event names and are merged as-is.

Eventopen-agentsclaudecodexcursor
before_finishYesYesYesPartial, rendered as stop
after_saveYesNoYesNo
pre_tool_useYes, rendered as pre_tool_executionNoPartial, rendered as pre_tool_executionYes, rendered as preToolUse
post_tool_useYes, rendered as post_tool_executionYes, rendered as post_tool_executionPartial, rendered as post_tool_executionYes, rendered as postToolUse
session_startNoYes, rendered as SessionStartNoYes, rendered as sessionStart
session_endNoNoNoYes, rendered as sessionEnd
stopNoNoNoYes, rendered as stop

Codex and Cursor have dedicated compatibility rows even when their output roots overlap with the generic Open Agents adapter. Cursor renders native names such as sessionStart, preToolUse, postToolUse, and stop into .cursor/hooks.json.

If you try to install a manifest-style hook with an unsupported event, Tuff blocks the install and shows which events that adapter accepts. Run tuff hooks matrix to inspect the registered adapter compatibility matrix, or tuff hooks check-portability <id> --target <adapter> to check an installed hook before switching adapters.

Terminal window
tuff agent list
tuff agent add open-agents
tuff agent add claude
tuff agent add codex
tuff agent add cursor
tuff hooks matrix