How Career-Ops Integrates with Claude Code, OpenCode, and Codex: An AI-Agnostic Architecture

Career-Ops integrates with AI coding CLIs through a centralized registry in web/src/lib/clis.ts that maps each tool to its specific invocation syntax, while keeping all business logic in Markdown prompt files under modes/ that any CLI can execute.

The santifer/career-ops repository implements an AI-agnostic architecture that decouples job-search automation logic from specific LLM providers. As documented in ARCHITECTURE.md, the system stores core logic in plain Markdown files and uses a lightweight CLI registry to translate commands for Claude Code, OpenCode, Codex, and other supported agents.

The CLI Registry: Mapping Commands to Binaries

At the heart of Career-Ops' multi-CLI support lies a lightweight registry that translates generic user intents into tool-specific command lines. This registry lives in web/src/lib/clis.ts and defines the exact binary names, flags, and argument patterns required for each AI coding assistant.

How the Registry Works

The CLIS array exported from web/src/lib/clis.ts contains configuration objects for each supported tool. Each entry specifies the binary name, the base command, and a function that formats the prompt into CLI-specific arguments:

// web/src/lib/clis.ts
export const CLIS = [
  { id: "claude",   name: "Claude Code",  bin: "claude",   run: "claude -p",   url: "https://claude.ai/code",               args: p => ["-p", p] },
  { id: "opencode", name: "OpenCode",    bin: "opencode", run: "opencode run", url: "https://opencode.ai",                 args: p => ["run", p] },
  { id: "codex",    name: "Codex",       bin: "codex",    run: "codex exec",   url: "https://github.com/openai/codex-cli", args: p => [p] },
];

When the Career-Ops web interface detects a CLI binary on your system, it consults this registry to suggest the correct invocation pattern. For example, Claude Code requires the -p flag to pass prompts, while OpenCode uses the run subcommand, and Codex expects the exec subcommand followed immediately by the prompt text.

Shared Prompt Architecture

Career-Ops achieves AI-agnosticism by keeping all business logic in plain Markdown files rather than embedding tool-specific code. This means any AI coding CLI can execute the same job-search workflows.

The modes/ Directory

All user-visible behavior—such as evaluating job descriptions, generating PDFs, or scanning portals—is defined in the modes/ directory. These files contain standard Markdown templates that serve as prompts for the LLM. Because the content is plain text, any CLI can read and execute these instructions without modification.

Universal Agent Instructions (AGENTS.md)

To ensure consistent behavior across different tools, Career-Ops maintains a shared instruction set in AGENTS.md. This file defines slash commands, skill definitions, and safety rules that remain identical regardless of which CLI you use.

For OpenCode specifically, the repository includes an OPENCODE.md wrapper that imports AGENTS.md, ensuring OpenCode understands the same configuration as Claude Code:

<!-- OPENCODE.md (first line) -->
<!-- OpenCode config — imports AGENTS.md, same as CLAUDE.md -->

This wrapper is referenced in DATA_CONTRACT.md, establishing a contractual guarantee that OpenCode will treat the repository exactly like Claude Code.

Running Career-Ops Across Different CLIs

You can invoke Career-Ops modes using the native syntax of whichever AI coding CLI you have installed. The underlying prompt remains identical; only the wrapper command changes:

Claude Code

claude -p "career-ops evaluate https://example.com/job"

OpenCode

opencode run "career-ops evaluate https://example.com/job"

Codex

codex exec "career-ops evaluate https://example.com/job"

Each command feeds the same evaluate mode prompt to the respective LLM backend. The CLI registry selects the appropriate entry and appends your arguments using the pattern defined in the args function.

The One-Command Installer

When you first clone the repository, the scaffolder script in scaffolder/bin/cli.mjs prints a reference table of supported agents and their exact command lines. This installer helps you verify that your chosen CLI is properly configured and shows the precise invocation syntax for Career-Ops workflows.

Why This Integration Works

