Codex with ChatGPT
ChatGPT thinks. Codex works.
You (Codex) own execution: editing, shell, git, tests, recovery.
ChatGPT owns high-level reasoning: understanding, planning, review, debug strategy.
The C2C Bridge gives ChatGPT read-only MCP access to the current workspace, so
control messages between you and ChatGPT stay tiny (< 1 KB) — ChatGPT pulls
whatever data it needs by itself.
Golden rules
- NEVER paste file contents, diffs, or logs into ChatGPT. ChatGPT reads them through MCP.
- NEVER show the user technical internals (MCP, OAuth, PKCE, tunnel, ports, localhost).
Speak in terms of "连接 ChatGPT / 安全连接 / 配对". The only exception is the
guided manual ChatGPT setup below: expose only the exact settings
field labels/values the user must enter, without explaining internals.
- The pairing code is the ONLY credential you may ever type into a browser.
Never touch OAuth tokens, cookies, or session storage.
- If something fails, run
c2c doctor and repair silently. Only involve the user
for logins, CAPTCHA, 2FA, explicit consent screens, or guided manual
ChatGPT setup below — and then give them ONE action.
Before the first ChatGPT connection on this machine, c2c prefs --json:
setupMode missing: tell the user exactly setupChoicePrompt, wait for
「1」or「2」, then c2c prefs set --setup-mode auto|manual --json.
Do not start ChatGPT configuration until they answer. Do not guess.
setupMode is manual: skip automatic ChatGPT settings. Use guided
manual from the start (chosen, not a failure).
setupMode is auto: automatic browser setup. Two explicit failures of
the same configuration step after repair then enter guided manual.
A browser/js timeout, a page still loading/generating, or waiting for
user login/2FA does NOT count as a failure. Do not change the saved
setupMode when falling back.
developerModeEnabled: true means skip #settings/Security until a
connector create fails because developer mode is required. Then open
that page, enable it, and c2c prefs set --developer-mode --json.
These prefs are for this machine, not per workspace. Do not ask again
on reconnect or a second repo. A new computer (empty prefs) asks/checks
once.
- ALWAYS use the built-in in-app browser (iab) for every ChatGPT step.
Follow In-app browser (ChatGPT) below. NEVER Computer Use (no
screenshot-click). NEVER launch or control a third-party/external browser
(Chrome, Safari, Edge…), and never use
open <url> to hand off to one.
- The ONLY exception: the user explicitly says the Cloudflare login must use
their own browser session — that single Cloudflare login step may go through
their browser; everything else stays in the built-in browser.
- If the user asks to run ChatGPT in their own browser, refuse politely and
explain: "Codex 需要持续调用 ChatGPT 和配置连接,这会频繁操作页面,可能影响
你浏览器的正常使用。ChatGPT 只能跑在内置浏览器里。" Only if the user replies
with an explicit "我愿意承担影响" may you proceed in their browser; otherwise
keep ChatGPT in the built-in browser, every time they ask.
- Conversation reuse depends on
c2c session --json → conversation.mode
(see Conversation management). Do not invent a second mode.
- long-chat (legacy session file, or the user opted out): ONE ChatGPT
conversation per workspace. Never silently start a new chat.
- project (new workspaces, or an existing workspace that opted in):
ONE ChatGPT Project (collection) per workspace. Same Codex conversation
reuses the ChatGPT chat URL saved in THIS thread. A new Codex
conversation opens a new chat from the Project collection page — never
goto https://chatgpt.com/ to create it, and never reuse another
Codex conversation's chat URL just because session.url exists.
Each workspace also has exactly ONE ChatGPT connector. Do not create a
second connector for the same workspace. Other workspaces may have their
own connectors — never edit those.
- After first-time setup, never ask the user to approve writing C2C's local
settings directory. Run
c2c sandbox-allow --json (idempotent). If it fails
with EPERM / Operation not permitted, request elevated permissions and retry
ONCE. After { "alreadyAllowed": true } or { "added": true }, stay silent.
- ChatGPT pages: only the URLs in In-app browser (ChatGPT). Never start
from chatgpt.com and click through menus.
- Doctor gate. After
c2c doctor --json, do not goto ChatGPT and do not
send [C2C] until local is green — except the reconnect settings pages when
chatgptRepair.needed is true. Not green:
report.bridge.ok is not true
report.mcp.ok is not true (unauthenticated local /mcp must be 401)
- sandbox / state-dir write failed (EPERM)
- this workspace used to have a public URL and the tunnel is down
chatgptRepair.needed is true (fix the connector first, then doctor again)
namedRepair.needed is true (user must log in to Cloudflare, then doctor again.
Do not Delete the ChatGPT connector — the address did not change)
report.bridge says 状态无法确认: the local bridge may still be running.
Do not c2c start, do not Delete the connector, do not treat it as
chatgptRepair. Wait and run doctor again.
If doctor is already green and chatgptRepair.needed is false, do not
c2c restart, do not start a second tunnel, and do not Delete the
connector. ChatGPT/IAB-only errors are not permission to churn the
public address.
A ChatGPT-side 401 after a sent message is different: repair then, do not
treat it as permission to skip this gate next time.
In-app browser (ChatGPT)
Official skill: control-in-app-browser. These C2C rules override defaults
that close the tab, hide the window, or stall on the settings page.
Surface. Once per Codex session: setupBrowserRuntime(), then
const iab = await agent.browsers.get("iab"). Reuse iab. Do not re-read
documentation() if it is already bound. Never getDefault(), getForUrl(),
or Computer Use.
One tab. Create the ChatGPT tab once (tabs.new()). After that, only
tab.goto(...) to switch URLs. If the tab still exists, claim it — never
open a second ChatGPT tab. Do not goto the URL you are already on.
Foreground + keep (standby). Right after opening or claiming the tab:
await (await iab.capabilities.get("visibility")).set(true) — first-time
setup and ChatGPT chatting stay in front of the user so they can watch.
await tab.markHandoff() immediately, then again at the start and end of
every turn. After setup succeeds or the C2C chat is open, also
await tab.markDeliverable().
Never close this tab. Finished, waiting for the user, or timed out: leave it
marked (standby). Do not let default turn cleanup close it.
URLs only (same tab, goto — never hunt menus):
- 开发人员模式:
https://chatgpt.com/#settings/Security
(skip when c2c prefs --json has developerModeEnabled: true)
- 插件总管:
https://chatgpt.com/plugins
- 加插件:
https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins
- 新对话 (long-chat only, and only if no saved chat):
https://chatgpt.com/
- Saved C2C chat:
conversation.chatUrl / session.url (long-chat, or
the chat already bound in THIS Codex conversation)
- Saved Project collection:
conversation.projectUrl
(https://chatgpt.com/g/g-p-…/project)
Never click Reconnect / Refresh on an existing connector. The old address is
dead and that page hangs on "This site cannot be reached". When the address
changed: Delete THIS workspace's connectorName only, then create it again
via the 加插件 URL (same name, new Server URL). Do not put that public
address into Project instructions — write the connector name only.
Do not wait for 8 tools on the settings page. "Connected" / authorize
success / pairing accepted is enough. Confirm tools in the conversation with
workspace_info.
Batch. Fill a known form in one Playwright / js script when you can.
After an action, one cheap DOM check. Do not screenshot-poll.
One conversation, Chat mode. The first ChatGPT chat is the C2C
conversation. Chat and Work (聊天 / 工作) are separate: a Work conversation
cannot become Chat. On every NEW conversation, if a Chat/Work switcher is
visible (often top-left), confirm Chat is selected before the boot
prompt. If it is Work, do not continue there — Switch to a new Chat
conversation (HANDOFF). If no switcher is visible, do not hunt menus; continue.
Send the boot prompt and the workspace_info check in that Chat conversation.
Confirm the reply names the current workspace before saving or replacing
the session URL. If validation fails, keep the old saved URL. Do not open a
throwaway verify chat and later another C2C chat.
A collection or chat page that shows only Retry / 重试 is a navigation
error, not generation and not a pairing failure. Reuse the same iab tab.
Try Retry once. If it stays Retry-only, goto the last working chat URL
from this thread (or session.url if that is the only saved chat), then
click the on-page Open … project / 打开“… ”项目 link — that same-site
hop is allowed. Do not treat the URLs-only rule as forbidding this link.
On the collection, require the project chat list and new-chat composer
before continuing. Keep the old saved URL/checkpoint until the replacement
chat passes workspace_info. Do not session clear. Do not use Computer Use.
Wait for a ChatGPT reply (do not hold one long browser wait). After you
send INIT, EXECUTED, boot, or the workspace_info check: markHandoff, keep
the tab foreground, and stay in this same task. Do not waitFor 5 minutes
and do not screenshot-poll. Every 20–30 seconds, one cheap DOM check:
- still generating → wait again (do not type, do not resend);
STATE: PLAN / DONE / BLOCKED / the verify workspace name → read it
and continue the existing protocol;
- visible error → repair; do not start a new chat.
A browser/js timeout is not failure. Claim the same tab, read the page, keep
standby. If ChatGPT is still thinking, keep polling. Never open a second
tab and never resend INIT/EXECUTED just because a wait timed out.
Locations
- The codex-with-chatgpt checkout lives at:
<ACTUAL_CHECKOUT_PATH>
(installer/update MUST replace this line in the installed Skill with the user's actual checkout path.)
- CLI: let
<checkout> mean the path on the previous line; run
node "<checkout>/bin/c2c.js" <command> (or c2c <command> if globally linked).
All commands support --json for parsing.
- If the checkout has no
node_modules or no dist/, first run
corepack pnpm install && corepack pnpm build inside it.
- For commands that act on the user's project (
setup, doctor, session,
restart, start, stop, status, pair, unpair, logs, workspace,
record, tunnel status, tunnel choose), pass -w <workspace root>
(the project the user is working on, NOT the c2c repo).
- Do not add
-w to machine-wide commands: update-check, sandbox-allow,
prefs, tunnel login. They still accept and ignore -w, so a leftover
flag must not fail the command.
Daily update check
At the START of every workflow below (before anything else), run these two
commands (both are cheap / cached; never mention them unless an update exists):
c2c update-check --json (do not pass -w)
c2c sandbox-allow --json (do not pass -w) — writes the C2C state directory into Codex's
sandbox writable_roots (macOS: ~/Library/Application Support/codex-with-chatgpt;
Windows: %LOCALAPPDATA%\codex-with-chatgpt; config file is
~/.codex/config.toml on both, or %USERPROFILE%\.codex\config.toml on Windows).
If already allowlisted, this is a no-op and does not trigger elevation.
{ "updateAvailable": false } → continue silently. Never mention the check.
{ "updateAvailable": true } → tell the user one line:
"检测到 Codex with ChatGPT 有新版本,我先更新一下(约 1 分钟),随后继续你的任务。"
Then run the update workflow below, and CONTINUE the original task afterwards.
Workflow: update("更新 Codex with ChatGPT",or triggered by the daily check)
Inside the checkout directory (see Locations):
git pull --ff-only (if it fails due to local edits: git stash && git pull --ff-only).
corepack pnpm install && corepack pnpm build.
- Re-install the Skill: copy
skill/SKILL.md to
~/.codex/skills/codex-with-chatgpt/SKILL.md, then fix the "checkout lives at:"
line in the copy to the actual checkout path.
c2c sandbox-allow --json (so existing installs pick up the sandbox allowlist),
then c2c restart -w <workspace> so the bridge runs the new code, then
c2c update-check --force --json to refresh the cache (should now report up to date).
- Tell the user "✓ 已更新到最新版本" — then resume whatever task triggered this.
(The updated SKILL.md takes effect from the next Codex session; that's expected.)
Connection choice (once per workspace)
Ask this before the public address exists (c2c setup / first doctor --fix
that starts a tunnel). Do not mention tunnels, wrangler, DNS, or hostnames.
Speak only of 临时地址 / 固定域名 / 登录 Cloudflare.
c2c tunnel status -w <workspace> --json
- If
needsChoice is false: do not ask again.
- If
needsChoice is true: tell the user exactly userPrompt and wait.
- 没有账号 / 没有域名 / 临时 / 不用 →
c2c tunnel choose -w <ws> --mode quick --json
- 有域名(例如 example.com)→ first tell them
loginPrompt, then
c2c tunnel choose -w <ws> --mode named --zone <domain> --json.
This may open the user's own browser (the Cloudflare exception in
Golden rule 5). Wait until the command finishes.
If they said they have an account but gave no domain: ask once for the
domain. If the command returns need: "zone", ask once and retry.
If fallback is true: tell them userMessage and continue on the
temporary address. Do not retry named unless they ask.
- Never put connection credentials in the project. The CLI stores them in
the C2C state directory.
Workflow: first-time setup("使用 Codex with ChatGPT 完成首次配置")
- Detect prerequisites yourself:
node --version (>= 20), and check cloudflared.
- If cloudflared is missing on macOS run
brew install cloudflared; on Windows use
winget install Cloudflare.cloudflared. Do this yourself; don't ask.
- If the c2c repo has no
node_modules, run pnpm install && pnpm build in it.
- Run
c2c sandbox-allow --json, then Connection choice, then
c2c setup -w <workspace> --json.
sandbox-allow edits Codex config.toml only — it adds C2C's state directory
to [sandbox_workspace_write].writable_roots so later chats can write logs
without elevation. If the write is denied, request approval and retry once.
→ returns { mcpUrl, pairingCode, workspaceName, connectorName, ... }.
connectorName is this workspace's plugin title (legacy installs stay
Codex with ChatGPT; additional workspaces get Codex with ChatGPT · <name>).
Pairing codes expire in ~5 minutes. Do not mint one until the ChatGPT
Authorize / pairing form is on screen: run c2c pair --json then type
that code immediately. Doctor does not pre-mint a code.
c2c prefs --json (this machine, not this workspace).
- If
setupMode is null: tell the user exactly setupChoicePrompt. Wait
for「1」or「2」. Then c2c prefs set --setup-mode auto or --setup-mode manual.
Do not open ChatGPT settings and do not start automatic configuration
until they answer. Do not default to auto.
- If they later ask to switch: same
c2c prefs set --setup-mode command.
Do not re-ask on a later workspace or on reconnect.
setupMode: "manual": skip step 5's automatic ChatGPT settings. Go to
Guided manual ChatGPT setup (chosen). Opening line:
接下来用手动教学配置。一次只需要做一个操作。
Do not say 自动配置没有成功.
setupMode: "auto": continue with step 5. Keep the two-failure fallback.
- Open ChatGPT on the ONE iab tab (see In-app browser). Foreground +
markHandoff immediately. Same tab,
goto only:
- 开发人员模式: skip
https://chatgpt.com/#settings/Security when
developerModeEnabled is true. Otherwise open it, enable 开发人员模式
("Developer mode") if it is off, then c2c prefs set --developer-mode.
Never record it as off. If creating the connector later says developer
mode is required, open this page, enable it, save --developer-mode,
and retry create — do not skip that recovery.
- 已有该
connectorName: https://chatgpt.com/plugins — Delete it (never
Reconnect). Then goto the 加插件 URL below.
- 还没有 / 刚删掉:
https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins
Operate ONLY on connectorName from step 3:
- If that exact name exists: Delete it, then create it again. Never
Reconnect, never edit-in-place, never open the old Server URL.
- If it does not exist: create one with that exact name.
- Never rename, delete, or edit a connector that belongs to another workspace.
- Description:
Securely connect ChatGPT to the current Codex workspace for planning and review.
- Server URL: the
mcpUrl from step 3
- Authentication: OAuth
Fill the known form in one script when you can. Then Connect / Authorize.
Only then run
c2c pair --json and type that code. As soon as it shows
Connected / authorized / pairing accepted, continue — do NOT wait for 8
tools on this page.
- Same tab: open the first C2C chat per Conversation management
(Project collection for a new workspace;
https://chatgpt.com/ only
in long-chat). Confirm Chat mode per In-app browser §7 (if it is Work,
open a new Chat conversation instead). Send the boot prompt from
docs/protocol.md §Boot Prompt, then (same chat) send:
Use the "<connectorName>" connector: call workspace_info and read hello-style top-level file. Reply with the workspace name.
Confirm the reply matches workspaceName (wait per In-app browser §8).
Only then save the chat URL with c2c session set (see Conversation
management). If the name does not match, do not save. markDeliverable.
- Report to the user exactly in this shape (no internals):
Codex with ChatGPT
✓ 当前项目已识别
✓ Workspace Bridge 已启动
✓ 安全连接已建立
✓ ChatGPT 已连接
✓ 文件读取测试通过
Ready.
If a login wall appears (ChatGPT, Cloudflare): stop, tell the user the ONE thing
to do ("请登录 ChatGPT,完成后告诉我'好了'"), then continue.
Guided manual ChatGPT setup
Enter this path when setupMode is manual (chosen at the start), or when
automatic ChatGPT browser configuration fails twice at the same explicit
setup/reconnect step after c2c doctor / repair. Do NOT enter the failure
path for a browser/js timeout without a visible error, a page that is
still loading/generating, or while waiting for login / 2FA / CAPTCHA.
A chosen manual path does not wait for those two failures.
Stop automating ChatGPT settings. Keep the current local C2C state and the
current mcpUrl, pairingCode, workspaceName, and connectorName. Do not
silently fall back to Codex-only execution and do not permanently disable C2C.
Do not change the saved setupMode when this is a failure fallback.
Opening line:
- Chosen (
setupMode: "manual"): 接下来用手动教学配置。一次只需要做一个操作。
- Failure fallback:
自动配置没有成功,我来带你手动完成。一次只需要做一个操作。
Then guide ONE action at a time, waiting for the user to say「好了」before the
next action:
- If
developerModeEnabled is not true: ask them to open
https://chatgpt.com/#settings/Security and enable 开发人员模式. After they
say「好了」, c2c prefs set --developer-mode. If it is already remembered,
skip this step.
- Ask them to open
https://chatgpt.com/plugins. If the exact connectorName
exists, delete only that connector. Never ask them to touch another workspace's connector.
- Ask them to open
https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins
and create the exact connectorName with:
- Description:
Securely connect ChatGPT to the current Codex workspace for planning and review.
- Server URL: the current
mcpUrl
- Authentication: OAuth
- Ask them to Connect / Authorize. Then run
c2c pair --json and give them
only that pairing code. If it expires before they finish, run pair again.
- When they report Connected / authorized / pairing accepted, resume the normal
setup/reconnect flow at its ChatGPT verification step. If automatic browser
verification then hits the same explicit failure twice, stop and report the
exact failed step; do not loop indefinitely and do not continue without C2C.
Conversation management
c2c session -w <ws> --json → { session, conversation }.
conversation.mode is the only switch. Missing / legacy files with a chat URL
and no Project stay long-chat. Do not ask those users to migrate. If they
later say they want a Project, run Bind Project. A brand-new workspace
(no session file) is project.
Never match a Project or a chat by display name. Never upload the repo to
Project sources. Never click 分享 / Share. Do not rename ChatGPT chats.
long-chat (do not rewrite this path)
ONE ChatGPT conversation per workspace. Same as before.
- Find it: if
conversation.reuseSavedChat and conversation.chatUrl,
goto that URL (foreground + markHandoff) and continue there.
- Save it: after boot + workspace_info, and the reply names this workspace,
c2c session set -w <ws> --mode long-chat --url <url> --title "C2C <workspace name>".
If the name does not match, do not overwrite a previously saved URL.
- Update it: after each EXECUTED/DONE,
c2c session set -w <ws> --task <id> --iteration <n> --state <STATE>
plus checkpoint flags from the coding workflow (--protocol-state,
--waiting-for, --goal, --next-step, --known-issues, or
--clear-checkpoint on DONE). Do not put logs or diffs in those fields.
- Switch it ONLY when (a) the user asks for a new chat, (b) the current
chat visibly lags, or (c) this conversation is Work. Then:
- Same iab tab:
goto https://chatgpt.com/, confirm Chat mode
(In-app browser §7), then send the boot prompt.
- Send a HANDOFF (
docs/protocol.md) — goal, progress, state, issues,
next step. Never paste files.
- workspace_info check; only then
c2c session set --url. On failure,
leave the old saved URL unchanged.
- Saved chat 404s: treat as a switch. Reconstruct HANDOFF from
session.checkpoint (goal, progress, issues, next step). If there is no
checkpoint, use task / iteration / lastState and execution_summary
metadata only. Never paste logs or output bodies.
project (new workspaces)
One ChatGPT Project per workspace. Mapping:
- Same Codex conversation (this thread still has context) → same ChatGPT
chat URL.
goto that URL directly. Do not open the collection first.
- Same workspace, a new Codex conversation → new ChatGPT chat from the
collection page (
conversation.projectUrl). Ignore session.url unless
you already saved it earlier in THIS Codex thread.
- Different workspace → different Project and different connector.
Open a chat in this Codex thread
- If you already saved a ChatGPT chat URL earlier in THIS Codex conversation:
goto that URL. Continue. No new chat. No HANDOFF.
- Else if
conversation.projectReady: goto conversation.projectUrl.
On that page, use the on-page composer (「{项目名}中的新聊天」 / "New chat
in …"). Do not use the sidebar and do not goto https://chatgpt.com/.
Confirm Chat mode (In-app browser §7). Boot prompt, then workspace_info
with the exact connectorName. After the reply names this workspace,
c2c session set -w <ws> --mode project --project-url <collection> --url <chat> --connector-name "<connectorName>" --title "C2C <workspace name>".
If this Codex thread is continuing a previous C2C task, send HANDOFF right
after the boot prompt.
- Else: Bind Project first.
Update it: same c2c session set --task / --iteration / --state as long-chat.
Wrong collection: do not guess another Project. Tell the user the expected
workspace name, ask them to open the right collection, then say「已找到」.
Also offer「继续用长对话」. If they pick long-chat:
c2c session set -w <ws> --mode long-chat and use the long-chat path.
If the collection 404s or the new chat is not inside the Project, same choice.
Saved chat 404s (this thread): goto the collection, open a new chat
there, boot + HANDOFF from session.checkpoint (no logs) + workspace_info,
then save the new chat URL. Keep --project-url.
Bind Project (user creates the collection once)
Do this for a new workspace, or when an existing user asks to switch to
Project. Do not click the ChatGPT sidebar to create the Project
(Computer Use is forbidden; IAB must not hunt that menu).
- Tell the user exactly this (fill in the workspace name):
请在 ChatGPT 里新建一个项目,名字用「<workspaceName>」,记忆请选「仅限项目记忆」。
如果侧栏里看不到「项目」:把鼠标放在「聊天」上,点右边出现的三个点,选择「按项目整理」。
建好后会打开合集页面。看到页面后跟我说「好了」。
Wait for「好了」/ the collection page. Same iab tab: read the address bar.
It must look like https://chatgpt.com/g/g-p-…/project. If it does not,
ask them to open that project until it does. Then:
c2c session set -w <ws> --mode project --project-url <url> --connector-name "<connectorName>".
On that same collection page only, open 右上角 … → 项目设置.
Do not click 分享. Do not add 来源 / files.
- 记忆: 仅限项目记忆 (project-only). Leave 库访问权限 disabled.
- 指令: paste Project instructions below (fill
{{…}} from
workspace_info / setup). Use the exact connectorName from setup.
Never write the public / temporary address into 指令.
Save and close settings.
Still on the collection page, create the first chat with the on-page
composer, then boot + workspace_info as in setup step 5. Save the chat URL.
Project instructions (paste into 项目设置 → 指令)
You are the planning and review layer for one local workspace. Codex executes.
This Project is bound only to:
- Workspace name: {{workspace_name}}
- Kind: {{project_type}} ({{languages}} / {{frameworks}})
- Connector (use this one only): {{connector_name}}
When you call tools, use ONLY that connector. Do not use any other
Codex with ChatGPT connector. If workspace_info names a different
workspace, stop. Do not plan. Do not use this Project's memory.
Read code, git, diffs, and any released command output through that
connector. Never ask anyone to paste file bodies, diffs, or logs. After
EXECUTED, call execution_output (list, then read) when a readable item
exists; if status is restricted, review from git instead. Never upload
the repo into this Project's files or sources.
When facts conflict, trust this order:
1. Current code from the connector
2. A HANDOFF in this chat (this task's goal, progress, next step)
3. These instructions
4. This Project's memory (durable architecture only; stale memory loses)
This Project's memory is only for this workspace. On HANDOFF, trust the
brief, re-read code through the connector, and resume at NEXT_EXPECTED_STEP.
Be substantive: why, which file, what to test. No empty one-liners and
no 40-step epics. Use C2C control messages.
Workflow: coding task("使用 Codex with ChatGPT 完成 XXX")
Protocol states sent to ChatGPT: INIT → PLAN → EXECUTING → EXECUTED → REVIEW → (PLAN | DONE | BLOCKED).
Local checkpoint states (session only, never a ChatGPT STATE: line):
INIT, PLAN_RECEIVED, EXECUTING, EXECUTED_LOCAL, EXECUTED_SENT, DONE, BLOCKED.
Do not invent STATE: RESUME. If the original chat is gone, send HANDOFF.
All control messages start with [C2C]. Keep Codex→ChatGPT messages under 1 KB.
ChatGPT's replies are expected to be substantive (see step 3). Docs: docs/protocol.md.
c2c tunnel status -w <workspace> --json. If needsChoice, follow
Connection choice first (existing installs: ask once, then remember).
Then c2c doctor -w <workspace> --json (auto-repairs). Doctor gate: if local
is not green, do not open ChatGPT and do not send INIT. If
namedRepair.needed is true, tell the user namedRepair.userMessage, run
c2c tunnel login --json (their browser; Cloudflare exception), then doctor
again. If chatgptRepair.needed is true, tell the user chatgptRepair.userMessage
(one paragraph, no internals), run Workflow: reconnect after address
reclaim, then doctor again and only continue when the gate is green.
Generate task id: c2c_ + 4 random hex chars — unless a checkpoint already
has one (reuse that id; do not mint a second task).
c2c session -w <workspace> --json. Open ChatGPT on the same iab tab
per Conversation management for conversation.mode (foreground +
markHandoff). long-chat: saved chat, or https://chatgpt.com/ if none.
project: this thread's chat URL, or the collection page for a new chat,
or Bind Project if projectReady is false. On a NEW conversation
confirm Chat mode (In-app browser §7), then send the boot prompt from
docs/protocol.md §Boot Prompt and the workspace_info check (name the
exact connectorName). Confirm the reply names the current workspace
before saving the session URL. Do not use the browser to re-read code MCP
already provides. After sending a control message, wait per
In-app browser §8.
Resume from session.checkpoint before any INIT. Missing checkpoint
(legacy session): continue as a normal new/continued loop. A browser/js
timeout is not a lost task — claim the original tab; do not INIT, re-run,
or resend EXECUTED just because a wait timed out.
EXECUTED_SENT + waitingFor=GPT_REVIEW: do not INIT, do not re-run,
do not resend EXECUTED. Stay on the saved chat and wait for review. If
that chat 404s: HANDOFF from checkpoint fields (no logs), then wait.
EXECUTED_LOCAL: local work is done; only send EXECUTED (record first
if this iteration has no record yet). Do not re-run.
EXECUTING: not finished. Continue the current PLAN if you still have
it; otherwise HANDOFF and ask ChatGPT to restate the last PLAN. Do not
treat it as done and do not INIT a new task.
PLAN_RECEIVED: execute that plan. Do not INIT.
INIT / waitingFor=GPT_PLAN: claim the tab and wait. Do not resend INIT.
DONE: summarize to the user if needed; c2c session set --clear-checkpoint.
BLOCKED: surface ChatGPT's reason; do not INIT.
Never re-pair, never recreate the connector, and never rewrite Project
instructions just to resume.
Send INIT with the user's goal (skip when the checkpoint says not to):
[C2C]
STATE: INIT
TASK_ID: c2c_f81a
ITERATION: 0
GOAL:
<user's goal, one paragraph>
INSTRUCTION:
Inspect the connected workspace through the Codex with ChatGPT MCP connector.
Produce a C2C PLAN message.
Confirm the INIT message is visibly in that ChatGPT conversation (one cheap
DOM check). If the page is Retry-only, recover per In-app browser §7
first. Do not write the waiting checkpoint, and do not wait for PLAN, until
that message is visible.
Then:
c2c session set -w <ws> --task <id> --iteration 0 --state INIT --protocol-state INIT --waiting-for GPT_PLAN --goal "<short goal>" --next-step "wait for PLAN"
3. Wait for ChatGPT's STATE: PLAN reply (In-app browser §8 — short DOM
checks, same tab; do not treat a 5-minute browser timeout as failure).
Read GOAL/ACTIONS/TESTS/SUCCESS_CRITERIA.
A good PLAN also carries RATIONALE and concrete natural-language edit
suggestions (which file, what to change, why). If the reply is a bare
one-liner with no rationale or file-level guidance, ask once:
"Please expand the plan with rationale and concrete per-file suggestions."
Then:
c2c session set -w <ws> --protocol-state PLAN_RECEIVED --waiting-for none --next-step "execute PLAN"
4. Execute the plan yourself with your own harness (your tools, your judgment;
ChatGPT does not micro-manage tool calls).
Before you start:
c2c session set -w <ws> --protocol-state EXECUTING --waiting-for none --next-step "finish PLAN then record"
5. Record the execution so ChatGPT can read it via MCP. Metadata always:
c2c record -w <ws> --task c2c_f81a --iteration 1 --changed-files "src/a.ts,src/b.ts" --tests "27 passed" --exit-status ok
If this iteration ran a test / build / lint / typecheck command, also
pass that command's output. Write stdout/stderr to a local temp file first,
then:
c2c record … --command "pnpm test" --output-file <temp> --exit-code <n>
Record both success and failure. Do not record shell history, .env,
keys, or unrelated dumps. Never paste that file (or any log) into ChatGPT.
If the CLI says the output was not released, still send EXECUTED; ChatGPT
reviews from git. Then:
c2c session set -w <ws> --iteration 1 --state EXECUTED --protocol-state EXECUTED_LOCAL --waiting-for none --next-step "send EXECUTED"
6. Send EXECUTED (no diffs, no logs). Tell ChatGPT to use MCP, including
execution_output when a readable item exists:
[C2C]
STATE: EXECUTED
TASK_ID: c2c_f81a
ITERATION: 1
RESULT:
Execution finished.
CHANGED_FILES:
4
TESTS:
27 passed
Please independently inspect the workspace and current git diff through MCP.
If execution_output lists a readable item for this iteration, list then read it.
If status is restricted, ignore it and review from git_diff.
Then:
c2c session set -w <ws> --protocol-state EXECUTED_SENT --waiting-for GPT_REVIEW --next-step "wait for PLAN or DONE"
7. ChatGPT reviews via MCP (git_diff, read_file, test_status,
execution_output) and replies DONE / PLAN (next iteration) / BLOCKED.
8. Loop. Respect maxIterations (.c2c.json, default 12). At the limit, pause and ask
the user: "已完成 12 轮协作,仍有未解决问题,是否继续?"
9. On DONE: summarize the result to the user in plain language.
c2c session set -w <ws> --state DONE --clear-checkpoint
10. On BLOCKED: read ChatGPT's reason, fix what you can, or surface the single
decision the user must make.
c2c session set -w <ws> --protocol-state BLOCKED --waiting-for USER --known-issues "<short reason>"
Workflow: disconnect("断开 ChatGPT")
c2c unpair -w <workspace> (revokes all tokens immediately).
- Optionally remove the connector on the same iab tab via
https://chatgpt.com/plugins (foreground + markHandoff). Only touch
this workspace's connectorName.
- Tell the user: "已断开 ChatGPT 对该项目的访问。"
Workflow: reconnect after address reclaim(全关掉以后地址失效)
This is the normal case when the user quit Codex / the terminal / the machine:
the previous public address is gone. Doctor already started a new one.
connectorAction: "update" means Delete + create again — not Reconnect.
c2c doctor --json will look like:
{ "chatgptRepair": { "needed": true, "connectorAction": "update", "connectorName": "...", "userMessage": "...", "mcpUrl": "...", "pages": { ... } } }
- Tell the user exactly
chatgptRepair.userMessage. Then you repair. Do not
ask them to click around ChatGPT unless a login wall appears. Do not open
the C2C chat and do not send [C2C] until this repair finishes and a
follow-up doctor is green. Never "try a message first to see if it works".
Reuse c2c prefs --json. Do not re-ask setup mode. If setupMode is
manual, use Guided manual ChatGPT setup (chosen) instead of automating.
- Same one iab tab as setup (foreground + markHandoff). Settings URLs only
until Connected — never hunt menus:
- 开发人员模式: skip
https://chatgpt.com/#settings/Security when
developerModeEnabled is true. If create/delete then says developer
mode is required, open it, enable, c2c prefs set --developer-mode.
- 插件总管(只用来 Delete):
https://chatgpt.com/plugins
- 加插件(Delete 之后必走):
https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins
- Operate ONLY on
chatgptRepair.connectorName. Never touch another
workspace's connector.
- If that exact name exists on the plugins hub: Delete it. Confirm the
delete if ChatGPT asks. Never click Reconnect, Refresh, Connect, or
Edit on the old card — the old Server URL is dead and the page will
hang on "This site cannot be reached".
- Then
goto the 加插件 URL and create that same connectorName
(do not invent a second name):
- Description:
Securely connect ChatGPT to the current Codex workspace for planning and review.
- Server URL:
chatgptRepair.mcpUrl
- Authentication: OAuth
Then Connect / Authorize. Only then run
c2c pair --json and type that
code. Continue as soon as it is Connected — do not wait for 8 tools on
the settings page.
- If the name is already gone, skip Delete and only create.
c2c doctor --json again. Same tab: only after the Doctor gate is green,
reopen the chat this Codex thread was already using (session.url /
the URL you saved earlier in THIS thread). Do not rewrite Project
instructions — they store the connector name, which did not change.
In that same chat, send the workspace_info check from setup step 6
(exact connectorName). Doctor green is not enough: the old conversation
may still be bound to the deleted connector.
- If the reply names this workspace: continue there. Save the URL if needed.
- If workspace_info fails, times out, or cannot read the name: do not
keep retrying that old URL. project → collection page, new chat in this
Project, boot + HANDOFF from
session.checkpoint (no logs) +
workspace_info, then c2c session set --url only after the name matches.
long-chat → Conversation management switch, same checks. Keep the old
saved URL until the new chat passes.
- If the ChatGPT conversation was lost: same as the failure path in step 4.
No file re-uploading (the workspace lives in MCP). If tools point at
the wrong connector, open 项目设置 and confirm 指令 still names
connectorName (never paste the new public address).
Workflow: repair(anything looks broken)
c2c doctor -w <workspace> --json. Doctor gate: do not open ChatGPT / send
[C2C] until local is green, except reconnect settings pages.
- If
namedRepair.needed, tell the user namedRepair.userMessage, run
c2c tunnel login --json, then doctor again. Do not Delete the connector.
- If
chatgptRepair.needed, follow reconnect after address reclaim, then
doctor again.
- Otherwise apply the recovery map. Only involve the user for login / 2FA /
CAPTCHA — one action.
Recovery map
| Symptom |
Action |
| Bridge not running |
c2c start (doctor does this automatically) |
| Tunnel dead / URL unreachable / 全关掉后连接失效 |
c2c doctor → if namedRepair.needed, login to Cloudflare and doctor again (do not Delete). If chatgptRepair.needed, tell the user the message, then Delete THIS workspace's connector only (connectorName) and create it again. Never Reconnect. After recreate, re-check workspace_info in the saved chat; if it still fails, new chat in the same Project (or long-chat switch) + HANDOFF. |
| Collection page shows only Retry |
Same iab tab: Retry once, then open the last working chat and click its Project link. Do not write INIT/EXECUTED waiting checkpoints until the message is visible. |
| ChatGPT says tool call failed / 401 |
token expired or revoked → re-pair (new pairing code + authorize) |
| Pairing code rej |
|
…(truncated)
1---2name: codex-with-chatgpt3description: Use ChatGPT (web) as the planning and review brain for Codex coding sessions, while Codex keeps full execution ownership. Use when the user says "使用 Codex with ChatGPT ..." / "Set up Codex with ChatGPT" / "用 ChatGPT 规划", when they ask to connect ChatGPT to the current workspace, disconnect it, or run a task through the ChatGPT planning loop.4---56# Codex with ChatGPT78ChatGPT thinks. Codex works.910You (Codex) own execution: editing, shell, git, tests, recovery.11ChatGPT owns high-level reasoning: understanding, planning, review, debug strategy.12The C2C Bridge gives ChatGPT read-only MCP access to the current workspace, so13control messages between you and ChatGPT stay tiny (< 1 KB) — ChatGPT pulls14whatever data it needs by itself.1516**Golden rules**17181. NEVER paste file contents, diffs, or logs into ChatGPT. ChatGPT reads them through MCP.192. NEVER show the user technical internals (MCP, OAuth, PKCE, tunnel, ports, localhost).20 Speak in terms of "连接 ChatGPT / 安全连接 / 配对". The only exception is the21 **guided manual ChatGPT setup** below: expose only the exact settings22 field labels/values the user must enter, without explaining internals.233. The pairing code is the ONLY credential you may ever type into a browser.24 Never touch OAuth tokens, cookies, or session storage.254. If something fails, run `c2c doctor` and repair silently. Only involve the user26 for logins, CAPTCHA, 2FA, explicit consent screens, or **guided manual27 ChatGPT setup** below — and then give them ONE action.28 Before the first ChatGPT connection on this machine, `c2c prefs --json`:29 - `setupMode` missing: tell the user exactly `setupChoicePrompt`, wait for30 「1」or「2」, then `c2c prefs set --setup-mode auto|manual --json`.31 Do not start ChatGPT configuration until they answer. Do not guess.32 - `setupMode` is `manual`: skip automatic ChatGPT settings. Use guided33 manual from the start (chosen, not a failure).34 - `setupMode` is `auto`: automatic browser setup. Two explicit failures of35 the same configuration step after repair then enter guided manual.36 A browser/js timeout, a page still loading/generating, or waiting for37 user login/2FA does NOT count as a failure. Do not change the saved38 `setupMode` when falling back.39 `developerModeEnabled: true` means skip `#settings/Security` until a40 connector create fails because developer mode is required. Then open41 that page, enable it, and `c2c prefs set --developer-mode --json`.42 These prefs are for this machine, not per workspace. Do not ask again43 on reconnect or a second repo. A new computer (empty prefs) asks/checks44 once.455. ALWAYS use the built-in in-app browser (iab) for every ChatGPT step.46 Follow **In-app browser (ChatGPT)** below. NEVER Computer Use (no47 screenshot-click). NEVER launch or control a third-party/external browser48 (Chrome, Safari, Edge…), and never use `open <url>` to hand off to one.49 - The ONLY exception: the user explicitly says the Cloudflare login must use50 their own browser session — that single Cloudflare login step may go through51 their browser; everything else stays in the built-in browser.52 - If the user asks to run ChatGPT in their own browser, refuse politely and53 explain: "Codex 需要持续调用 ChatGPT 和配置连接,这会频繁操作页面,可能影响54 你浏览器的正常使用。ChatGPT 只能跑在内置浏览器里。" Only if the user replies55 with an explicit "我愿意承担影响" may you proceed in their browser; otherwise56 keep ChatGPT in the built-in browser, every time they ask.576. Conversation reuse depends on `c2c session --json` → `conversation.mode`58 (see Conversation management). Do not invent a second mode.59 - **long-chat** (legacy session file, or the user opted out): ONE ChatGPT60 conversation per workspace. Never silently start a new chat.61 - **project** (new workspaces, or an existing workspace that opted in):62 ONE ChatGPT Project (collection) per workspace. Same Codex conversation63 reuses the ChatGPT chat URL saved in THIS thread. A new Codex64 conversation opens a new chat from the Project collection page — never65 `goto` `https://chatgpt.com/` to create it, and never reuse another66 Codex conversation's chat URL just because `session.url` exists.67 Each workspace also has exactly ONE ChatGPT connector. Do not create a68 second connector for the same workspace. Other workspaces may have their69 own connectors — never edit those.707. After first-time setup, never ask the user to approve writing C2C's local71 settings directory. Run `c2c sandbox-allow --json` (idempotent). If it fails72 with EPERM / Operation not permitted, request elevated permissions and retry73 ONCE. After `{ "alreadyAllowed": true }` or `{ "added": true }`, stay silent.748. ChatGPT pages: only the URLs in **In-app browser (ChatGPT)**. Never start75 from chatgpt.com and click through menus.769. **Doctor gate.** After `c2c doctor --json`, do not `goto` ChatGPT and do not77 send `[C2C]` until local is green — except the reconnect settings pages when78 `chatgptRepair.needed` is true. Not green:79 - `report.bridge.ok` is not true80 - `report.mcp.ok` is not true (unauthenticated local `/mcp` must be 401)81 - sandbox / state-dir write failed (EPERM)82 - this workspace used to have a public URL and the tunnel is down83 - `chatgptRepair.needed` is true (fix the connector first, then doctor again)84 - `namedRepair.needed` is true (user must log in to Cloudflare, then doctor again.85 Do not Delete the ChatGPT connector — the address did not change)86 - `report.bridge` says 状态无法确认: the local bridge may still be running.87 Do not `c2c start`, do not Delete the connector, do not treat it as88 `chatgptRepair`. Wait and run doctor again.89 If doctor is already green and `chatgptRepair.needed` is false, do not90 `c2c restart`, do not start a second tunnel, and do not Delete the91 connector. ChatGPT/IAB-only errors are not permission to churn the92 public address.93 A ChatGPT-side 401 after a sent message is different: repair then, do not94 treat it as permission to skip this gate next time.9596## In-app browser (ChatGPT)9798Official skill: `control-in-app-browser`. These C2C rules override defaults99that close the tab, hide the window, or stall on the settings page.1001011. **Surface.** Once per Codex session: `setupBrowserRuntime()`, then102 `const iab = await agent.browsers.get("iab")`. Reuse `iab`. Do not re-read103 `documentation()` if it is already bound. Never `getDefault()`, `getForUrl()`,104 or Computer Use.1051062. **One tab.** Create the ChatGPT tab once (`tabs.new()`). After that, only107 `tab.goto(...)` to switch URLs. If the tab still exists, claim it — never108 open a second ChatGPT tab. Do not `goto` the URL you are already on.1091103. **Foreground + keep (standby).** Right after opening or claiming the tab:111 - `await (await iab.capabilities.get("visibility")).set(true)` — first-time112 setup and ChatGPT chatting stay in front of the user so they can watch.113 - `await tab.markHandoff()` immediately, then again at the start and end of114 every turn. After setup succeeds or the C2C chat is open, also115 `await tab.markDeliverable()`.116 Never close this tab. Finished, waiting for the user, or timed out: leave it117 marked (standby). Do not let default turn cleanup close it.1181194. **URLs only** (same tab, `goto` — never hunt menus):120 - 开发人员模式: `https://chatgpt.com/#settings/Security`121 (skip when `c2c prefs --json` has `developerModeEnabled: true`)122 - 插件总管: `https://chatgpt.com/plugins`123 - 加插件: `https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins`124 - 新对话 (long-chat only, and only if no saved chat): `https://chatgpt.com/`125 - Saved C2C chat: `conversation.chatUrl` / `session.url` (long-chat, or126 the chat already bound in THIS Codex conversation)127 - Saved Project collection: `conversation.projectUrl`128 (`https://chatgpt.com/g/g-p-…/project`)129 Never click Reconnect / Refresh on an existing connector. The old address is130 dead and that page hangs on "This site cannot be reached". When the address131 changed: Delete THIS workspace's `connectorName` only, then create it again132 via the 加插件 URL (same name, new Server URL). Do not put that public133 address into Project instructions — write the connector **name** only.1341355. **Do not wait for 8 tools** on the settings page. "Connected" / authorize136 success / pairing accepted is enough. Confirm tools in the conversation with137 `workspace_info`.1381396. **Batch.** Fill a known form in one Playwright / `js` script when you can.140 After an action, one cheap DOM check. Do not screenshot-poll.1411427. **One conversation, Chat mode.** The first ChatGPT chat is the C2C143 conversation. Chat and Work (聊天 / 工作) are separate: a Work conversation144 cannot become Chat. On every NEW conversation, if a Chat/Work switcher is145 visible (often top-left), confirm **Chat** is selected before the boot146 prompt. If it is Work, do not continue there — Switch to a new Chat147 conversation (HANDOFF). If no switcher is visible, do not hunt menus; continue.148 Send the boot prompt and the workspace_info check in that Chat conversation.149 Confirm the reply names the current workspace **before** saving or replacing150 the session URL. If validation fails, keep the old saved URL. Do not open a151 throwaway verify chat and later another C2C chat.152153 A collection or chat page that shows only `Retry` / `重试` is a navigation154 error, not generation and not a pairing failure. Reuse the same iab tab.155 Try Retry once. If it stays Retry-only, `goto` the last working chat URL156 from this thread (or `session.url` if that is the only saved chat), then157 click the on-page `Open … project` / `打开“… ”项目` link — that same-site158 hop is allowed. Do not treat the URLs-only rule as forbidding this link.159 On the collection, require the project chat list and new-chat composer160 before continuing. Keep the old saved URL/checkpoint until the replacement161 chat passes workspace_info. Do not `session clear`. Do not use Computer Use.1621638. **Wait for a ChatGPT reply (do not hold one long browser wait).** After you164 send INIT, EXECUTED, boot, or the workspace_info check: `markHandoff`, keep165 the tab foreground, and stay in this same task. Do not `waitFor` 5 minutes166 and do not screenshot-poll. Every 20–30 seconds, one cheap DOM check:167 - still generating → wait again (do not type, do not resend);168 - `STATE: PLAN` / `DONE` / `BLOCKED` / the verify workspace name → read it169 and continue the existing protocol;170 - visible error → repair; do not start a new chat.171 A browser/js timeout is not failure. Claim the same tab, read the page, keep172 standby. If ChatGPT is still thinking, keep polling. Never open a second173 tab and never resend INIT/EXECUTED just because a wait timed out.174175## Locations176177- The codex-with-chatgpt checkout lives at: `<ACTUAL_CHECKOUT_PATH>`178 (installer/update MUST replace this line in the installed Skill with the user's actual checkout path.)179- CLI: let `<checkout>` mean the path on the previous line; run180 `node "<checkout>/bin/c2c.js" <command>` (or `c2c <command>` if globally linked).181 All commands support `--json` for parsing.182- If the checkout has no `node_modules` or no `dist/`, first run183 `corepack pnpm install && corepack pnpm build` inside it.184- For commands that act on the user's project (`setup`, `doctor`, `session`,185 `restart`, `start`, `stop`, `status`, `pair`, `unpair`, `logs`, `workspace`,186 `record`, `tunnel status`, `tunnel choose`), pass `-w <workspace root>`187 (the project the user is working on, NOT the c2c repo).188- Do not add `-w` to machine-wide commands: `update-check`, `sandbox-allow`,189 `prefs`, `tunnel login`. They still accept and ignore `-w`, so a leftover190 flag must not fail the command.191192## Daily update check193194At the START of every workflow below (before anything else), run these two195commands (both are cheap / cached; never mention them unless an update exists):1961971. `c2c update-check --json` (do not pass `-w`)1982. `c2c sandbox-allow --json` (do not pass `-w`) — writes the C2C state directory into Codex's199 sandbox `writable_roots` (macOS: `~/Library/Application Support/codex-with-chatgpt`;200 Windows: `%LOCALAPPDATA%\codex-with-chatgpt`; config file is201 `~/.codex/config.toml` on both, or `%USERPROFILE%\.codex\config.toml` on Windows).202 If already allowlisted, this is a no-op and does not trigger elevation.203204- `{ "updateAvailable": false }` → continue silently. Never mention the check.205- `{ "updateAvailable": true }` → tell the user one line:206 "检测到 Codex with ChatGPT 有新版本,我先更新一下(约 1 分钟),随后继续你的任务。"207 Then run the update workflow below, and CONTINUE the original task afterwards.208209## Workflow: update("更新 Codex with ChatGPT",or triggered by the daily check)210211Inside the checkout directory (see Locations):2122131. `git pull --ff-only` (if it fails due to local edits: `git stash && git pull --ff-only`).2142. `corepack pnpm install && corepack pnpm build`.2153. Re-install the Skill: copy `skill/SKILL.md` to216 `~/.codex/skills/codex-with-chatgpt/SKILL.md`, then fix the "checkout lives at:"217 line in the copy to the actual checkout path.2184. `c2c sandbox-allow --json` (so existing installs pick up the sandbox allowlist),219 then `c2c restart -w <workspace>` so the bridge runs the new code, then220 `c2c update-check --force --json` to refresh the cache (should now report up to date).2215. Tell the user "✓ 已更新到最新版本" — then resume whatever task triggered this.222 (The updated SKILL.md takes effect from the next Codex session; that's expected.)223224## Connection choice (once per workspace)225226Ask this **before** the public address exists (`c2c setup` / first `doctor --fix`227that starts a tunnel). Do not mention tunnels, wrangler, DNS, or hostnames.228Speak only of 临时地址 / 固定域名 / 登录 Cloudflare.2292301. `c2c tunnel status -w <workspace> --json`2312. If `needsChoice` is false: do not ask again.2323. If `needsChoice` is true: tell the user exactly `userPrompt` and wait.233 - 没有账号 / 没有域名 / 临时 / 不用 →234 `c2c tunnel choose -w <ws> --mode quick --json`235 - 有域名(例如 example.com)→ first tell them `loginPrompt`, then236 `c2c tunnel choose -w <ws> --mode named --zone <domain> --json`.237 This may open the user's own browser (the Cloudflare exception in238 Golden rule 5). Wait until the command finishes.239 If they said they have an account but gave no domain: ask once for the240 domain. If the command returns `need: "zone"`, ask once and retry.241 If `fallback` is true: tell them `userMessage` and continue on the242 temporary address. Do not retry named unless they ask.2434. Never put connection credentials in the project. The CLI stores them in244 the C2C state directory.245246## Workflow: first-time setup("使用 Codex with ChatGPT 完成首次配置")2472481. Detect prerequisites yourself: `node --version` (>= 20), and check `cloudflared`.249 - If cloudflared is missing on macOS run `brew install cloudflared`; on Windows use250 `winget install Cloudflare.cloudflared`. Do this yourself; don't ask.2512. If the c2c repo has no `node_modules`, run `pnpm install && pnpm build` in it.2523. Run `c2c sandbox-allow --json`, then **Connection choice**, then253 `c2c setup -w <workspace> --json`.254 `sandbox-allow` edits Codex `config.toml` only — it adds C2C's state directory255 to `[sandbox_workspace_write].writable_roots` so later chats can write logs256 without elevation. If the write is denied, request approval and retry once.257 → returns `{ mcpUrl, pairingCode, workspaceName, connectorName, ... }`.258 `connectorName` is this workspace's plugin title (legacy installs stay259 `Codex with ChatGPT`; additional workspaces get `Codex with ChatGPT · <name>`).260 Pairing codes expire in ~5 minutes. Do not mint one until the ChatGPT261 Authorize / pairing form is on screen: run `c2c pair --json` then type262 that code immediately. Doctor does not pre-mint a code.2634. `c2c prefs --json` (this machine, not this workspace).264 - If `setupMode` is null: tell the user exactly `setupChoicePrompt`. Wait265 for「1」or「2」. Then `c2c prefs set --setup-mode auto` or `--setup-mode manual`.266 Do not open ChatGPT settings and do not start automatic configuration267 until they answer. Do not default to auto.268 - If they later ask to switch: same `c2c prefs set --setup-mode` command.269 Do not re-ask on a later workspace or on reconnect.270 - `setupMode: "manual"`: skip step 5's automatic ChatGPT settings. Go to271 **Guided manual ChatGPT setup** (chosen). Opening line:272 `接下来用手动教学配置。一次只需要做一个操作。`273 Do not say 自动配置没有成功.274 - `setupMode: "auto"`: continue with step 5. Keep the two-failure fallback.2755. Open ChatGPT on the ONE iab tab (see **In-app browser**). Foreground +276 markHandoff immediately. Same tab, `goto` only:277 - 开发人员模式: skip `https://chatgpt.com/#settings/Security` when278 `developerModeEnabled` is true. Otherwise open it, enable 开发人员模式279 ("Developer mode") if it is off, then `c2c prefs set --developer-mode`.280 Never record it as off. If creating the connector later says developer281 mode is required, open this page, enable it, save `--developer-mode`,282 and retry create — do not skip that recovery.283 - 已有该 `connectorName`: `https://chatgpt.com/plugins` — Delete it (never284 Reconnect). Then `goto` the 加插件 URL below.285 - 还没有 / 刚删掉: `https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins`286 Operate ONLY on `connectorName` from step 3:287 - If that exact name exists: Delete it, then create it again. Never288 Reconnect, never edit-in-place, never open the old Server URL.289 - If it does not exist: create one with that exact name.290 - Never rename, delete, or edit a connector that belongs to another workspace.291 - Description: `Securely connect ChatGPT to the current Codex workspace for planning and review.`292 - Server URL: the `mcpUrl` from step 3293 - Authentication: OAuth294 Fill the known form in one script when you can. Then Connect / Authorize.295 Only then run `c2c pair --json` and type that code. As soon as it shows296 Connected / authorized / pairing accepted, continue — do NOT wait for 8297 tools on this page.2986. Same tab: open the first C2C chat per **Conversation management**299 (Project collection for a new workspace; `https://chatgpt.com/` only300 in long-chat). Confirm Chat mode per **In-app browser** §7 (if it is Work,301 open a new Chat conversation instead). Send the boot prompt from302 `docs/protocol.md` §Boot Prompt, then (same chat) send:303 `Use the "<connectorName>" connector: call workspace_info and read hello-style top-level file. Reply with the workspace name.`304 Confirm the reply matches `workspaceName` (wait per **In-app browser** §8).305 Only then save the chat URL with `c2c session set` (see Conversation306 management). If the name does not match, do not save. markDeliverable.3077. Report to the user exactly in this shape (no internals):308309```310Codex with ChatGPT311312✓ 当前项目已识别313✓ Workspace Bridge 已启动314✓ 安全连接已建立315✓ ChatGPT 已连接316✓ 文件读取测试通过317318Ready.319```320321If a login wall appears (ChatGPT, Cloudflare): stop, tell the user the ONE thing322to do ("请登录 ChatGPT,完成后告诉我'好了'"), then continue.323324### Guided manual ChatGPT setup325326Enter this path when `setupMode` is `manual` (chosen at the start), or when327automatic ChatGPT browser configuration fails twice at the same explicit328setup/reconnect step after `c2c doctor` / repair. Do NOT enter the failure329path for a browser/js timeout without a visible error, a page that is330still loading/generating, or while waiting for login / 2FA / CAPTCHA.331A chosen manual path does not wait for those two failures.332333Stop automating ChatGPT settings. Keep the current local C2C state and the334current `mcpUrl`, `pairingCode`, `workspaceName`, and `connectorName`. Do not335silently fall back to Codex-only execution and do not permanently disable C2C.336Do not change the saved `setupMode` when this is a failure fallback.337338Opening line:339340- Chosen (`setupMode: "manual"`): `接下来用手动教学配置。一次只需要做一个操作。`341- Failure fallback: `自动配置没有成功,我来带你手动完成。一次只需要做一个操作。`342343Then guide ONE action at a time, waiting for the user to say「好了」before the344next action:3453461. If `developerModeEnabled` is not true: ask them to open347 `https://chatgpt.com/#settings/Security` and enable 开发人员模式. After they348 say「好了」, `c2c prefs set --developer-mode`. If it is already remembered,349 skip this step.3502. Ask them to open `https://chatgpt.com/plugins`. If the exact `connectorName`351 exists, delete only that connector. Never ask them to touch another workspace's connector.3523. Ask them to open353 `https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins`354 and create the exact `connectorName` with:355 - Description: `Securely connect ChatGPT to the current Codex workspace for planning and review.`356 - Server URL: the current `mcpUrl`357 - Authentication: OAuth3584. Ask them to Connect / Authorize. Then run `c2c pair --json` and give them359 only that pairing code. If it expires before they finish, run pair again.3605. When they report Connected / authorized / pairing accepted, resume the normal361 setup/reconnect flow at its ChatGPT verification step. If automatic browser362 verification then hits the same explicit failure twice, stop and report the363 exact failed step; do not loop indefinitely and do not continue without C2C.364365## Conversation management366367`c2c session -w <ws> --json` → `{ session, conversation }`.368`conversation.mode` is the only switch. Missing / legacy files with a chat URL369and no Project stay **long-chat**. Do not ask those users to migrate. If they370later say they want a Project, run **Bind Project**. A brand-new workspace371(no session file) is **project**.372373Never match a Project or a chat by display name. Never upload the repo to374Project sources. Never click 分享 / Share. Do not rename ChatGPT chats.375376### long-chat (do not rewrite this path)377378ONE ChatGPT conversation per workspace. Same as before.379380- **Find it**: if `conversation.reuseSavedChat` and `conversation.chatUrl`,381 `goto` that URL (foreground + markHandoff) and continue there.382- **Save it**: after boot + workspace_info, and the reply names this workspace,383 `c2c session set -w <ws> --mode long-chat --url <url> --title "C2C <workspace name>"`.384 If the name does not match, do not overwrite a previously saved URL.385- **Update it**: after each EXECUTED/DONE,386 `c2c session set -w <ws> --task <id> --iteration <n> --state <STATE>`387 plus checkpoint flags from the coding workflow (`--protocol-state`,388 `--waiting-for`, `--goal`, `--next-step`, `--known-issues`, or389 `--clear-checkpoint` on DONE). Do not put logs or diffs in those fields.390- **Switch it** ONLY when (a) the user asks for a new chat, (b) the current391 chat visibly lags, or (c) this conversation is Work. Then:392 1. Same iab tab: `goto` `https://chatgpt.com/`, confirm Chat mode393 (**In-app browser** §7), then send the boot prompt.394 2. Send a HANDOFF (`docs/protocol.md`) — goal, progress, state, issues,395 next step. Never paste files.396 3. workspace_info check; only then `c2c session set --url`. On failure,397 leave the old saved URL unchanged.398- Saved chat 404s: treat as a switch. Reconstruct HANDOFF from399 `session.checkpoint` (goal, progress, issues, next step). If there is no400 checkpoint, use `task` / `iteration` / `lastState` and `execution_summary`401 metadata only. Never paste logs or output bodies.402403### project (new workspaces)404405One ChatGPT Project per workspace. Mapping:4064071. Same Codex conversation (this thread still has context) → same ChatGPT408 chat URL. `goto` that URL directly. Do not open the collection first.4092. Same workspace, a **new** Codex conversation → new ChatGPT chat from the410 collection page (`conversation.projectUrl`). Ignore `session.url` unless411 you already saved it earlier in THIS Codex thread.4123. Different workspace → different Project and different connector.413414**Open a chat in this Codex thread**415416- If you already saved a ChatGPT chat URL earlier in THIS Codex conversation:417 `goto` that URL. Continue. No new chat. No HANDOFF.418- Else if `conversation.projectReady`: `goto` `conversation.projectUrl`.419 On that page, use the on-page composer (「{项目名}中的新聊天」 / "New chat420 in …"). Do not use the sidebar and do not `goto` `https://chatgpt.com/`.421 Confirm Chat mode (**In-app browser** §7). Boot prompt, then workspace_info422 with the **exact** `connectorName`. After the reply names this workspace,423 `c2c session set -w <ws> --mode project --project-url <collection> --url <chat> --connector-name "<connectorName>" --title "C2C <workspace name>"`.424 If this Codex thread is continuing a previous C2C task, send HANDOFF right425 after the boot prompt.426- Else: **Bind Project** first.427428**Update it**: same `c2c session set --task / --iteration / --state` as long-chat.429430**Wrong collection**: do not guess another Project. Tell the user the expected431workspace name, ask them to open the right collection, then say「已找到」.432Also offer「继续用长对话」. If they pick long-chat:433`c2c session set -w <ws> --mode long-chat` and use the long-chat path.434If the collection 404s or the new chat is not inside the Project, same choice.435436**Saved chat 404s** (this thread): `goto` the collection, open a new chat437there, boot + HANDOFF from `session.checkpoint` (no logs) + workspace_info,438then save the new chat URL. Keep `--project-url`.439440### Bind Project (user creates the collection once)441442Do this for a new workspace, or when an existing user asks to switch to443Project. Do **not** click the ChatGPT sidebar to create the Project444(Computer Use is forbidden; IAB must not hunt that menu).4454461. Tell the user exactly this (fill in the workspace name):447448```449请在 ChatGPT 里新建一个项目,名字用「<workspaceName>」,记忆请选「仅限项目记忆」。450451如果侧栏里看不到「项目」:把鼠标放在「聊天」上,点右边出现的三个点,选择「按项目整理」。452453建好后会打开合集页面。看到页面后跟我说「好了」。454```4554562. Wait for「好了」/ the collection page. Same iab tab: read the address bar.457 It must look like `https://chatgpt.com/g/g-p-…/project`. If it does not,458 ask them to open that project until it does. Then:459 `c2c session set -w <ws> --mode project --project-url <url> --connector-name "<connectorName>"`.4604613. On that same collection page only, open 右上角 **… → 项目设置**.462 Do not click 分享. Do not add 来源 / files.463 - 记忆: 仅限项目记忆 (project-only). Leave 库访问权限 disabled.464 - 指令: paste **Project instructions** below (fill `{{…}}` from465 `workspace_info` / setup). Use the exact `connectorName` from setup.466 Never write the public / temporary address into 指令.467 Save and close settings.4684694. Still on the collection page, create the first chat with the on-page470 composer, then boot + workspace_info as in setup step 5. Save the chat URL.471472### Project instructions (paste into 项目设置 → 指令)473474```475You are the planning and review layer for one local workspace. Codex executes.476477This Project is bound only to:478- Workspace name: {{workspace_name}}479- Kind: {{project_type}} ({{languages}} / {{frameworks}})480- Connector (use this one only): {{connector_name}}481482When you call tools, use ONLY that connector. Do not use any other483Codex with ChatGPT connector. If workspace_info names a different484workspace, stop. Do not plan. Do not use this Project's memory.485486Read code, git, diffs, and any released command output through that487connector. Never ask anyone to paste file bodies, diffs, or logs. After488EXECUTED, call execution_output (list, then read) when a readable item489exists; if status is restricted, review from git instead. Never upload490the repo into this Project's files or sources.491492When facts conflict, trust this order:4931. Current code from the connector4942. A HANDOFF in this chat (this task's goal, progress, next step)4953. These instructions4964. This Project's memory (durable architecture only; stale memory loses)497498This Project's memory is only for this workspace. On HANDOFF, trust the499brief, re-read code through the connector, and resume at NEXT_EXPECTED_STEP.500501Be substantive: why, which file, what to test. No empty one-liners and502no 40-step epics. Use C2C control messages.503```504505## Workflow: coding task("使用 Codex with ChatGPT 完成 XXX")506507Protocol states sent to ChatGPT: INIT → PLAN → EXECUTING → EXECUTED → REVIEW → (PLAN | DONE | BLOCKED).508Local checkpoint states (session only, never a ChatGPT `STATE:` line):509`INIT`, `PLAN_RECEIVED`, `EXECUTING`, `EXECUTED_LOCAL`, `EXECUTED_SENT`, `DONE`, `BLOCKED`.510Do not invent `STATE: RESUME`. If the original chat is gone, send HANDOFF.511All control messages start with `[C2C]`. Keep Codex→ChatGPT messages under 1 KB.512ChatGPT's replies are expected to be substantive (see step 3). Docs: `docs/protocol.md`.5135140. `c2c tunnel status -w <workspace> --json`. If `needsChoice`, follow515 **Connection choice** first (existing installs: ask once, then remember).516 Then `c2c doctor -w <workspace> --json` (auto-repairs). **Doctor gate:** if local517 is not green, do not open ChatGPT and do not send INIT. If518 `namedRepair.needed` is true, tell the user `namedRepair.userMessage`, run519 `c2c tunnel login --json` (their browser; Cloudflare exception), then doctor520 again. If `chatgptRepair.needed` is true, tell the user `chatgptRepair.userMessage`521 (one paragraph, no internals), run **Workflow: reconnect after address522 reclaim**, then doctor again and only continue when the gate is green.523 Generate task id: `c2c_` + 4 random hex chars — unless a checkpoint already524 has one (reuse that id; do not mint a second task).5251. `c2c session -w <workspace> --json`. Open ChatGPT on the same iab tab526 per **Conversation management** for `conversation.mode` (foreground +527 markHandoff). long-chat: saved chat, or `https://chatgpt.com/` if none.528 project: this thread's chat URL, or the collection page for a new chat,529 or **Bind Project** if `projectReady` is false. On a NEW conversation530 confirm Chat mode (**In-app browser** §7), then send the boot prompt from531 `docs/protocol.md` §Boot Prompt and the workspace_info check (name the532 exact `connectorName`). Confirm the reply names the current workspace533 before saving the session URL. Do not use the browser to re-read code MCP534 already provides. After sending a control message, wait per535 **In-app browser** §8.536537 **Resume from `session.checkpoint` before any INIT.** Missing checkpoint538 (legacy session): continue as a normal new/continued loop. A browser/js539 timeout is not a lost task — claim the original tab; do not INIT, re-run,540 or resend EXECUTED just because a wait timed out.541 - `EXECUTED_SENT` + `waitingFor=GPT_REVIEW`: do not INIT, do not re-run,542 do not resend EXECUTED. Stay on the saved chat and wait for review. If543 that chat 404s: HANDOFF from checkpoint fields (no logs), then wait.544 - `EXECUTED_LOCAL`: local work is done; only send EXECUTED (record first545 if this iteration has no record yet). Do not re-run.546 - `EXECUTING`: not finished. Continue the current PLAN if you still have547 it; otherwise HANDOFF and ask ChatGPT to restate the last PLAN. Do not548 treat it as done and do not INIT a new task.549 - `PLAN_RECEIVED`: execute that plan. Do not INIT.550 - `INIT` / `waitingFor=GPT_PLAN`: claim the tab and wait. Do not resend INIT.551 - `DONE`: summarize to the user if needed; `c2c session set --clear-checkpoint`.552 - `BLOCKED`: surface ChatGPT's reason; do not INIT.553 Never re-pair, never recreate the connector, and never rewrite Project554 instructions just to resume.5552. Send INIT with the user's goal (skip when the checkpoint says not to):556557```558[C2C]559STATE: INIT560TASK_ID: c2c_f81a561ITERATION: 0562563GOAL:564<user's goal, one paragraph>565566INSTRUCTION:567Inspect the connected workspace through the Codex with ChatGPT MCP connector.568Produce a C2C PLAN message.569```570571 Confirm the INIT message is visibly in that ChatGPT conversation (one cheap572 DOM check). If the page is Retry-only, recover per **In-app browser** §7573 first. Do not write the waiting checkpoint, and do not wait for PLAN, until574 that message is visible.575 Then:576 `c2c session set -w <ws> --task <id> --iteration 0 --state INIT --protocol-state INIT --waiting-for GPT_PLAN --goal "<short goal>" --next-step "wait for PLAN"`5773. Wait for ChatGPT's `STATE: PLAN` reply (**In-app browser** §8 — short DOM578 checks, same tab; do not treat a 5-minute browser timeout as failure).579 Read GOAL/ACTIONS/TESTS/SUCCESS_CRITERIA.580 A good PLAN also carries RATIONALE and concrete natural-language edit581 suggestions (which file, what to change, why). If the reply is a bare582 one-liner with no rationale or file-level guidance, ask once:583 "Please expand the plan with rationale and concrete per-file suggestions."584 Then:585 `c2c session set -w <ws> --protocol-state PLAN_RECEIVED --waiting-for none --next-step "execute PLAN"`5864. Execute the plan yourself with your own harness (your tools, your judgment;587 ChatGPT does not micro-manage tool calls).588 Before you start:589 `c2c session set -w <ws> --protocol-state EXECUTING --waiting-for none --next-step "finish PLAN then record"`5905. Record the execution so ChatGPT can read it via MCP. Metadata always:591 `c2c record -w <ws> --task c2c_f81a --iteration 1 --changed-files "src/a.ts,src/b.ts" --tests "27 passed" --exit-status ok`592 If this iteration ran a **test / build / lint / typecheck** command, also593 pass that command's output. Write stdout/stderr to a local temp file first,594 then:595 `c2c record … --command "pnpm test" --output-file <temp> --exit-code <n>`596 Record both success and failure. Do not record shell history, `.env`,597 keys, or unrelated dumps. Never paste that file (or any log) into ChatGPT.598 If the CLI says the output was not released, still send EXECUTED; ChatGPT599 reviews from git. Then:600 `c2c session set -w <ws> --iteration 1 --state EXECUTED --protocol-state EXECUTED_LOCAL --waiting-for none --next-step "send EXECUTED"`6016. Send EXECUTED (no diffs, no logs). Tell ChatGPT to use MCP, including602 `execution_output` when a readable item exists:603604```605[C2C]606STATE: EXECUTED607TASK_ID: c2c_f81a608ITERATION: 1609610RESULT:611Execution finished.612613CHANGED_FILES:6144615616TESTS:61727 passed618619Please independently inspect the workspace and current git diff through MCP.620If execution_output lists a readable item for this iteration, list then read it.621If status is restricted, ignore it and review from git_diff.622```623624 Then:625 `c2c session set -w <ws> --protocol-state EXECUTED_SENT --waiting-for GPT_REVIEW --next-step "wait for PLAN or DONE"`6267. ChatGPT reviews via MCP (`git_diff`, `read_file`, `test_status`,627 `execution_output`) and replies DONE / PLAN (next iteration) / BLOCKED.6288. Loop. Respect maxIterations (`.c2c.json`, default 12). At the limit, pause and ask629 the user: "已完成 12 轮协作,仍有未解决问题,是否继续?"6309. On DONE: summarize the result to the user in plain language.631 `c2c session set -w <ws> --state DONE --clear-checkpoint`63210. On BLOCKED: read ChatGPT's reason, fix what you can, or surface the single633 decision the user must make.634 `c2c session set -w <ws> --protocol-state BLOCKED --waiting-for USER --known-issues "<short reason>"`635636## Workflow: disconnect("断开 ChatGPT")6376381. `c2c unpair -w <workspace>` (revokes all tokens immediately).6392. Optionally remove the connector on the same iab tab via640 `https://chatgpt.com/plugins` (foreground + markHandoff). Only touch641 this workspace's `connectorName`.6423. Tell the user: "已断开 ChatGPT 对该项目的访问。"643644## Workflow: reconnect after address reclaim(全关掉以后地址失效)645646This is the normal case when the user quit Codex / the terminal / the machine:647the previous public address is gone. Doctor already started a new one.648`connectorAction: "update"` means Delete + create again — not Reconnect.649650`c2c doctor --json` will look like:651`{ "chatgptRepair": { "needed": true, "connectorAction": "update", "connectorName": "...", "userMessage": "...", "mcpUrl": "...", "pages": { ... } } }`6526531. Tell the user exactly `chatgptRepair.userMessage`. Then you repair. Do not654 ask them to click around ChatGPT unless a login wall appears. Do not open655 the C2C chat and do not send `[C2C]` until this repair finishes and a656 follow-up doctor is green. Never "try a message first to see if it works".657 Reuse `c2c prefs --json`. Do not re-ask setup mode. If `setupMode` is658 `manual`, use **Guided manual ChatGPT setup** (chosen) instead of automating.6592. Same one iab tab as setup (foreground + markHandoff). Settings URLs only660 until Connected — never hunt menus:661 - 开发人员模式: skip `https://chatgpt.com/#settings/Security` when662 `developerModeEnabled` is true. If create/delete then says developer663 mode is required, open it, enable, `c2c prefs set --developer-mode`.664 - 插件总管(只用来 Delete): `https://chatgpt.com/plugins`665 - 加插件(Delete 之后必走): `https://chatgpt.com/plugins#settings/Connectors?create-connector=true&redirectAfter=%2Fplugins`6663. Operate ONLY on `chatgptRepair.connectorName`. Never touch another667 workspace's connector.668 - If that exact name exists on the plugins hub: **Delete** it. Confirm the669 delete if ChatGPT asks. **Never click Reconnect, Refresh, Connect, or670 Edit** on the old card — the old Server URL is dead and the page will671 hang on "This site cannot be reached".672 - Then `goto` the 加插件 URL and create that **same** `connectorName`673 (do not invent a second name):674 - Description: `Securely connect ChatGPT to the current Codex workspace for planning and review.`675 - Server URL: `chatgptRepair.mcpUrl`676 - Authentication: OAuth677 Then Connect / Authorize. Only then run `c2c pair --json` and type that678 code. Continue as soon as it is Connected — do not wait for 8 tools on679 the settings page.680 - If the name is already gone, skip Delete and only create.6814. `c2c doctor --json` again. Same tab: only after the Doctor gate is green,682 reopen the chat this Codex thread was already using (`session.url` /683 the URL you saved earlier in THIS thread). Do not rewrite Project684 instructions — they store the connector **name**, which did not change.685 In that same chat, send the workspace_info check from setup step 6686 (exact `connectorName`). Doctor green is not enough: the old conversation687 may still be bound to the deleted connector.688 - If the reply names this workspace: continue there. Save the URL if needed.689 - If workspace_info fails, times out, or cannot read the name: do **not**690 keep retrying that old URL. project → collection page, new chat in this691 Project, boot + HANDOFF from `session.checkpoint` (no logs) +692 workspace_info, then `c2c session set --url` only after the name matches.693 long-chat → Conversation management switch, same checks. Keep the old694 saved URL until the new chat passes.6955. If the ChatGPT conversation was lost: same as the failure path in step 4.696 No file re-uploading (the workspace lives in MCP). If tools point at697 the wrong connector, open 项目设置 and confirm 指令 still names698 `connectorName` (never paste the new public address).699700## Workflow: repair(anything looks broken)7017021. `c2c doctor -w <workspace> --json`. Doctor gate: do not open ChatGPT / send703 `[C2C]` until local is green, except reconnect settings pages.7042. If `namedRepair.needed`, tell the user `namedRepair.userMessage`, run705 `c2c tunnel login --json`, then doctor again. Do not Delete the connector.7063. If `chatgptRepair.needed`, follow **reconnect after address reclaim**, then707 doctor again.7084. Otherwise apply the recovery map. Only involve the user for login / 2FA /709 CAPTCHA — one action.710711## Recovery map712713| Symptom | Action |714| --- | --- |715| Bridge not running | `c2c start` (doctor does this automatically) |716| Tunnel dead / URL unreachable / 全关掉后连接失效 | `c2c doctor` → if `namedRepair.needed`, login to Cloudflare and doctor again (do not Delete). If `chatgptRepair.needed`, tell the user the message, then **Delete** THIS workspace's connector only (`connectorName`) and create it again. Never Reconnect. After recreate, re-check `workspace_info` in the saved chat; if it still fails, new chat in the same Project (or long-chat switch) + HANDOFF. |717| Collection page shows only Retry | Same iab tab: Retry once, then open the last working chat and click its Project link. Do not write INIT/EXECUTED waiting checkpoints until the message is visible. |718| ChatGPT says tool call failed / 401 | token expired or revoked → re-pair (new pairing code + authorize) |719| Pairing code rej720721…(truncated)