Metadata-Version: 2.4
Name: codex-mode
Version: 0.1.0a7
Summary: Independent Linux tool to switch Codex ChatGPT and API routes with shared history
Author: henrychi
License-Expression: MIT
Keywords: codex,cli,authentication,benchmark
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: tomlkit<1,>=0.13
Dynamic: license-file

# codex-mode (Linux alpha)

独立的 Codex 鉴权切换工具，不是 OpenAI 官方产品。让 ChatGPT 登录与
Responses API 路由使用同一个 CODEX_HOME，保留聊天历史。

当前版本 `0.1.0a7` 是 PyPI 候选发布包，尚未上传。Linux / Python 3.11+，
已验证 Codex 0.153.4 / 0.154.0；不是 OpenAI 官方产品。

新增命名 ChatGPT 账号和隔离测速：

```bash
codex-mode login --account second       # 保存登录，不立即启用
codex-mode accounts
codex-mode account-save --account first # 服务停止后，保存当前登录
codex-mode chatgpt --account second     # 停止任务、暂停 goal、断开 Desktop 后切换
codex-mode speed                        # hello，gpt-5.6-sol / medium，各一次
codex-mode speed --rounds 3 --timeout 60
```

测速消耗额度/费用，使用空白临时目录，不发送旧聊天或代码，不切换当前线路。
结果为端到端完整回复耗时，包含 CLI 启动、排队和内部重试，不是首 token 延迟。
多轮交替顺序，并汇总成功次数和成功样本中位数；失败样本不算成功。
上游实际模型映射无法由本工具保证，hello 结果也不代表长任务吞吐。
ChatGPT 测试临时凭据可能触发令牌刷新；首次建议避开重要运行任务。
命名账号共享本地历史，不能同步云端任务，也不支持同目录双账号并发。
Python >= 3.11；仅支持 Linux。版本检查目前只接受 Codex 0.153.4 / 0.154.0；
实验接口可能变化，其他版本需要先完成兼容验证。

## 本地安装

```bash
python3 -m venv .venv
.venv/bin/python -m pip install .
.venv/bin/codex-mode --version
```

不要覆盖已有稳定版的命令；先在独立虚拟环境验证。包名 `codex-mode` 暂定，
PyPI 名称可用性、许可证、作者信息和发布账户尚待确认。

## 推荐：逐步配置向导

先安装 Codex 并运行一次，确保 CODEX_HOME 已有 config.toml。手动停止所有任务、
暂停 goal，断开该机器的 Desktop；在服务器终端而不是运行中的 Codex 聊天执行：

```bash
codex-mode setup
# 不带参数也启动向导；指定其他目录：
codex-mode setup --state-dir /absolute/path/to/codex-home
```

