π―What you get here
A real, tested workflow from someone who works with both agents. Youβll learn how to configure a VS Code setup, pass context between them in 30 seconds, divide work without getting in each otherβs way, and prepare for new runtimes to arrive.
Detailed content
π Session handoff β the standardized summary
A short, structured summary you ask the current agent for BEFORE handing things off to the other one. This is the feature that unlocks a dual workflow. Without it, you keep re-explaining context. With it, you have a cheat sheet and can move on.
Handoff template (5 sections)
# Session handoff β 2026-05-24 16:30 ## π― Foco atual Implementar autenticaΓ§Γ£o OAuth no /api/auth com Google. ## π Arquivos tocados (com estado) - src/api/auth.ts β parcial, falta validaΓ§Γ£o JWT - src/api/auth.test.ts β testes do happy path passando - prisma/schema.prisma β adicionou model OAuthAccount ## β DecisΓ΅es tomadas - Usar passport.js (nΓ£o auth0) - JWT em cookie httpOnly (nΓ£o localStorage) - Refresh token rotacionando a cada 1h ## π§ Problema aberto JWT verification falhando com "jwt malformed" no payload de teste. Tentei 3 abordagens (recriar token, mudar secret, verificar cookie parse) sem sucesso. ProvΓ‘vel bug na lib ou no setup do test. ## β PrΓ³ximos passos 1. Investigar setup do test (jest mock do passport?) 2. Se persistir, trocar passport por jose lib 3. Implementar refresh endpoint 4. Cobertura de erro paths
β Good handoff
- β’ Short (fits on one page)
- β’ Fixed structure (5 sections)
- β’ List of files WITH status
- β’ Explicit decisions (not obvious from the code)
- β’ Current problem with previous attempts
β Useless handoff
- β’ "I'm working on feature X" (vague)
- β’ 20 pages of context (no one reads them)
- β’ No current problem (doesn't know what to do)
- β’ Decisions you can read from the code (redundant)
- β’ No next step
π‘Becomes a skill
Perfect candidate for a skill session-handoff in both runtimes (written once via polyskill). You run /session-handoff or $session-handoff, gets the completed template ready to paste into the other agent.
Key concepts
Focus, files, etc.
Standardizes
Single page
+ attempts
π₯οΈ Two terminals, one project β VS Code setup
Practical setup that works: VS Code open in the project, two terminal panes β one running claude, another running codex. Same filesystem, same git, same docs. You switch panels with a shortcut.
VS Code ASCII layout
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Explorer β src/api/auth.ts β
β β ββββββββββββββββββββββββββββββββββββββ β
β βΎ src β export async function login(req, res) { β
β api β // implementaΓ§Γ£o aqui β
β ui β ... β
β βΈ tests β } β
β β β
β ββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ€
β β TERMINAL 1: claude β TERMINAL 2: codex β
β β > refatorando auth.ts β > escrevendo testes β
β β [Claude pensaβ¦] β [Codex pensaβ¦] β
β β β β
ββββββββββββ΄βββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββ
Terminal split
Ctrl+Shift+5 (VS Code) splits the panel. Each half runs an agent.
Profile per agent
Create 2 terminal profiles in VS Code: "Claude" and "Codex". Different colors, agent auto-start.
focus shortcut
Ctrl+Shift+` focuses the terminal. Use the arrow keys to navigate between panels without a mouse.
Ideal workspace settings
// .vscode/settings.json
{
"terminal.integrated.profiles.osx": {
"Claude Code": {
"path": "/bin/zsh",
"args": ["-c", "claude"],
"color": "terminal.ansiBlue"
},
"OpenAI Codex": {
"path": "/bin/zsh",
"args": ["-c", "codex"],
"color": "terminal.ansiMagenta"
}
},
"files.watcherExclude": {
"**/.claude/**": false,
"**/.codex/**": false,
"**/.agents/**": false
}
}
Key concepts
Side-by-side panels
Visual distinction
No mouse
.vscode/ in git
β οΈ Avoiding conflicts β when both edit
If both agents edit the same file at the same time, one overrides the other. Itβs the #1 way to lose work with a dual workflow. The solution is simple discipline: split by area or phase.
π Division by area
Each agent works in different folders:
Claude β src/api/ (backend) Codex β src/ui/ (frontend)
No overlap, no conflicts. Simpler.
βοΈ Division by phase
Same area, different phases:
Claude β implementa src/x.ts Codex β escreve testes/x.test.ts
Coordinates: implementation done? Tell Codex to run a test.
Advanced strategies
feat/x-impl, codex in feat/x-test. Merge later.// LOCKED by claude β 16:30 at the top. Someone else sees it and respects it.β οΈThe scenario to avoid
Two agents editing src/api/auth.ts in parallel. Claude finishes and writes. Codex finishes 30s later and writes over itβClaudeβs work is lost. You discover at the next commit that half the changes are missing. 1β2 hours of drama to reconstruct it.
Key concepts
Simpler
Implementation vs. test
Advanced
Loses work
π Shared MCP servers
MCP servers run as independent processes. Configured once, both agents connect to the same. The server isnβt duplicatedβonly the declaration on the client (JSON for Claude, TOML for Codex).
Mirrored configuration
# Claude: .mcp.json (no projeto) { "mcpServers": { "github": { "command": "npx", "args": ["-y", "@mcp/github"], "env": { "TOKEN": "${GITHUB_TOKEN}" } } } } # Codex: .codex/config.toml (no projeto) [mcp_servers.github] command = "npx" args = ["-y", "@mcp/github"] [mcp_servers.github.env] TOKEN = "${GITHUB_TOKEN}" # Resultado: # Os dois agentes apontam pro MESMO server (mesmo binΓ‘rio, # mesmas credenciais, mesmas ferramentas expostas).
Independent server
MCP server is a process. It starts when called and stays available. It doesn't matter who called it.
Centralized env
Use .env shared. The GitHub token is in one place β both clients read it.
Allowlist by runtime
Each client can have a different allowlist. Codex allows everything, Claude allows read-only access. OK.
π‘Maintenance
A skill that needs a specific MCP? Declare it in openai.yaml sidecar for Codex AND in the frontmatter or doc for Claude. Polyskill handles this automatically when building.
Key concepts
Doesn't duplicate
Credentials once
JSON + TOML
By client
πͺ Hooks shared via script
Hooks are shell commands. Put the logic in scripts/check.sh in the project, both runtimes point to this script. Maintenance in one placeβedit the script, and both agents follow it.
Recommended standard
# scripts/lint-on-edit.sh β lΓ³gica central #!/bin/bash set -e CHANGED_FILE="$1" # passado pelo hook if [[ "$CHANGED_FILE" == *.ts ]]; then npx tsc --noEmit "$CHANGED_FILE" npx eslint "$CHANGED_FILE" fi if [[ "$CHANGED_FILE" == *.py ]]; then ruff check "$CHANGED_FILE" fi # .claude/settings.json β declara o hook { "hooks": { "PostToolUse": [{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "./scripts/lint-on-edit.sh ${file}" }] }] } } # .codex/config.toml β mesma coisa [[hooks]] event = "post_tool_use" matcher = "edit" command = "./scripts/lint-on-edit.sh ${file}"
β Logic in the script
- β’ Update the script β applies to both
- β’ Script can be tested outside the agent
- β’ Versioned alongside the code
- β’ Can also be used in CI/pre-commit
β Inline logic in hooks
- β’ Duplicates regex/commands across both runtimes
- β’ Forgets to update one side
- β’ Hard to test in isolation
- β’ Can't be reused outside hooks
π‘Git pre-commit hook too
Put scripts/lint-on-edit.sh no .git/hooks/pre-commit (or via husky). The same logic applies to both agents and manual commits. Triple guarantee.
Key concepts
Core logic
Only calls a script
Pass/block
Same script
π Governance β when to use which
Set of rules for choosing an agent by task type. Without a written rule, choices come down to unstable intuition. With a rule, new team members have a standard to follow.
Rule of thumb (real example)
Write in CLAUDE.md/AGENTS.md
Put the rule in the project manual. Everyone on the team sees it.
Periodic A/B testing
Every 2β3 months, redo a task in both. Calibrate the rule.
"Grab the idle one"
When it's a tie, use whichever has less context loaded.
π‘Quarterly review
Models are updated all the time. What was one modelβs strength may be another modelβs strength 3 months later. Schedule a review of the rule of thumb every quarter. Without a review, the rule becomes a myth.
Key concepts
Time consultation
Calibrates
Always an alternative
Fixed review
π Next runtimes β preparing for the future
The ecosystem doesn't stop at Claude+Codex. Gemini CLI, Cursor, Copilot, JetBrains AI Assistant are on the polyskill roadmap. Your cross-runtime skills are already readyβall thatβs missing is the adapter.
Polyskill roadmap
How to contribute a new adapter
- Repo fork
inematds/pollyskill - Create a new file in
src/adapters/<nome>.tsimplementing an interfaceAdapter(parse, emit, validate) - Register in
src/adapters/index.ts:register(new SeuAdapter()); - Add an example in
examples/<nome>-example/with round-trip - Open a PR with a tag
new-adapter
Community β Early AI Dopters
The patterns behind polyskill, updates as new runtimes gain adapters, and a working group of builders shipping cross-runtime tools β all of this lives at:
π¦The investment that lasts
Every skill you write in the portable format is future-proof. When Gemini gets an adapter, your skill works there on day 1. When Cursor does? Same thing. When βClaude 5 Codeβ comes along? Same thing. You don't rewrite it.
Key concepts
Standard contribution
Investment lasts
Early AI Dopters
Single slash
π―Module summary
π Course complete!
You completed all 6 paths. Now you know the anatomy of both runtimes, how to migrate, how to write cross-runtime skills with polyskill, and how to work with both day to day.