by Ducksss
Named CODEX_HOME profiles and ChatGPT Desktop windows with separate local state, without copying tokens
# Add to your Claude Code skills
git clone https://github.com/Ducksss/codex-profilesGuides for using cli tools skills like codex-profiles.
Last scanned: 8/23/2026
{
"issues": [
{
"file": "README.md",
"line": 80,
"type": "remote-install",
"message": "Install command (remote install script piped to a shell — review the source before running): \"curl -fsSL https://raw.githubusercontent.com/Ducksss/codex-profiles/main/install\"",
"severity": "low"
},
{
"file": "README.md",
"line": 423,
"type": "dangerous-command",
"message": "Dangerous command (recursive delete of home/root): \"rm -rf \"$HOME\"",
"severity": "medium"
}
],
"status": "PASSED",
"scannedAt": "2026-08-23T04:35:56.470Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}codex-profiles is an open-source cli tools skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by Ducksss. Named CODEX_HOME profiles and ChatGPT Desktop windows with separate local state, without copying tokens. It has 100 GitHub stars.
Yes. codex-profiles passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/Ducksss/codex-profiles" and add it to your Claude Code skills directory (see the Installation section above).
codex-profiles is primarily written in Shell. It is open-source under Ducksss on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other CLI Tools skills you can browse and compare side by side. Open the CLI Tools category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh codex-profiles against similar tools.
No comments yet. Be the first to share your thoughts!
Top skills in this category by stars
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
Named Codex homes and ChatGPT windows with separate local state, without copying tokens.
Project page | llms.txt | Practical guides | Agent guide | Security model
codex-profiles is a dependency-free Bash wrapper for people who use Codex
with personal, work, school, client, or test accounts. Each name selects a
separate CODEX_HOME. On macOS, a named Desktop launch also selects separate
Electron user data for the whole launched ChatGPT window.
codex-profile cli personal # Codex CLI on personal
codex-profile cli work exec "review this repo" # one-shot Codex CLI on work
codex-profile app default ~/Dev/app # stock ChatGPT session
codex-profile app work ~/Dev/client # named work ChatGPT window
The project keeps its existing name and commands. Version 0.7 adapts the
implementation to OpenAI's integrated ChatGPT desktop app; it does not rebrand
the CLI or copy, parse, print, or migrate auth.json.
OpenAI's July 9 release notes describe the integrated desktop app as bringing Chat, Work, and Codex together. The commands in this project therefore have two intentionally different scopes:
| Command family | What the selected name controls |
|---|---|
cli, login, env, use |
Codex-local state under the selected CODEX_HOME. These commands do not switch an open ChatGPT window. |
app default |
The normal installed ChatGPT app, its stock Desktop session, and ~/.codex. |
app <name> |
A named ChatGPT window with its own local Electron user data across Chat, Work, and Codex, plus ~/.codex-<name> for Codex-local state. |
status |
Codex-local login status. It does not identify the account shown in a ChatGPT window. |
doctor |
Installation and local-state diagnostics. It cannot prove that CLI and Desktop are signed into the same account. |
work in codex-profile app work is a user-chosen profile name. It is not the
ChatGPT product mode named Work. Once a named window is open, switching its
mode between Chat, Work, and Codex stays inside that window's Desktop session.
Account equality is deliberately unverified. The tool does not inspect tokens, account identifiers, cookies, or private application data. If you want the CLI and Desktop window to use the same account, authenticate both in that profile and verify the visible account yourself.
Local-state separation is not an account, OS, or server-side boundary.
With npm:
npm install -g codex-profile
The npm package is singular. It installs both codex-profile and
codex-profiles; the plural npm package belongs to another project.
With Homebrew:
brew install Ducksss/tap/codex-profile
With the standalone installer:
curl -fsSL https://raw.githubusercontent.com/Ducksss/codex-profiles/main/install.sh | sh
With Nix:
nix run github:Ducksss/codex-profiles
nix profile install github:Ducksss/codex-profiles
From source:
git clone https://github.com/Ducksss/codex-profiles.git
cd codex-profiles
make install
Then verify the installation:
codex-profile doctor
Create two Codex homes and authenticate their CLI sessions:
codex-profile init personal
codex-profile init work
codex-profile login personal
codex-profile login work
To keep authentication and runtime state separate while sharing selected configuration, initialize a new linked profile from an existing one:
codex-profile init personal-2 --share-with personal
codex-profile login personal-2
Run the upstream Codex CLI with either home:
codex-profile cli personal
codex-profile cli work exec "run tests and summarize failures"
Optionally bind a project once, then let the current directory select its profile for both CLI and Desktop launches:
codex-profile workspace bind ~/Dev/work-project work
cd ~/Dev/work-project
codex-profile run exec "run tests and summarize failures"
codex-profile run --app
On macOS, open the stock ChatGPT session or a named window with separate local state:
codex-profile app default ~/Dev/main-project
codex-profile app personal ~/Dev/personal-project
codex-profile app work ~/Dev/work-project
The first launch of a named window may require signing into ChatGPT. Reopening
the same name reuses that name's Desktop process and data. Different names can
run side by side. The launcher uses the original signed ChatGPT.app; it does
not clone, patch, re-sign, quit, or replace the installed app.
Only default is special:
default -> ~/.codex
<name> -> ~/.codex-<name>
Examples:
personal -> ~/.codex-personal
work -> ~/.codex-work
edu -> ~/.codex-edu
client -> ~/.codex-client
Every launch picks one profile box. Shared skills are added to whichever box you pick:
flowchart TB
shared["SHARED BY EVERY PROFILE<br/>OpenAI bundled skills<br/>~/.agents/skills<br/><repo>/.agents/skills"]
subgraph defaultBox["DEFAULT"]
default["~/.codex"]
defaultOwn["Its own<br/>login · config · sessions<br/>skills · plugins · automations"]
defaultApp["app default<br/>stock ChatGPT Desktop data"]
default --> defaultOwn
default --> defaultApp
end
subgraph namedBox["NAMED — example: work"]
named["~/.codex-work"]
namedOwn["Its own<br/>login · config · sessions<br/>skills · plugins · automations"]
namedApp["app work<br/>Desktop data in electron-user-data/"]
named --> namedOwn
named --> namedApp
end
shared --> default
shared --> named
The two profile boxes are siblings: work does not inherit anything from
default. Only init --share-with creates the limited links documented below.
For a named Desktop launch, local Electron data lives below that profile home:
~/.codex-<name>/electron-user-data
The directory supplies separate Electron state for that named ChatGPT window. Local-state separation is not an account, OS, or server-side boundary. Profile names must begin with a letter or number and may then contain letters, numbers, dots, dashes, or underscores.
Inspect a path without creating or launching anything:
codex-profile path personal
codex-profile init client-a
codex-profile init client-b --share-with client-a
codex-profile list
codex-profile remove client-a
codex-profile remove client-a --yes
list and status are read-only. They do not create a directory for a typo.
Removing a profile deletes its Codex home and, for a named Desktop profile, its
local Electron data. It also removes bindings that target that profile, without
deleting any project directory. Review the path and close the corresponding
window first.
codex-profile workspace bind ~/Dev/client-a client-a
codex-profile workspace bind ~/Dev/client-a/service client-a-service
codex-profile workspace list
codex-profile workspace status
codex-profile workspace status --json ~/Dev/client-a/service
Bindings use physical canonical directory paths. The nearest bound ancestor
wins, so a nested project can override a broader workspace. Similar string
prefixes are not matches: binding client-a does not bind client-app.
Bindings are private local metadata; they do not create or modify files in a
project.
From a bound directory, omit the profile name:
codex-profile run
codex-profile run exec "review this repo"
codex-profile run -- --app # pass --app to the upstream CLI
codex-profile run --app # launch the bound ChatGPT window
codex-profile run --app ~/Dev/client-a
Explicit cli, env/use, and app selections are checked against the
current or supplied workspace. Mismatches warn on stderr by default, so stdout
remains safe for eval and scripts. Choose stricter or disabled checks with:
codex-profile workspace guard strict
codex-profile workspace guard off
codex-profile workspace guard warn
Strict mode rejects a mismatch before launching Codex, ChatGPT, or emitting
shell exports. This is a mistake-prevention guardrail, not a security boundary;
it can be disabled or bypassed by invoking upstream Codex directly. The wrapper
requires -- before upstream options that start with a dash, for example
codex-profile run -- -C <directory>. Those arguments are passed through and
are not parsed for guard resolution, so change to the intended directory before
using run or an explicitly guarded cli.
Binding state is stored with private permissions in `${XDG_CONFIG_HOME