diff --git a/README.md b/README.md
index d3db66b..81e1f69 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
**Keep one portable memory-and-skills layer across coding-agent harnesses, so switching tools doesn't reset how your agent works.**
-A portable `.agent/` folder (memory + skills + protocols) that plugs into Claude Code, Cursor, Windsurf, OpenCode, OpenClaw, Hermes, Pi Coding Agent, or a DIY Python loop — and keeps its knowledge when you switch.
+A portable `.agent/` folder (memory + skills + protocols) that plugs into Claude Code, Cursor, Windsurf, OpenCode, OpenClaw, Hermes, Pi Coding Agent, Codex, or a DIY Python loop — and keeps its knowledge when you switch.
@@ -28,7 +28,7 @@ brew install agentic-stack
# drop the brain into any project — the onboarding wizard runs automatically
cd your-project
agentic-stack claude-code
-# or: cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
+# or: cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
```
### Windows (PowerShell)
@@ -52,7 +52,7 @@ brew update && brew upgrade agentic-stack
git clone https://github.com/codejunkie99/agentic-stack.git
cd agentic-stack && ./install.sh claude-code # mac / linux / git-bash
# or on Windows PowerShell: .\install.ps1 claude-code
-# adapters: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
+# adapters: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
```
## Onboarding wizard
@@ -122,7 +122,7 @@ See [`docs/architecture.md`](docs/architecture.md) for the full lifecycle.
Every guide shows the folder structure. This repo gives you the folder
structure **plus the files that actually go inside**: a working portable
brain with five seed skills, four memory layers, enforced permissions, a
-nightly staging cycle, host-agent review tools, and adapters for eight
+nightly staging cycle, host-agent review tools, and adapters for multiple
harnesses.
- **Memory** — `working/`, `episodic/`, `semantic/`, `personal/`. Each
@@ -197,6 +197,7 @@ adapters/ # one small shim per harness
├── openclaw/ (AGENTS.md + system-prompt include; auto-registers per-project agent)
├── hermes/ (AGENTS.md)
├── pi/ (AGENTS.md + .pi/skills symlink)
+├── codex/ (AGENTS.md)
├── standalone-python/ (DIY conductor entrypoint)
└── antigravity/ (ANTIGRAVITY.md)
@@ -225,6 +226,7 @@ verify_codex_fixes.py # v0.8.0 regression checks (33 checks)
| **OpenClaw** | `AGENTS.md` (auto-injected) + per-project `openclaw agents add --workspace` | varies by fork |
| **Hermes Agent** | `AGENTS.md` (agentskills.io compatible) | partial (own memory) |
| **Pi Coding Agent** | `AGENTS.md` + `.pi/skills/` + `.pi/extensions/` | yes (`tool_result` event) |
+| **Codex** | `AGENTS.md` + `.agents/skills/` | no (manual reflect calls) |
| **Standalone Python** | `run.py` (any LLM) | yes (full control) |
| **Antigravity** | `ANTIGRAVITY.md` | yes (system context) |
diff --git a/adapters/codex/AGENTS.md b/adapters/codex/AGENTS.md
new file mode 100644
index 0000000..14bbc57
--- /dev/null
+++ b/adapters/codex/AGENTS.md
@@ -0,0 +1,46 @@
+# AGENTS.md — Codex adapter for agentic-stack
+
+Codex reads `AGENTS.md` before doing any work. This file points it at
+the portable brain in `.agent/`.
+
+> **Python invocation**: examples below use `python3`. On stock Windows
+> only `python` is on PATH; use whichever resolves on your system.
+
+## Startup (read in order)
+1. `.agent/AGENTS.md` — the map
+2. `.agent/memory/personal/PREFERENCES.md` — user conventions
+3. `.agent/memory/semantic/LESSONS.md` — distilled lessons
+4. `.agent/protocols/permissions.md` — hard rules
+
+## Skills
+Codex scans `.agents/skills/` for repository-scoped skills (per
+[OpenAI Codex docs](https://developers.openai.com/codex/skills)). The
+install script symlinks or syncs `.agents/skills` from `.agent/skills`
+so the portable brain remains the one source of truth. Load a full
+`SKILL.md` only when its triggers match the task (progressive
+disclosure). Edit skills in `.agent/skills/` — `.agents/skills/` is a
+mirror and re-running the installer will sync it back.
+
+## Recall before non-trivial tasks
+For deploy / ship / migration / schema / timestamp / date / failing test /
+debug / refactor, FIRST run:
+
+```bash
+python3 .agent/tools/recall.py ""
+```
+
+Surface results in a `Consulted lessons before acting:` block and follow
+them.
+
+## Memory discipline
+- Update `.agent/memory/working/WORKSPACE.md` as you work.
+- After significant actions, run
+ `python3 .agent/tools/memory_reflect.py `.
+- Never delete memory entries; archive only.
+- Quick state: `python3 .agent/tools/show.py`.
+- Teach a rule in one shot:
+ `python3 .agent/tools/learn.py "" --rationale ""`.
+
+## Hard rules
+- No force push to `main`, `production`, `staging`.
+- No modification of `.agent/protocols/permissions.md`.
diff --git a/adapters/codex/README.md b/adapters/codex/README.md
new file mode 100644
index 0000000..da1db02
--- /dev/null
+++ b/adapters/codex/README.md
@@ -0,0 +1,44 @@
+# Codex adapter
+
+## Install
+```bash
+./install.sh codex
+```
+
+Or on Windows PowerShell:
+```powershell
+.\install.ps1 codex C:\path\to\your-project
+```
+
+## What it wires up
+- `AGENTS.md` — Codex reads this natively as project instructions. If
+ `AGENTS.md` already exists (for example from the pi, hermes, or
+ opencode adapters), the installer leaves it in place.
+- `.agents/skills/` → `.agent/skills/` — Codex scans `.agents/skills/`
+ for repository skills. The installer creates a symlink when possible
+ and falls back to copying / merging when symlinks are unavailable.
+
+## Verify
+Run Codex in the project and ask:
+
+```bash
+codex --ask-for-approval never "Summarize the current instructions."
+```
+
+It should mention `.agent/AGENTS.md` and the portable memory files.
+
+Then ask:
+
+```bash
+codex --ask-for-approval never "What's in my lessons file?"
+```
+
+It should read `.agent/memory/semantic/LESSONS.md`.
+
+## Notes
+- This adapter does **not** install Codex hooks. Codex hooks are still
+ experimental, and the official docs note they are currently disabled
+ on Windows. The adapter therefore relies on manual `recall.py` and
+ `memory_reflect.py` calls, like the Cursor and Windsurf paths.
+- If `.agents/skills/` is a copied directory rather than a symlink,
+ re-run the installer after editing `.agent/skills/` to sync updates.
diff --git a/docs/architecture.md b/docs/architecture.md
index 51d9c27..c3804c0 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -33,7 +33,8 @@ Three modules, one principle: the harness is dumb, the knowledge is in files.
## Why the separation matters
You can swap the harness for any of the adapters (Claude Code, Cursor,
-Windsurf, OpenCode, OpenClaw, Hermes, standalone Python) and lose
-nothing. The brain is portable; only the glue changes.
+Windsurf, OpenCode, OpenClaw, Hermes, Pi, Codex, standalone Python,
+Antigravity) and lose nothing. The brain is portable; only the glue
+changes.
See `diagram.svg` for a visual.
diff --git a/docs/getting-started.md b/docs/getting-started.md
index 40715cb..32bd8d4 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -16,7 +16,8 @@ cp /path/to/agentic-stack/install.sh ./
```bash
./install.sh claude-code # or cursor, windsurf, opencode,
- # openclaw, hermes, standalone-python
+ # openclaw, hermes, pi, codex,
+ # standalone-python, antigravity
```
Each adapter has its own `README.md` under `adapters//`.
diff --git a/docs/per-harness/codex.md b/docs/per-harness/codex.md
new file mode 100644
index 0000000..5b6af4c
--- /dev/null
+++ b/docs/per-harness/codex.md
@@ -0,0 +1,58 @@
+# Codex setup
+
+[Codex](https://developers.openai.com/codex/) reads `AGENTS.md` natively
+and scans `.agents/skills/` for repository-scoped skills. Our adapter
+layers the portable `.agent/` brain on top so you keep one knowledge
+base even if you later swap harnesses.
+
+## What the adapter installs
+- `AGENTS.md` at project root. Skipped if one already exists, since
+ codex, pi, hermes, and opencode can all share the same file.
+- `.agents/skills/` symlinked to `.agent/skills/` when possible. Falls
+ back to copying / merging on platforms without symlink support.
+
+## Install
+```bash
+npm install -g @openai/codex
+./install.sh codex
+codex
+```
+
+On Windows PowerShell:
+```powershell
+npm install -g @openai/codex
+.\install.ps1 codex C:\path\to\your-project
+codex
+```
+
+## How it works
+- Codex loads `AGENTS.md` before starting work. The adapter file points
+ it at `.agent/AGENTS.md`, `PREFERENCES.md`, `LESSONS.md`, and
+ `permissions.md`.
+- Codex scans `.agents/skills/` from the current working directory up to
+ the repository root. The adapter mirrors `.agent/skills/` there so the
+ portable skills are visible without duplication.
+- The adapter intentionally does **not** install Codex hooks. The docs
+ mark hooks experimental, and Windows support is currently disabled, so
+ manual `recall.py` and `memory_reflect.py` calls remain the stable
+ cross-platform path.
+
+## Verify
+```bash
+codex --ask-for-approval never "Summarize the current instructions."
+codex --ask-for-approval never "What's in my lessons file?"
+```
+
+Expected:
+- the first command mentions `.agent/AGENTS.md`
+- the second reads `.agent/memory/semantic/LESSONS.md`
+
+## Troubleshooting
+- If Codex does not pick up `AGENTS.md`, restart it from the repository
+ root and run the `Summarize the current instructions` check again.
+- If skills are missing, inspect `.agents/skills/`. On filesystems
+ without symlink support, the installer copies / merges the directory
+ instead; re-run the installer after updating `.agent/skills/`.
+- On Windows, the native sandbox is the default and works fine for this
+ adapter. If your workflow needs Linux-native tooling, run Codex inside
+ WSL2 instead.
diff --git a/install.ps1 b/install.ps1
index 4cf47a0..084af1e 100644
--- a/install.ps1
+++ b/install.ps1
@@ -1,6 +1,6 @@
# install.ps1 — Windows PowerShell installer (parallel to install.sh)
# Usage: .\install.ps1 [target-dir] [-Yes] [-Reconfigure] [-Force]
-# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
+# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
# target-dir: where your project lives (default: current dir)
# -Yes accept all wizard defaults (safe for CI)
# -Reconfigure re-run the wizard on an existing project
@@ -24,7 +24,7 @@ $Here = Split-Path -Parent $MyInvocation.MyCommand.Path
$ValidAdapters = @(
'claude-code', 'cursor', 'windsurf',
- 'opencode', 'openclaw', 'hermes', 'pi',
+ 'opencode', 'openclaw', 'hermes', 'pi', 'codex',
'standalone-python', 'antigravity'
)
if ($Adapter -notin $ValidAdapters) {
@@ -190,6 +190,73 @@ switch ($Adapter) {
Copy-Item (Join-Path $Here '.agent/harness/hooks/pi_post_tool.py') (Join-Path $hooksDir 'pi_post_tool.py') -Force
Write-Host " + .agent/harness/hooks/pi_post_tool.py (synced for upgrades)"
}
+ 'codex' {
+ # Mirror install.sh: openclaw-style merge-or-alert on existing AGENTS.md.
+ $agentsMd = Join-Path $TargetDir 'AGENTS.md'
+ if (Test-Path $agentsMd -PathType Leaf) {
+ $existing = Get-Content -Path $agentsMd -Raw -ErrorAction SilentlyContinue
+ if ($existing -match '\.agent/') {
+ Write-Host " ~ AGENTS.md already references .agent/ — leaving alone"
+ } else {
+ Write-Host " ! AGENTS.md exists but does not reference .agent/; not overwriting."
+ Write-Host " merge this block into your AGENTS.md to wire the brain:"
+ Write-Host " ---8<---"
+ Get-Content -Path (Join-Path $Src 'AGENTS.md') | ForEach-Object { Write-Host " $_" }
+ Write-Host " --->8---"
+ }
+ } else {
+ Copy-Item (Join-Path $Src 'AGENTS.md') $agentsMd -Force
+ Write-Host " + AGENTS.md"
+ }
+
+ # Codex scans .agents/skills/ — keep the portable brain authoritative.
+ $agentsDir = Join-Path $TargetDir '.agents'
+ New-Item -ItemType Directory -Path $agentsDir -Force | Out-Null
+ $skillsSrc = Join-Path $TargetAgent 'skills'
+ $skillsDst = Join-Path $agentsDir 'skills'
+
+ # Detect symlink/junction BEFORE Remove-Item: on PowerShell 5.1
+ # `Remove-Item -Recurse` on a symlink can delete the target's
+ # contents. Use IsLink detection + .NET Delete (or repoint).
+ $skillsDstItem = Get-Item -LiteralPath $skillsDst -Force -ErrorAction SilentlyContinue
+ $isLink = $false
+ if ($skillsDstItem) {
+ $isLink = ($skillsDstItem.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -eq [System.IO.FileAttributes]::ReparsePoint
+ }
+
+ if ($skillsDstItem -and $isLink) {
+ # Existing link: delete the link only (NOT its target), then re-create.
+ try {
+ [System.IO.Directory]::Delete($skillsDst, $false)
+ } catch {
+ [System.IO.File]::Delete($skillsDst)
+ }
+ try {
+ New-Item -ItemType SymbolicLink -Path $skillsDst -Target $skillsSrc -ErrorAction Stop | Out-Null
+ Write-Host " + .agents/skills -> $skillsSrc (relinked)"
+ } catch {
+ Copy-Item -Path $skillsSrc -Destination $skillsDst -Recurse
+ Write-Host " + .agents/skills (copy; symlink not supported here)"
+ }
+ } elseif ($skillsDstItem) {
+ Remove-Item -LiteralPath $skillsDst -Recurse -Force
+ try {
+ New-Item -ItemType SymbolicLink -Path $skillsDst -Target $skillsSrc -ErrorAction Stop | Out-Null
+ Write-Host " + .agents/skills -> $skillsSrc (replaced stale copy)"
+ } catch {
+ Copy-Item -Path $skillsSrc -Destination $skillsDst -Recurse
+ Write-Host " ~ replaced .agents/skills with current .agent/skills (no symlink)"
+ }
+ } else {
+ try {
+ New-Item -ItemType SymbolicLink -Path $skillsDst -Target $skillsSrc -ErrorAction Stop | Out-Null
+ Write-Host " + .agents/skills -> $skillsSrc"
+ } catch {
+ Copy-Item -Path $skillsSrc -Destination $skillsDst -Recurse
+ Write-Host " + .agents/skills (copy; symlink not supported here)"
+ }
+ }
+ }
'standalone-python' {
Copy-Item (Join-Path $Src 'run.py') (Join-Path $TargetDir 'run.py') -Force
}
diff --git a/install.sh b/install.sh
index 504142d..46e187d 100755
--- a/install.sh
+++ b/install.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# install.sh — copy an adapter into the consuming project, then run the onboarding wizard
# Usage: ./install.sh [target-dir] [--yes] [--reconfigure]
-# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
+# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
# target-dir: where your project lives (default: current dir)
# --yes accept all wizard defaults without prompting (safe for CI)
# --reconfigure re-run the wizard even if PREFERENCES.md is already filled
@@ -13,7 +13,7 @@ HERE="$(cd "$(dirname "$0")" && pwd)"
if [[ -z "$ADAPTER" ]]; then
echo "usage: $0 [target-dir]" >&2
- echo "adapters: claude-code cursor windsurf opencode openclaw hermes pi standalone-python antigravity" >&2
+ echo "adapters: claude-code cursor windsurf opencode openclaw hermes pi codex standalone-python antigravity" >&2
exit 2
fi
@@ -171,6 +171,55 @@ case "$ADAPTER" in
cp "$HERE/.agent/harness/hooks/pi_post_tool.py" "$TARGET/.agent/harness/hooks/pi_post_tool.py"
echo " + .agent/harness/hooks/pi_post_tool.py (synced for upgrades)"
;;
+ codex)
+ # codex reads AGENTS.md (like pi, hermes, opencode). Many other tools
+ # also write AGENTS.md (aider, amp, cline, existing codex setups), so
+ # we follow the openclaw pattern: merge-or-alert, never blind overwrite,
+ # never blind skip.
+ if [[ -f "$TARGET/AGENTS.md" ]]; then
+ if grep -q '\.agent/' "$TARGET/AGENTS.md" 2>/dev/null; then
+ echo " ~ AGENTS.md already references .agent/ — leaving alone"
+ else
+ echo " ! AGENTS.md exists but does not reference .agent/; not overwriting."
+ echo " merge this block into your AGENTS.md to wire the brain:"
+ echo " ---8<---"
+ sed 's/^/ /' "$SRC/AGENTS.md"
+ echo " --->8---"
+ fi
+ else
+ cp "$SRC/AGENTS.md" "$TARGET/AGENTS.md"
+ echo " + AGENTS.md"
+ fi
+
+ # Codex scans .agents/skills/ (plural) for repo-scoped skills — per
+ # OpenAI docs https://developers.openai.com/codex/skills. Keep the
+ # portable brain authoritative: .agents/skills mirrors .agent/skills.
+ mkdir -p "$TARGET/.agents"
+ SKILLS_SRC="$(cd "$TARGET/.agent/skills" && pwd)"
+ SKILLS_DEST="$TARGET/.agents/skills"
+ if [[ -L "$SKILLS_DEST" ]]; then
+ # Existing symlink: repoint at current .agent/skills (cheap, safe)
+ ln -sfn "$SKILLS_SRC" "$SKILLS_DEST"
+ echo " + .agents/skills -> $SKILLS_SRC"
+ elif [[ -d "$SKILLS_DEST" ]]; then
+ # Real directory from a prior copy-fallback install: sync with
+ # delete-orphans so removed/renamed skills don't linger. Use rsync
+ # if available, otherwise rm+cp as a safe-but-blunt replacement.
+ if command -v rsync >/dev/null 2>&1; then
+ rsync -a --delete "$SKILLS_SRC/" "$SKILLS_DEST/"
+ echo " ~ synced .agent/skills → .agents/skills (rsync --delete)"
+ else
+ rm -rf "$SKILLS_DEST"
+ cp -R "$SKILLS_SRC" "$SKILLS_DEST"
+ echo " ~ replaced .agents/skills with current .agent/skills (no rsync)"
+ fi
+ elif ln -sfn "$SKILLS_SRC" "$SKILLS_DEST" 2>/dev/null; then
+ echo " + .agents/skills -> $SKILLS_SRC"
+ else
+ cp -R "$SKILLS_SRC" "$SKILLS_DEST"
+ echo " + .agents/skills (copy; symlink not supported here)"
+ fi
+ ;;
standalone-python)
cp "$SRC/run.py" "$TARGET/run.py"
;;