The seamless integration across disparate AI coding tools relies on four architectural principles:

  1. Uniform prompt format – Every mode is a plain-text Markdown file; the CLI only needs to stream that text to the LLM.
  2. CLI-specific runners – Each entry in clis.ts knows how to call its binary (claude -p, opencode run, codex exec), abstracting tool-specific syntax away from the business logic.
  3. No hard-coded models – The LLM endpoint is chosen by the CLI's configuration, allowing you to swap providers (Claude, OpenAI, OpenRouter, Ollama) without touching Career-Ops code.
  4. Shared agent configuration – AGENTS.md provides identical instructions to both Claude Code and OpenCode, guaranteeing that slash-commands and safety rules remain consistent.

Adding a New CLI to Career-Ops

Extending support to a new AI coding tool requires only a single line entry in the registry. For example, to add a hypothetical "MyAI" binary:

// Extend web/src/lib/clis.ts
export const CLIS = [
  // ... existing entries
  { id: "myai", name: "MyAI", bin: "myai", run: "myai prompt", url: "https://myai.example.com", args: p => ["prompt", p] },
];

After adding this entry, the Career-Ops UI will automatically suggest "MyAI" when it detects the binary on your PATH, requiring no changes to the core job-search logic.

Programmatic Invocation

For automation scripts, you can invoke Career-Ops programmatically by mapping CLI IDs to their respective command strings:

import { execSync } from "child_process";

function runCareerOps(cliId, prompt) {
  const cliMap = {
    claude: `claude -p "${prompt}"`,
    opencode: `opencode run "${prompt}"`,
    codex: `codex exec "${prompt}"`,
  };
  const cmd = cliMap[cliId];
  if (!cmd) throw new Error("Unsupported CLI");
  return execSync(cmd, { encoding: "utf8" });
}

// Example: ask OpenCode to generate a PDF of the CV
console.log(runCareerOps("opencode", "career-ops pdf"));

This Node.js script demonstrates how the abstract CLI registry translates into concrete system commands, enabling you to build tooling that works across multiple AI assistants.

Summary

  • Career-Ops maintains a CLI registry in web/src/lib/clis.ts that maps tool-specific invocation patterns for Claude Code, OpenCode, Codex, and others.
  • All job-search logic resides in Markdown files under modes/ and shared instructions in AGENTS.md, making the system AI-agnostic.
  • OpenCode support is implemented via OPENCODE.md, which imports the same AGENTS.md used by Claude Code.
  • Adding new CLI support requires only a single-line entry in the registry, with no changes to core business logic.
  • The architecture delegates LLM provider selection to the CLI configuration, allowing seamless swaps between Anthropic, OpenAI, and local models.

Frequently Asked Questions

Does Career-Ops require a specific AI model or API key?

No. Career-Ops is AI-agnostic by design. The repository stores logic in Markdown files and delegates LLM execution to whichever AI coding CLI you have installed. Your API keys and model selection are configured in the CLI tool itself (Claude Code, OpenCode, etc.), not in Career-Ops.

How do I switch between Claude Code and OpenCode for the same task?

Simply use the command syntax specific to your installed CLI. For example, to evaluate a job description URL, use claude -p "career-ops evaluate [URL]" for Claude Code or opencode run "career-ops evaluate [URL]" for OpenCode. Both commands execute the same prompt file from the modes/ directory.

Where are the prompt templates and business logic stored?

All executable workflows and prompt templates are stored in the modes/ directory as plain Markdown files. Shared agent instructions that define slash commands and safety rules live in AGENTS.md at the repository root, which is imported by both Claude Code and OpenCode configurations.

Can I use Career-Ops with a local LLM like Ollama or via OpenRouter?

Yes. Because Career-Ops delegates LLM execution to the underlying CLI, you can use any model supported by your chosen AI coding tool. If your CLI (such as Codex or a custom OpenCode configuration) points to Ollama, OpenRouter, or another provider, Career-Ops will work with those endpoints without configuration changes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →