Skip to content

Install for six harnesses

On many teams one developer uses Claude Code, another uses Cursor, and a CI job runs Codex. Each harness wants the same agent (subagent) in a different folder and format. palm writes all six from one command, records every file in one lock, and tells you what each harness could not take.

When you finish, the agent exists once per harness format and the skill twice:

  • Folder.agents/
    • Folderskills/
      • Foldersdk-helper/
        • …
  • Folder.claude/
    • Folderagents/
      • agent-sdk-verifier-py.md
    • Folderskills/
      • Foldersdk-helper/
        • …
  • Folder.codex/
    • Folderagents/
      • agent-sdk-verifier-py.toml
  • Folder.cursor/
    • Folderagents/
      • agent-sdk-verifier-py.md
  • Folder.gemini/
    • Folderagents/
      • agent-sdk-verifier-py.md
  • Folder.github/
    • Folderagents/
      • agent-sdk-verifier-py.agent.md
  • Folder.opencode/
    • Folderagents/
      • agent-sdk-verifier-py.md
  • palm.lock.yaml
  • palm.yaml

The skill appears twice because Claude Code reads .claude/skills, which Cursor reads too, and the other four share .agents/skills. The sessions on this page ran against palm’s fixture that mirrors anthropics/claude-plugins-official.

  • The project is a git repository.
  • You accept that the Gemini CLI and OpenCode placements are unverified. They follow each harness’s documentation and source, checked on 2026-09-28, and have not run against a live CLI in palm’s tests yet.
  1. Declare all six targets.

    Terminal window
    palm init --target claude,codex,copilot,cursor,gemini,opencode
  2. Install the agent and the skill it uses.

    Terminal window
    palm install anthropics/claude-plugins-official agent-sdk-verifier-py sdk-helper
    ~/project
    $ palm install anthropics/claude-plugins-official agent-sdk-verifier-py sdk-helper
    i agent agent-sdk-verifier-py preloads mcp context7, not installed: palm install anthropics/claude-plugins-official mcp:context7
    i ref main saved to palm.yaml; edit ref: to pin a tag
    + skill sdk-helper .agents/skills/sdk-helper/, .claude/skills/sdk-helper/ 2 files from anthropics/claude-plugins-official main
    claude gets its own copy in .claude/skills
    cursor reads .claude/skills; no second copy
    + agent agent-sdk-verifier-py .claude/agents/agent-sdk-verifier-py.md, .codex/agents/agent-sdk-verifier-py.toml +4 6 files from anthropics/claude-plugins-official main
    .codex/agents/agent-sdk-verifier-py.toml: dropped model (sonnet), tools, skills, mcpServers, color (not supported by Codex)
    .github/agents/agent-sdk-verifier-py.agent.md: dropped model (sonnet), tools: Bash(python -m pytest:*) restriction (all of execute), mcpServers, skills, color (not supported by GitHub Copilot)
    .cursor/agents/agent-sdk-verifier-py.md: dropped model (sonnet), tools, skills, mcpServers, color (not supported by Cursor)
    .gemini/agents/agent-sdk-verifier-py.md: dropped model (sonnet), tools: Bash(python -m pytest:*) restriction (all of run_shell_command), skills, color (not supported by Gemini CLI)
    .opencode/agents/agent-sdk-verifier-py.md: dropped model (sonnet), color (green), tools: Bash(python -m pytest:*) restriction (all of bash), skills (not supported by OpenCode)
    2 installed. Commit palm.yaml, palm.lock.yaml, .claude/, .codex/, .cursor/, .gemini/, .github/, .opencode/ and .agents/ together.

    Each i line names what one harness has no place for, such as a model field for Codex or an argument restriction for Copilot. palm records the same notes in the lock, and palm describe agent-sdk-verifier-py shows them later.

  3. Compare the formats palm wrote.

    ~/project
    $ cat .claude/agents/agent-sdk-verifier-py.md
    ---
    name: agent-sdk-verifier-py
    description: "Use this agent to verify a Python Agent SDK app. Examples: <example>Context: user created an app</example>"
    model: sonnet
    tools: Read, Grep, Glob, Bash(python -m pytest:*)
    skills:
    - sdk-helper
    mcpServers:
    - context7
    color: green
    ---
    You are a Python Agent SDK application verifier.
    $ cat .codex/agents/agent-sdk-verifier-py.toml
    name = "agent-sdk-verifier-py"
    description = "Use this agent to verify a Python Agent SDK app. Examples: <example>Context: user created an app</example>"
    developer_instructions = """
    You are a Python Agent SDK application verifier.
    """
    $ cat .github/agents/agent-sdk-verifier-py.agent.md
    ---
    name: agent-sdk-verifier-py
    description: "Use this agent to verify a Python Agent SDK app. Examples: <example>Context: user created an app</example>"
    tools:
    - read
    - search
    - execute
    - context7/*
    ---
    You are a Python Agent SDK application verifier.
    Harness File What palm changes
    Claude Code .claude/agents/<name>.md nothing for a Claude Code agent; from another format, keys Claude Code does not define are dropped with a note
    Codex .codex/agents/<name>.toml TOML with name, description and developer_instructions
    GitHub Copilot .github/agents/<name>.agent.md Copilot tool names such as read and execute, MCP servers as context7/*
    Cursor .cursor/agents/<name>.md readonly: true only when no tool in the list writes files or runs commands
    Gemini CLI .gemini/agents/<name>.md strict frontmatter with kind: local and Gemini tool names
    OpenCode .opencode/agents/<name>.md mode: subagent and a permission map that denies what the tool list leaves out
  4. Install kinds that some harnesses cannot hold.

    Terminal window
    palm install anthropics/claude-plugins-official new-sdk-app
    palm install anthropics/claude-plugins-official hook:agent-sdk-dev --dry-run
    ~/project
    $ palm install anthropics/claude-plugins-official new-sdk-app
    i ref main saved to palm.yaml; edit ref: to pin a tag
    + skill new-sdk-app .agents/skills/new-sdk-app/, .claude/skills/new-sdk-app/ 2 files from anthropics/claude-plugins-official main
    from command new-sdk-app.md: installed as a skill, which a harness may also load on its own when it looks relevant
    claude gets its own copy in .claude/skills
    cursor reads .claude/skills; no second copy
    1 installed. Commit palm.yaml, palm.lock.yaml, .agents/ and .claude/ together.
    $ palm install anthropics/claude-plugins-official hook:agent-sdk-dev --dry-run
    This install adds 1 program that will run on your machine.
    1. hook agent-sdk-dev from anthropics/claude-plugins-official (commit bc94689, main, 2026-09-28)
    PreToolUse Write|Edit CLAUDE_PLUGIN_ROOT="$CLAUDE_PROJECT_DIR"/.palm/assets/anthropics__claude-plugins-official/agent-sdk-dev/plugins/agent-sdk-dev python3 "$CLAUDE_PROJECT_DIR"/.palm/assets/anthropics__claude-plugins-official/agent-sdk-dev/plugins/agent-sdk-dev/hooks/guard.py
    cursor: CURSOR_PLUGIN_ROOT="$CURSOR_PROJECT_DIR"/.palm/assets/anthropics__claude-plugins-official/agent-sdk-dev/plugins/agent-sdk-dev CLAUDE_PLUGIN_ROOT="$CURSOR_PROJECT_DIR"/.palm/assets/anthropics__claude-plugins-official/agent-sdk-dev/plugins/agent-sdk-dev python3 "$CURSOR_PROJECT_DIR"/.palm/assets/anthropics__claude-plugins-official/agent-sdk-dev/plugins/agent-sdk-dev/hooks/guard.py
    targets: claude (.claude/settings.json), codex (.codex/hooks.json), copilot (.github/hooks/agent-sdk-dev.json), cursor (.cursor/hooks.json), gemini (.gemini/settings.json)
    skipped: opencode (OpenCode hooks are JS plugins; hook agent-sdk-dev not installed)
    scripts: 2 files, 321 B -> .palm/assets/anthropics__claude-plugins-official/agent-sdk-dev/ (committed with your repo)
    plugins/agent-sdk-dev/hooks/guard.py 644 12 B sha256:3a66aebd
    ... 1 more (--review shows every script)
    palm never runs this itself. If you say yes, its hash goes into palm.lock.yaml,
    so teammates and CI install it without being asked; any change asks again.
    + would install hook agent-sdk-dev .github/hooks/agent-sdk-dev.json, .palm/assets/anthropics__claude-plugins-official/agent-sdk-dev/plugins/agent-sdk-dev/ +4 3 files +4 merged from anthropics/claude-plugins-official main
    OpenCode hooks are JS plugins; hook agent-sdk-dev not installed
    opencode: skipped
    dry run: 1 would install; nothing written.

    The command file installs as a skill everywhere, with a note about $ARGUMENTS. A harness without skill commands loses the /new-sdk-app call, and the note says so too. The hook lands in five harnesses. OpenCode has no declarative hooks, so palm skips it there and says so.

These are the combinations palm skips.

Kind Harness Scope Why
hook OpenCode both OpenCode hooks are JavaScript plugins
hook with a matcher that has arguments, such as Bash(git commit*) GitHub Copilot both Copilot matchers cannot hold arguments
instruction Cursor global Cursor keeps user rules in its settings

An on-request or manual rule is not skipped in Claude Code and OpenCode, but installs always-on there until 0.3, with a notice per rule.

palm describe target <target> prints where each kind goes for one harness, skips included.

Terminal window
palm describe target opencode

Several harnesses read the same files, and palm keeps each entity loaded once per harness. With claude and cursor, a skill lives only in .claude/skills, because Cursor reads it there. Codex reads instructions from AGENTS.md, which Cursor, OpenCode and Copilot also read. palm 0.2 still writes Cursor’s own .cursor/rules file too, and palm check warns about that double load. palm 0.3 records one carrier per harness and drops the second copy. The skill copies palm chose above never warn, because palm check uses the same facts as the install.

Terminal window
palm describe agent-sdk-verifier-py
palm check

palm describe lists the file each target received and every note palm recorded.