六步：检查环境 → 完整备份 → 扫描历史 provider → 隐藏输入 API key 和模型名
→ 复用或完成官方 ChatGPT 设备登录 → 隔离验证两种模式。逐步确认是否托管历史
provider、是否发送真实测试请求、是否最终启用路由。默认不激活路由。
旧任务只读取，不 resume、不启动 turn、不操作 goal。真实请求仅使用新建临时
任务和固定一句话，不发送旧聊天。跳过真实请求时不会宣称实际线路可用。
测试配置关闭 shell、unified exec 和 web search，移除生产 MCP/hooks 等设置。
参考官方 [鉴权](https://learn.chatgpt.com/docs/auth)、
[App Server](https://learn.chatgpt.com/docs/app-server) 和
[配置字段](https://learn.chatgpt.com/docs/config-file/config-reference)。

完整备份位于父目录/.codex-mode-backups/<目录名>-<时间>/home，含凭据、聊天、
数据库和插件，可能占用数十 GB，不要分享。目录 0700、普通文件 0600；SQLite
backup API 合并已提交 WAL。运行时 socket 不复制，符号链接不跟随，异常及原始
权限记录在 manifest.json。正式向导拒绝运行中的服务；测试 live capture 不是
跨文件一致性快照。验证只写元数据/结果，不在报告中写正文和 token。

逐个检查全部任务摘要，检查置顶任务和少量样本的最新轮次内容；不是逐字校验全部
历史，也不能保证 Desktop 每个筛选都显示所有任务。内置 openai 不覆盖，历史
provider/source/cwd 筛选仍可能隐藏任务，需按 ID 或相应筛选打开。缺失代码目录
会提示，工具不迁移代码。失败不启用新路由；工具配置/凭据会保留供排查，原主配置
和鉴权保持不变。

```bash
codex-mode scan
codex-mode restore --backup /absolute/path/to/backup-directory
codex-mode verify --backup /absolute/path/to/backup-directory
# 已有完整备份时重试验证，无需再次备份；加 --request-test 确认后测试真实请求
```

restore 需停止服务并确认，只还原配置和登录，先保存当前控制文件的撤销副本；不
覆盖聊天、数据库或代码。旧登录可能需重新授权。备份中不存在的控制文件会移除，
可从撤销副本找回。只分享 wheel 和 SHARE.md，不分享备份或真实 CODEX_HOME。

## 初始化与使用

先安装、初始化 Codex，确保选定 CODEX_HOME 中有 config.toml。
默认使用环境变量 CODEX_HOME，否则使用当前用户的 ~/.codex。

```bash
# API 地址需要指向支持 Responses 的服务，不要在 URL 中放密钥。
codex-mode init --api-url https://api.example.com/v1 --prompt-key
# 或使用环境变量（该变量也必须对 Desktop 远程服务可见）
codex-mode init --api-url https://api.example.com/v1 --key-env MY_CODEX_API_KEY

codex-mode doctor
codex-mode login
codex-mode chatgpt --dry-run
codex-mode chatgpt
codex-mode api
codex-mode status
```

`sub2api` 是 `api` 的兼容命令。`--state-dir DIR` 指定独立目录；
`--codex-bin PATH` 覆盖 Codex 可执行文件；`init --codex-bin PATH` 将其保存。
`init --import-api-key` 显式导入现有 auth.json 的 API key，不改现有鉴权。
可选 `init --health-url URL` 启用独立健康检查，默认不假定服务有 /health。

工具配置保存在 CODEX_HOME/codex-mode.json。隐藏输入的 API key 保存在
CODEX_HOME/auth-profiles/sub2api.auth.json（0600）；不是加密保险库。
也可使用 key_env，不保存 key 值。`_key` 是凭据读取专用内部命令，不应手动调用。
安装路径及对应虚拟环境必须在 Codex 使用期间保持可访问，生成的凭据命令
使用该 Python 的绝对路径和 `-m codex_mode`。

## 中断与历史边界

普通切换前，请手动停止正在运行的任务、暂停 goal，并断开 Desktop。
工具只复查已加载会话是否空闲，不查询 goal，也不自动暂停或中断任务。
空闲服务使用 SIGTERM 请求退出，最多等待 30 秒；无法确认空闲时拒绝切换。
空闲 Desktop 代理仍在时，可用 --disconnect-idle；无法正常停止时用 --force。
显式 `codex-mode chatgpt --force`（或 `api --force`）绕过会话查询，要求终端确认，
先向当前用户/当前 CODEX_HOME 的既有服务与代理发送 SIGTERM，5 秒后仍未退出才
发送 SIGKILL。需要 Python/kernel 的 Linux pidfd 支持；不会终止新出现的连接。
force 模式不能保证未完成轮次完整保存，也不会暂停或清除 goal；外部后台进程可能
继续运行。切换完成后重连 Desktop，启动新配置服务。force 仅适合正常切换失败时使用。
未手动暂停的 goal 可能在重连后继续运行；工具不会改变 goal 状态。
已中断的轮次不会自动继续，已落盘代码修改不会撤销。
切换期间不要重新连接 Desktop 或提交新任务；外部客户端不受本工具锁约束，
状态复查只能缩小并发窗口，不能提供跨客户端事务保证。

重新连接 Desktop，在同一聊天检查进度并继续。训练、下载、nohup/systemd 等
外部进程不受会话中断统一管理，重新运行命令前检查它们。

默认只管理稳定 provider ID `direct`。历史 provider ID 不会自动统一，
CLI 列表可能仍按 provider 过滤；`resume --all` 只取消目录筛选。
使用 `init --provider-alias OpenAI --provider-alias sub2api` 显式允许工具在切换时
重写这些 provider 的配置，使它们跟随所选路由。它不会改历史 JSONL 或数据库。
这些别名原有的专有设置将被替换；其他 providers、项目设置、注释和多行值保留。
新配置使用文件凭据存储，替代 forced_login_method；不保留 keyring-only 设置。

默认日志精简，TTY 支持颜色，NO_COLOR / TERM=dumb 禁用颜色；
`--verbose` 查看任务 ID、备份路径等。`--dry-run` 仅验证配置转换，不验证网络、
任务状态或实际模型请求。

## 网络与发布

不自动配置 SSH、系统路由或中继。已有 SSH 转发可作为 api-url 指向的本地端口，
由用户另外管理。

```bash
python -m unittest discover -s tests -v
# 实际 Codex + 临时 CODEX_HOME + loopback 模拟 API，不使用真实凭据：
python tests/integration_smoke.py /absolute/path/to/codex
python -m build
python -m twine check dist/*
# 先确认名称/许可证/账号，再手动上传 TestPyPI；不要上传凭据或历史。
# python -m twine upload --repository testpypi dist/*
```

发布前待办见 RELEASE.md。安装不会读取或修改实际 Codex 登录；init 只更改
工具自己的配置/凭据，mode 命令才执行切换并备份 config.toml/auth.json。
