[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-78208":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":12,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":18,"rankGlobal":9,"rankLanguage":9,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":9,"pushedAt":9,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":15,"starSnapshotCount":15,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},78208,"codex-shim","0xSero\u002Fcodex-shim","0xSero","Local Responses-API shim that exposes Factory BYOK models (and optional ChatGPT GPT-5.5 passthrough) to Codex Desktop.",null,"Python",863,83,3,1,0,714,11,9.77,"MIT License",false,"main",true,[],"2026-06-12 02:03:46","# codex-shim\n\nRun **Codex Desktop** with any model declared in your `~\u002F.factory\u002Fsettings.json`\n(or any custom JSON file), plus an optional passthrough to your **ChatGPT\nsubscription's GPT‑5.5** — without recompiling Codex.\n\nThe shim is a small local Python server that pretends to be an OpenAI Responses\nAPI endpoint. Codex points at it; the shim routes each request to whatever\nupstream the matching Factory BYOK entry uses (OpenAI \u002F Anthropic \u002F\ngeneric-chat-completion-api \u002F ChatGPT subscription).\n\n> Status: tested on Codex Desktop **0.133.0-alpha.1** for macOS arm64.\n> Linux\u002FWindows users should be able to skip the ASAR patch section and use the\n> shim itself unchanged.\n\n---\n\n## Why\n\nCodex Desktop only shows the models its server-side Statsig config whitelists.\nIf you have OpenAI \u002F Anthropic \u002F Z.ai \u002F DeepSeek \u002F Gemini \u002F OpenRouter \u002F Factory\nkeys you'd like to use **as first-class models in the picker**, this gets you\nthere. It also lets you keep your ChatGPT subscription's GPT‑5.5 visible\nalongside everything else.\n\n---\n\n## Install\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002F\u003Cyou>\u002Fcodex-shim ~\u002FDocuments\u002Fcodex-shim\ncd ~\u002FDocuments\u002Fcodex-shim\npython3 -m pip install --user aiohttp pytest    # only runtime dep is aiohttp\nln -s \"$PWD\u002Fbin\u002Fcodex-shim\" ~\u002F.local\u002Fbin\u002Fcodex-shim\nln -s \"$PWD\u002Fbin\u002Fcodex-app\"  ~\u002F.local\u002Fbin\u002Fcodex-app\nln -s \"$PWD\u002Fbin\u002Fcodex-model\" ~\u002F.local\u002Fbin\u002Fcodex-model\n```\n\nRequires Python 3.11+.\n\n---\n\n## Quick start\n\n### 1. Generate the catalog and start the shim\n\n```bash\ncodex-shim generate          # reads ~\u002F.factory\u002Fsettings.json, writes catalog\ncodex-shim start             # background daemon on 127.0.0.1:8765\ncodex-shim list              # show generated slugs and upstream routes\ncodex-shim status            # health probe\n```\n\n### 2. Point Codex Desktop at it (no global config changes)\n\n```bash\ncodex-shim app .             # launch Codex with the shim wired in\n```\n\nThat command applies opt-in `-c` overrides only for this launch. Your\n`~\u002F.codex\u002Fconfig.toml` is left untouched. After this Codex Desktop sees every\nentry from `~\u002F.factory\u002Fsettings.json` plus an optional `OpenAI GPT-5.5\n(ChatGPT)` slug as picker entries.\n\nIf your Codex Desktop's model picker only shows \"default\" and refuses to render\nthe catalog entries, you also need the **picker patch** below.\n\n### 3. (Optional) Switch the active Desktop model\n\n```bash\ncodex-model list\ncodex-model openai-gpt-5-5    # or any other slug from `list`\ncodex-app                     # relaunch Codex with new default\n```\n\n---\n\n## Custom config file\n\nThe shim defaults to `~\u002F.factory\u002Fsettings.json` (the file Factory.ai writes\nwhen you save BYOK custom models). You can point it at any file:\n\n```bash\ncodex-shim --settings \u002Fpath\u002Fto\u002Fmy-models.json generate\ncodex-shim --settings \u002Fpath\u002Fto\u002Fmy-models.json start\n```\n\nSchema expected (Factory's own format):\n\n```json\n{\n  \"customModels\": [\n    {\n      \"model\": \"gpt-5.5\",\n      \"provider\": \"openai\",\n      \"baseUrl\": \"https:\u002F\u002Fapi.openai.com\u002Fv1\",\n      \"apiKey\": \"sk-…\",\n      \"displayName\": \"OpenAI GPT-5.5\",\n      \"maxContextLimit\": 400000\n    },\n    {\n      \"model\": \"claude-opus-4-7-20251109\",\n      \"provider\": \"anthropic\",\n      \"baseUrl\": \"https:\u002F\u002Fapi.anthropic.com\u002Fv1\",\n      \"apiKey\": \"sk-ant-…\",\n      \"displayName\": \"Claude Opus 4.7\"\n    },\n    {\n      \"model\": \"deepseek-v4-pro\",\n      \"provider\": \"anthropic\",\n      \"baseUrl\": \"https:\u002F\u002Fapi.deepseek.com\u002Fanthropic\",\n      \"apiKey\": \"…\",\n      \"displayName\": \"DeepSeek V4 Pro\",\n      \"noImageSupport\": true\n    }\n  ]\n}\n```\n\nThe shim **never copies your API keys** into the generated catalog. Keys stay\nin your settings file and are read fresh on every request.\n\nSupported `provider` values:\n\n| provider | upstream API |\n|---|---|\n| `openai` | OpenAI\u002F`\u002Fv1\u002Fchat\u002Fcompletions` |\n| `generic-chat-completion-api` | OpenAI-shaped chat completions |\n| `anthropic` | Anthropic `\u002Fv1\u002Fmessages` |\n\n---\n\n## Picker patch for Codex Desktop on macOS\n\nCodex Desktop has a Statsig server-side allowlist (`use_hidden_models: true`)\nthat hides any model whose slug isn't on a hardcoded list. Custom catalog\nentries fall into the hidden bucket and never render in the picker.\n\nA single‑boolean ASAR patch flips the allowlist branch off so the picker only\nchecks the local `hidden` flag (which our catalog never sets).\n\n> **Always back up `app.asar` and `Info.plist` before patching.**\n\n```bash\nAPP=\u002FApplications\u002FCodex.app\nsudo cp -R \"$APP\" \"$APP.unpatched-$(date +%Y%m%d-%H%M%S)\"\n\n# 1. Extract the ASAR\ncd \u002Ftmp && rm -rf codex-asar-patch && mkdir codex-asar-patch && cd codex-asar-patch\nnpx --yes @electron\u002Fasar extract \"$APP\u002FContents\u002FResources\u002Fapp.asar\" extracted\n\n# 2. Patch the picker filter (this match is single-occurrence, unique to that file)\nPATCH_FILE=$(grep -RIl 'useHiddenModels' extracted\u002Fwebview\u002Fassets\u002Fmodel-queries-*.js | head -n1)\nsed -i.bak -E 's\u002Flet u=c\\.useHiddenModels&&o!==`amazonBedrock`,d;\u002Flet u=!1,d;\u002F' \"$PATCH_FILE\"\ndiff \"$PATCH_FILE.bak\" \"$PATCH_FILE\" || true   # confirm exactly one change\nrm \"$PATCH_FILE.bak\"\n\n# 3. Repack\nnpx --yes @electron\u002Fasar pack extracted app.asar.new\nsudo cp app.asar.new \"$APP\u002FContents\u002FResources\u002Fapp.asar\"\n```\n\nThat alone will crash Codex on next launch with `EXC_BREAKPOINT`. Electron's\n`ElectronAsarIntegrity` field in `Info.plist` is a SHA-256 of the **JSON\nheader** of the asar archive (not the whole file). Recompute it and re-sign:\n\n```bash\n# 4. Compute new header hash\nHEADER_HASH=$(python3 - \"$APP\u002FContents\u002FResources\u002Fapp.asar\" \u003C\u003C'PY'\nimport struct, hashlib, sys\nwith open(sys.argv[1], 'rb') as f:\n    data_size, header_size, _, json_size = struct.unpack('\u003C4I', f.read(16))\n    header_json = f.read(json_size)\nprint(hashlib.sha256(header_json).hexdigest())\nPY\n)\necho \"new header hash: $HEADER_HASH\"\n\n# 5. Patch Info.plist (replaces the hash for Resources\u002Fapp.asar)\nsudo \u002Fusr\u002Flibexec\u002FPlistBuddy -c \\\n  \"Set :ElectronAsarIntegrity:Resources\u002Fapp.asar:hash $HEADER_HASH\" \\\n  \"$APP\u002FContents\u002FInfo.plist\"\n\n# 6. Ad-hoc re-sign (drops Apple signature; Gatekeeper will warn once)\nsudo codesign --force --deep --sign - \"$APP\"\n\n# 7. Launch\nopen \"$APP\"\n```\n\nTo roll back: `sudo rm -rf \"$APP\" && sudo mv \"$APP.unpatched-…\" \"$APP\"`.\n\n---\n\n## ChatGPT GPT‑5.5 passthrough (optional)\n\nIf you have a ChatGPT plan with Codex access (`~\u002F.codex\u002Fauth.json` exists with\n`auth_mode: chatgpt`), the shim exposes one synthetic slug\n`openai-gpt-5-5` (display name `OpenAI GPT-5.5 (ChatGPT)`) that proxies\nstraight to `https:\u002F\u002Fchatgpt.com\u002Fbackend-api\u002Fcodex\u002Fresponses` with your access\ntoken. It bypasses Factory entirely and uses your ChatGPT subscription quota.\n\nIt's already in `.codex-shim\u002Fcustom_model_catalog.json` after `codex-shim\ngenerate`. Just select it in the picker.\n\nIf you don't want it, delete the entry with slug `openai-gpt-5-5` from the\ngenerated catalog, or run with `CODEX_SHIM_DISABLE_CHATGPT=1` (TODO).\n\n---\n\n## How the routing works\n\n```\nCodex Desktop ── \u002Fv1\u002Fresponses ──▶ codex-shim (127.0.0.1:8765)\n                                     │\n                                     ├── slug \"openai-gpt-5-5\"\n                                     │       └─▶ chatgpt.com\u002Fbackend-api\u002Fcodex\u002Fresponses\n                                     │           (Authorization: Bearer \u003Cauth.json access_token>)\n                                     │\n                                     ├── provider \"openai\" \u002F \"generic-…\"\n                                     │       └─▶ baseUrl\u002Fchat\u002Fcompletions\n                                     │           (Authorization: Bearer apiKey)\n                                     │\n                                     └── provider \"anthropic\"\n                                             └─▶ baseUrl\u002Fmessages\n                                                 (x-api-key: apiKey, anthropic-version: …)\n```\n\nThe shim translates Codex's Responses-API request into the upstream's shape\n(chat completions or Anthropic Messages) and translates the streamed reply\nback. Extended-thinking blocks from Anthropic-shaped upstreams (Claude,\nDeepSeek, GLM) round-trip through `reasoning.encrypted_content` items.\n\n---\n\n## MCP\n\nCodex Desktop forwards three generic MCP tools to every model:\n\n- `list_mcp_resources`\n- `list_mcp_resource_templates`\n- `read_mcp_resource`\n\nIt does **not** flatten individual MCP server tools into the function list.\nThat's a Codex client behavior, not a shim limitation. Shim-routed models\nreceive the same MCP tools as built-in OpenAI models. The model is expected\nto call `list_mcp_resources` to discover what's available.\n\n---\n\n## Commands\n\n```\ncodex-shim generate         regenerate catalog\u002Fconfig without starting daemon\ncodex-shim start            start local shim daemon\ncodex-shim status           health check + model count\ncodex-shim stop             stop daemon\ncodex-shim restart          restart daemon\ncodex-shim list             list generated slugs and Factory routes\ncodex-shim model list       list slugs currently usable in the picker\ncodex-shim model use \u003Cslug> set the Desktop default model\ncodex-shim codex -- \u003Cargs>  exec `codex` CLI through the shim\ncodex-shim app [path]       launch Codex Desktop through the shim\n\ncodex-app [path]            shortcut for `codex-shim app`\ncodex-model [list|\u003Cslug>]   shortcut for `codex-shim model …`\n```\n\nAll commands accept `--settings \u003Cpath>` and `--port \u003Cport>`.\n\n---\n\n## File layout\n\n```\ncodex_shim\u002F             python source (server + cli + translation)\nbin\u002Fcodex-shim          main entrypoint\nbin\u002Fcodex-app           shortcut wrapping `codex-shim app`\nbin\u002Fcodex-model         shortcut wrapping `codex-shim model …`\n.codex-shim\u002F            generated catalog, config, logs, pid (gitignored)\ntests\u002F                  pytest suite\n```\n\nThe shim never edits `~\u002F.codex\u002Fconfig.toml`. All Codex overrides are passed\ninline as `-c key=value` arguments per launch.\n\n---\n\n## License\n\nMIT — see `LICENSE`.\n\nCodex Desktop is a trademark of OpenAI. This project is unaffiliated.\n","codex-shim 是一个本地响应API代理，允许Codex Desktop使用自定义的Factory BYOK模型，并可选地通过ChatGPT订阅访问GPT-5.5。项目核心功能是模拟OpenAI Responses API端点的小型Python服务器，能够将请求路由到用户在`~\u002F.factory\u002Fsettings.json`中配置的各种上游服务（如OpenAI、Anthropic等）。该工具特别适合需要在Codex Desktop中集成多种AI模型的开发者或研究人员使用，使得他们可以轻松地在统一界面下管理和使用不同来源的语言模型。此外，它还支持通过简单的命令行操作来生成目录、启动服务以及切换当前使用的模型。",2,"2026-06-06 03:57:39","CREATED_QUERY"]