teammode skill
Codex-only team orchestration: run a named team of cooperating Codex workers with durable, script-managed state. MUST USE when the user asks Codex to create, run, coordinate, inspect, archive, or delete a team of agents/threads/sessions, or to work on something as a team in parallel. FIRST inspects the active tool surface (checking tool_search for deferred tools) and tells the user the route: native MultiAgentV2 agents (flat spawn_agent with task_name) when available, Codex App threads as the fallback, or a plain-subagent split when neither set exists. The main session is always the leader; members are defined by a concrete part, ownership area, or perspective - never a vague job role; a bundled cross-platform script writes the .omo/teams state plus an auto-generated member field manual. Use a team when the work is not perfectly isolated but parallelizing helps; use plain subagents when scope is perfectly isolated or the goal is ambiguous. Triggers: team mode, teammode, make a team, run as a team, team of agents, coordinate threads, parallel Codex threads, archive the team.
Is the teammode skill safe?
Clean: nothing in its files matched our rules. We read 6 files in the folder on 2026-09-28.
- low
SKILL.md:1The description is over 1,024 characters, the limit agents read.
1090 characters
Install the teammode skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/code-yeongyu/oh-my-openagent.git /tmp/oh-my-openagent mkdir -p ~/.claude/skills cp -r /tmp/oh-my-openagent/packages/omo-codex/plugin/components/teammode/skills/teammode ~/.claude/skills/teammode
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
Teammode
Run a named team of cooperating Codex workers under one leader, with durable state on disk. This is a Codex-only workflow. It never depends on an external terminal runner - it coordinates through Codex's own collaboration tools plus a bundled state script, on ONE of two transports chosen up front: native MultiAgentV2 agents, or Codex App threads as the fallback.
When to use a team (and when to use plain subagents instead)
Use a TEAM when EITHER holds:
more convenient - members will need to see and react to each other's findings; or
- the work does NOT split into perfectly isolated pieces, but doing it in parallel is clearly
a fixed objective.
- one task still needs exploration, yet its GOAL is already clear - parallel investigation under
Use plain fire-and-forget subagents ($ulw / one-off spawn_agent workers) - NOT a team - when EITHER holds:
- the work IS perfectly isolated, so there is no coordination cost worth paying; or
- the GOAL is still ambiguous, where one mind should resolve direction before any fan-out.
A team buys cross-member coordination at a real overhead cost; only spend it when coordination is the thing you actually need.
Pick the transport FIRST - then tell the user
Before creating any team state, decide which transport this session can run. Inspect your active tool list and select:
flat spawnagent whose schema requires taskname, plus sendmessage, followuptask, waitagent, listagents, and interruptagent. Members are durable native agents addressed by task name / agent path (/root/). The namespaced multiagentv1. surface never qualifies as a team transport.
- MultiAgentV2 (preferred) - select when the flat V2 collaboration tools are ALL active:
codexapp. thread tools are (createthread, readthread, sendmessagetothread, setthreadtitle, setthread_archived).
- Codex App threads (fallback) - select when flat V2 is not available but the
(e.g. spawnagent, codexapp) before concluding: some environments defer tools behind tool search. A hit is only a lead: revalidate that the visible result is the COMPLETE, mutually compatible transport set from case 1 or 2 before selecting it. Do not combine partial hits from different transports.
- Neither set visible - if a tool_search tool is active, search for the missing sets
partial tooling. If another visible plain-subagent mechanism can independently spawn, communicate with, and observe plain workers, announce that exact mechanism and use it for non-overlapping scopes. Otherwise continue serially and report the capability limitation; never promise or imply plain subagents that this session cannot create.
- Neither set exists - teammode cannot run here. Do NOT run init or fake a team with
Then, BEFORE running init (or instead of it in case 4), tell the user in one line what this environment provides and which route you picked:
using for independent scopes.
- Teammode transport: MultiAgentV2 (flat spawnagent with taskname).
- Teammode transport: Codex App threads (flat V2 tools not present in this session).
- Teammode unavailable: neither MultiAgentV2 nor codex_app tools exist in this session -
no compatible plain-subagent mechanism is available - continuing serially.
- Teammode unavailable: neither MultiAgentV2 nor codex_app tools exist in this session, and
Pass the choice to init as --transport multiagentv2 or --transport codexapp. The transport is recorded in team.json and is IMMUTABLE for the team's lifetime: a V2 spawn failure is a V2 blocker to report, never permission to mix Codex App threads into the same team. Never probe by trial-calling tools; read your tool list, and search it with toolsearch only when a needed set is not visible.
You are the leader - orchestrate, do not implement
The main session is ALWAYS the team leader; you orchestrate directly and never spin up a separate leader worker. Your job is orchestration, NOT writing product code: split the work and assign each slice, hold live situational awareness of every member, verify and QA what they deliver, relay findings between members, instruct and unblock, and synthesize the result. DELEGATE every code edit to a member - if you catch yourself editing product files while the team runs, that work was a member's slice you should have handed off. You own direction, verification, and integration (the merge), not the keystrokes.
Compose by part, ownership, or perspective - not by job title
A team is ALWAYS two or more members - never a single-member team. One worker on an isolated job is a plain subagent, not a team; if you end up with a single member, either split off a second distinct slice or drop the team and use a subagent.
Compose the team from what you actually KNOW about the work. Ground the split in real knowledge of the problem, then divide it into clear, non-overlapping responsibilities - one per aspect of the work - and give each member exactly one. No two members may own the same thing. Define each member by a concrete slice: a specific part of the codebase, an ownership area, or a distinct perspective/lens. Assigning a vague role ("backend dev", "release analyst", "the tester") is an anti-pattern - it gives the member no real boundary and invites overlap. Each member's focus names what they own concretely; the lens is one of area, ownership, or perspective. Give each member a short, distinct --name too - its role or what it watches (e.g. app-server-lifecycle, mailbox-delivery) - it labels the member everywhere; never reuse one name for two members. On MultiAgentV2 teams also give each member a unique --task-name in lowercasedigitsunderscores form - it becomes the member's permanent agent path /root/.
Run the script - never hand-write team state
A bundled, dependency-free Node script owns all team state so you never author team.json or the member manual by hand. Run it with node (or bun); it works on macOS, Linux, and Windows. Replace with this skill's own directory.
node "<skill-root>/scripts/team.mjs" init --name "<team>" --session-name "<session>" --transport multi_agent_v2|codex_app [--session <leader_thread_id>] [--worktree] [--base-branch dev]
node "<skill-root>/scripts/team.mjs" add-member --team <session_id> --id A --name "<short role>" [--task-name <v2_task_name>] --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>" [--branch <branch>]
node "<skill-root>/scripts/team.mjs" bind-agent --team <session_id> --id A --agent-path /root/<task_name> [--cwd <path>] # multi_agent_v2 teams
node "<skill-root>/scripts/team.mjs" bind-thread --team <session_id> --id A --thread <thread_id> [--cwd <path>] # codex_app teams
node "<skill-root>/scripts/team.mjs" member-prompt --team <session_id> --id A
node "<skill-root>/scripts/team.mjs" set-status --team <session_id> --id A --status reported|blocked|active|archived [--note "<...>"]
node "<skill-root>/scripts/team.mjs" worktree-add --team <session_id> --id A [--base-branch <branch>]
node "<skill-root>/scripts/team.mjs" worktree-remove --team <session_id> --id A [--force]
node "<skill-root>/scripts/team.mjs" integrate --team <sessinit creates .omo/teams/{sessionid}/ containing team.json (the single durable state file: team id, transport, the main-session leader, the member roster, status, worktree config, and a lifecycle log), guide.md (the auto-generated member field manual), and artifacts/ (a shared exchange space). On codexapp teams {session_id} is the leader's Codex session id when you can pass it via --session; otherwise the script generates a stable handle. Re-running init is a safe no-op. Every mutating subcommand rewrites guide.md, so the manual always matches the current team.
Mutating subcommands take a per-team state lock before reading and rewriting team.json. It is safe to run independent add-member, bind-agent, bind-thread, set-status, archive, delete, guide, and worktree mutation commands concurrently against the same team: they serialize and each command reads the latest committed state before writing. If a command reports that team state is locked, do not treat the intended mutation as complete; retry after the named command finishes, or inspect .omo/teams/{sessionid}/.team.lock/owner.json if the previous command crashed. bind-agent refuses codexapp teams and bind-thread refuses multiagentv2 teams, and a refused command never changes team.json.
Create the team and its members
init the team, then add-member once per member. What happens next depends on the transport.
MultiAgentV2 teams:
spawn_agent has no cwd argument, so the path must ride in the bootstrap message.
- If a member needs an isolated worktree, run worktree-add BEFORE spawning it - flat
taskname is that member's --task-name, message is the bootstrap printed by add-member / member-prompt, and forkturns is "none" (members read guide.md for context; full parent history is not their context model). Put any role, priority, or task-specific routing instruction in message; V2 does not accept agenttype, model, reasoningeffort, or service_tier, so members inherit the session model.
- Spawn each member with flat spawn_agent using only the V2 schema fields:
/root/); binding confirms the runtime identity matches the roster and records the member's cwd. Members are durable: they persist as subagent threads, survive idling, and are re-tasked with followup_task - never respawned under a second name.
- bind-agent --agent-path with the canonical task name the spawn returned (normally
deep links (V2 exposes no thread title or codex:// link surface to you).
- Members appear in list_agents with their task paths; inspect status there instead of
Codex App teams:
every member - titled [team name] , using THAT member's own name, so no two threads share a title. add-member prints the exact title to use. If the tool accepts a working directory / cwd argument, set it to that member's worktree; otherwise the member's manual tells it to cd there first. Use codexapp.setthread_title if the title did not land at creation. If Codex returns only pendingWorktreeId, the worktree-backed thread is not ready yet: do not bind-thread and do not send the member bootstrap. Wait until Codex surfaces a real threadId, then set the title, bind that real id with the cwd, and only then send the bootstrap.
- Create a durable thread per member with codexapp.createthread - ALWAYS this tool for
trigger as the thread's first message. The trigger is short on purpose: it tells the new thread to READ its guide.md and team.json rather than carrying the whole protocol inline.
- bind-thread to record each thread id (and --cwd), then send that member's bootstrap
codex://threads/ next to the raw id - worktree-backed threads are easy to lose in the sidebar without it. On a codexapp team, a spawned in-process agent is never a member substitute: it cannot carry the team title or be inspected, titled, archived, or re-opened with the codexapp.* tools this team runs on.
- Whenever you report, audit, reopen, or hand off a member thread, include the app deep link
On either transport, a member only counts once it is bound (bind-agent / bind-thread). If the selected transport's tools stop working mid-run, STOP and say so (see Stop rules); do not quietly switch transports.
Communication
Members push to you and to one another; you never poll them as a routine. The address book is team.json, and the generated manual binds members to the hard rules, so you mainly keep the channel open: expect frequent small inbound updates from each member - findings, WORKING:/BLOCKED: markers, peer digests - rather than one final dump, and act on them as they arrive.
members[].agentPath. You reach members the same way; use followuptask when you hand an idle member NEW work (it wakes the member), sendmessage for context that should not interrupt, and waitagent only when you are genuinely blocked on their next update - a waitagent timeout only means no new mailbox update arrived, never that a member failed. Your own session IS /root - members can always reach you; leave --session unset.
- MultiAgentV2: members reach you with send_message to /root and reach peers by their
More skills from code-yeongyu/oh-my-openagent
- Aast-grepSearches and rewrites code by AST shape across 25 languages. Use when the target is a syntax pattern (every call/class/import shaped like X, a codemod, a YAML rule) rather than literal text; for plain strings, comments, or filenames, use rg.
- AbrowserDrives a real browser through the omowright library from the js eval kernel: sites the user is already signed into, forms and clicks, JS-rendered pages, screenshots, web QA, extension popups, a human handoff for login, CAPTCHA or OTP, and a browser you own for scraping, bot-scored targets, network capture and QA traces. Use for any interactive browser task; not for a plain search or an unblocked static fetch.
- Acodex-qaQA the omo Codex Light edition (lazycodex / packages/omo-codex) itself, in strict isolation so ONLY our plugin is exercised, never the user's real ~/.codex. The first-party method drives the real `codex app-server` against an isolated CODEX_HOME plus a LOCAL mock model (no real API call), and proves a plugin hook fired by asserting hook/started + hook/completed notifications. Also: isolated install verification, per-component hook probes, a tmux TUI smoke, and runtime log observation (RUST_LOG / logs SQLite / /debug-config). Ships tested helper scripts each with a --self-test. Use whenever someone changes anything under packages/omo-codex or wants to QA, smoke-test, verify, or debug the Codex plugin, its hooks/components, the installer/config.toml, the app-server flow, or the Codex TUI. Triggers: codex qa, qa codex, codex-qa, test codex plugin, verify codex hook, codex app-server, lazycodex qa, isolated CODEX_HOME, prove codex hook fired, codex tui test.
- Acoding-agent-sessionsFinds, reads, and reconstructs coding-agent sessions across Codex, Claude, OpenCode, OMO/Senpi, and other local agent logs. Use when asked to find or search past sessions, transcripts, or subagent runs, or to recover what an earlier session did.
- Acomment-checkerUse when Codex needs to understand or respond to automatic comment-checker feedback emitted after an edit-like PostToolUse hook.
- Adag-libraryStores a DAG definition once and re-runs it by name, instead of pasting the definition into every run. Use when the user wants to save a DAG, run a saved one, or schedule the same multi-agent graph repeatedly.
- Ddata-scientistProcesses and analyzes data with resident-kernel engines (DuckDB, Polars) and one-shot tools. Use for CSV/parquet/JSON analysis, group-by/join/aggregation, time series, distributions, cleaning, or plotting a dataset.
- AdebuggingRuns a hypothesis-driven debugging loop across any language or binary, escalating to orthogonal oracle angles and locking the fix with a failing test. Use for crashes, silent failures, hangs, wrong responses, memory leaks, async misbehavior, or reverse engineering.
- Adev-browserBrowser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include "go to [url]", "click on", "fill out the form", "take a screenshot", "scrape", "automate", "test the website", "log into", or any browser interaction request.
- CfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- AfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- Aget-unpublished-changesCompare HEAD with the latest published npm versions and list all unpublished changes by release layer. Triggers: unpublished changes, changelog, what changed, whats new.