Supported Tools - mensfeld/code-on-incus GitHub Wiki

Supported AI Coding Tools

COI supports multiple AI coding assistants through a pluggable tool abstraction.

Currently Supported

Claude Code (default)

Anthropic's official CLI tool for AI-assisted coding.

# Use Claude Code (default)
coi shell

# Explicit tool selection
coi shell --tool claude

Configuration:

  • Config directory: ~/.claude/
  • Session storage: ~/.coi/sessions-claude/
  • Resume: coi shell --resume (auto-continues last conversation)

Claude-Specific Settings:

You can configure Claude Code-specific settings in your .coi/config.toml:

[tool]
name = "claude"

[tool.claude]
effort_level = "medium"  # "low", "medium", or "high" (default: "medium")

The effort_level setting controls Claude's response thoroughness. COI automatically injects this setting to prevent the interactive effort selection prompt from appearing during autonomous shell sessions.

Requirements:

  • Claude account (shows login screen if not authenticated)
  • API access via Anthropic or AWS Bedrock

opencode

Open-source AI coding agent from opencode.ai.

# Use opencode
coi shell --tool opencode

# Or configure as default in .coi/config.toml
[tool]
name = "opencode"

Configuration:

  • Config file: ~/.config/opencode/opencode.json (XDG-compliant location)
  • Session storage: .opencode/ in workspace directory (SQLite database)
  • Resume: coi shell --tool opencode --resume uses --continue to resume the last session

Requirements:

  • API key required (unlike Claude, opencode won't start without one)
  • Set ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable
  • Or configure in ~/.opencode.json:
{
  "providers": {
    "anthropic": {
      "apiKey": "sk-ant-..."
    }
  }
}

Key Differences from Claude:

Feature Claude Code opencode
Login screen Shows if no API key Fails if no API key
Session storage ~/.claude/ (home dir) .opencode/ (workspace, SQLite)
Resume behavior --resume continues last conversation --resume uses --continue flag
Config location ~/.claude/ directory ~/.config/opencode/opencode.json
Permission bypass Auto-injected into settings.json Auto-injected "permission": {"*": "allow"}

Passing API Keys

For opencode and other tools that require API keys:

# Via forward_env in config (~/.coi/config.toml)
[defaults]
forward_env = ["ANTHROPIC_API_KEY"]
# Via host config file (copied into container automatically)
# ~/.opencode.json on host is copied and merged with permission bypass

Tool Selection

Per-Session (CLI Flag)

coi shell --tool opencode
coi shell --tool claude

Per-Project (.coi/config.toml)

# .coi/config.toml in project root
[tool]
name = "opencode"

Migration from 0.7.x: Project config has moved from .coi.toml to .coi/config.toml. See Configuration for details.

Global Default (~/.coi/config.toml)

[tool]
name = "opencode"

Precedence: CLI flag > .coi/config.toml > global config > "claude" (default)

Permission Mode

By default, COI bypasses all permission prompts inside containers so tools run autonomously. If you prefer a human-in-the-loop workflow where the tool asks before running commands, set permission_mode under [tool]:

# .coi/config.toml or ~/.coi/config.toml
[tool]
permission_mode = "interactive"  # "bypass" (default) or "interactive"
Mode Claude Code opencode
bypass (default) --permission-mode bypassPermissions flag + bypass settings injected into settings.json "permission": {"*": "allow"} injected into opencode.json
interactive No bypass flag or settings — Claude asks before running commands No permission bypass injected — opencode asks before running commands

Notes:

  • This is a cross-cutting setting that applies to whichever tool is active
  • Effort level settings (for Claude) are always injected regardless of permission mode
  • Empty or omitted value defaults to "bypass" for backward compatibility

Adding New Tools

COI's tool abstraction makes it straightforward to add new AI coding assistants. Each tool implements the Tool interface:

type Tool interface {
    Name() string
    Binary() string
    ConfigDirName() string
    SessionsDirName() string
    BuildCommand(sessionID string, resume bool, resumeSessionID string) []string
    DiscoverSessionID(stateDir string) string
    GetSandboxSettings() map[string]interface{}
}

Tools that use a config directory (most tools) should also implement ToolWithConfigDirFiles, which tells COI which files to copy from the host and where to inject sandbox settings:

type ToolWithConfigDirFiles interface {
    Tool
    EssentialConfigFiles() []string       // Files to copy from host config dir
    SandboxSettingsFileName() string      // File to inject sandbox/bypass settings into
    StateConfigFileName() string          // Sibling state file (e.g. ".claude.json"), "" if none
}

Tools that support configurable reasoning effort (like Claude) can implement ToolWithEffortLevel:

type ToolWithEffortLevel interface {
    Tool
    SetEffortLevel(level string)  // "low", "medium", or "high"
}

Tools that support configurable permission modes can implement ToolWithPermissionMode:

type ToolWithPermissionMode interface {
    Tool
    SetPermissionMode(mode string)  // "bypass" (default) or "interactive"
}

Tools that support auto-loading context from a file (like Claude's ~/.claude/CLAUDE.md) can implement ToolWithAutoContextFile:

type ToolWithAutoContextFile interface {
    Tool
    AutoContextFile() string  // Path relative to home dir (e.g. ".claude/CLAUDE.md")
}

Tools that reference the context file path in their config (like OpenCode's instructions field) can implement ToolWithAutoContextPath:

type ToolWithAutoContextPath interface {
    Tool
    SetAutoContextPath(path string)  // Absolute path to sandbox context file
}

See internal/tool/tool.go and internal/tool/opencode.go for complete examples.

Sandbox Context File

COI automatically injects a ~/SANDBOX_CONTEXT.md file into every container, describing the sandbox environment to AI tools. This includes:

  • Workspace path and home directory
  • OS and architecture
  • Container mode (ephemeral/persistent)
  • Network mode and restrictions
  • SSH agent availability
  • Docker availability
  • User privileges and sudo access
  • Protected paths and limitations

The file is rendered from a built-in template with session-specific values and regenerated on every session start (including resume), so AI tools always have current information about their environment.

Auto-Context Injection

By default, COI also injects the sandbox context into each tool's native context-loading mechanism (auto_context = true):

  • Claude Code: Sandbox context is written to ~/.claude/CLAUDE.md, which Claude auto-reads at every session start. If the host has a CLAUDE.md with user instructions, those are preserved and sandbox context is appended with a # COI Sandbox Context separator.
  • OpenCode: The instructions field in opencode.json is set to reference ~/SANDBOX_CONTEXT.md.

This means AI tools automatically have full sandbox awareness without users needing to manually reference ~/SANDBOX_CONTEXT.md.

To disable (the ~/SANDBOX_CONTEXT.md file is still created):

[tool]
auto_context = false

Override with a custom file:

[tool]
context_file = "~/my-sandbox-context.md"

When context_file is set, COI uses your custom file instead of the built-in template. Supports ~ expansion.

Coming Soon

  • Aider - AI pair programming in your terminal
  • Cursor - AI-first code editor (CLI mode)

The tool abstraction layer makes it easy to add support for new AI coding assistants as they become available.