Use M8Shift in VS Code
M8Shift can coordinate Claude and Codex running as panels inside VS Code — the panels are the agents. The one thing to internalise: an interactive chat UI is not a background process. wait blocks a shell; it cannot wake a sleeping conversation. A human (or a host integration) resumes the next agent after each handoff.
Claude and Codex are used here as the concrete UI pair. The same discipline works with Gemini, Vibe, or any other cooperative agent UI that can read project instructions, run shell commands, and follow claim → work → append.
🟣 agent panels · ⚪ human resume (wait cannot wake a UI)
Setup
Open the repository in VS Code on its root — one window per repo.
Add the CLI and initialise:
bashcp m8shift.py . python3 m8shift.py init --agents claude,codexRun Developer: Reload Window, then start new conversations so each agent picks up its freshly injected anchor (
CLAUDE.md,AGENTS.md).Open both panels in the same window. For autonomy, put Codex in Agent mode and Claude in auto-accept.
Bootstrapping the loop
Give each agent a short loop prompt, Claude first:
Run
python3 m8shift.py next claude. If it claims the pen, do exactly one scoped step, thenappend claude --to codex --waitwith a clear--ask. Before any final answer to the human, runpython3 m8shift.py status --for claude; if the relay is notDONE, keep following the safe next action.
Then Codex, symmetrically (next codex, append codex --to claude --wait, status --for codex).
Keeping it moving
- After each handoff, resume the target panel: "Resume the M8Shift loop from
python3 m8shift.py next <agent>." - Prefer
append --waitwhen an agent hands off: it keeps that process blocked until its next turn orDONE, so a premature final message is harder to miss. - Keep
M8SHIFT.mdopen beside the source — the lock block tells you whose turn it is. - Use
python3 m8shift.py status --for <agent>whenever a human interrupts a panel; it prints the safe next action instead of relying on memory. - During a long
WORKING_<you>, re-runpython3 m8shift.py claim <you>to refreshexpirestonow + 30 min— a manual heartbeat (the agent or a headless wrapper does it; M8Shift runs no daemon). Skip it and the lock goes stale after 30 minutes, letting another agent reclaim it. - If a panel crashed mid-turn and left a stale lock, recover with
python3 m8shift.py claim <agent> --force(only works once the lock is past its 30-minute TTL).
For unattended runs, use the headless runner instead of the IDE. M8Shift stays the coordination primitive — it does not smuggle in a daemon under a fashionable name.