Skip to content

Commit 5113298

Browse files
authored
Merge pull request #16 from hovhannest/codex-adapter
Add codex adapter
2 parents 208cf73 + 62fc7b0 commit 5113298

8 files changed

Lines changed: 279 additions & 11 deletions

File tree

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**Keep one portable memory-and-skills layer across coding-agent harnesses, so switching tools doesn't reset how your agent works.**
44

5-
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.
5+
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.
66

77
<p align="center">
88
<img src="docs/demo.gif" alt="agentic-stack demo" width="880"/>
@@ -28,7 +28,7 @@ brew install agentic-stack
2828
# drop the brain into any project — the onboarding wizard runs automatically
2929
cd your-project
3030
agentic-stack claude-code
31-
# or: cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
31+
# or: cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
3232
```
3333

3434
### Windows (PowerShell)
@@ -52,7 +52,7 @@ brew update && brew upgrade agentic-stack
5252
git clone https://github.com/codejunkie99/agentic-stack.git
5353
cd agentic-stack && ./install.sh claude-code # mac / linux / git-bash
5454
# or on Windows PowerShell: .\install.ps1 claude-code
55-
# adapters: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
55+
# adapters: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
5656
```
5757

5858
## Onboarding wizard
@@ -122,7 +122,7 @@ See [`docs/architecture.md`](docs/architecture.md) for the full lifecycle.
122122
Every guide shows the folder structure. This repo gives you the folder
123123
structure **plus the files that actually go inside**: a working portable
124124
brain with five seed skills, four memory layers, enforced permissions, a
125-
nightly staging cycle, host-agent review tools, and adapters for eight
125+
nightly staging cycle, host-agent review tools, and adapters for multiple
126126
harnesses.
127127

128128
- **Memory**`working/`, `episodic/`, `semantic/`, `personal/`. Each
@@ -197,6 +197,7 @@ adapters/ # one small shim per harness
197197
├── openclaw/ (AGENTS.md + system-prompt include; auto-registers per-project agent)
198198
├── hermes/ (AGENTS.md)
199199
├── pi/ (AGENTS.md + .pi/skills symlink)
200+
├── codex/ (AGENTS.md)
200201
├── standalone-python/ (DIY conductor entrypoint)
201202
└── antigravity/ (ANTIGRAVITY.md)
202203
@@ -225,6 +226,7 @@ verify_codex_fixes.py # v0.8.0 regression checks (33 checks)
225226
| **OpenClaw** | `AGENTS.md` (auto-injected) + per-project `openclaw agents add --workspace` | varies by fork |
226227
| **Hermes Agent** | `AGENTS.md` (agentskills.io compatible) | partial (own memory) |
227228
| **Pi Coding Agent** | `AGENTS.md` + `.pi/skills/` + `.pi/extensions/` | yes (`tool_result` event) |
229+
| **Codex** | `AGENTS.md` + `.agents/skills/` | no (manual reflect calls) |
228230
| **Standalone Python** | `run.py` (any LLM) | yes (full control) |
229231
| **Antigravity** | `ANTIGRAVITY.md` | yes (system context) |
230232

adapters/codex/AGENTS.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# AGENTS.md — Codex adapter for agentic-stack
2+
3+
Codex reads `AGENTS.md` before doing any work. This file points it at
4+
the portable brain in `.agent/`.
5+
6+
> **Python invocation**: examples below use `python3`. On stock Windows
7+
> only `python` is on PATH; use whichever resolves on your system.
8+
9+
## Startup (read in order)
10+
1. `.agent/AGENTS.md` — the map
11+
2. `.agent/memory/personal/PREFERENCES.md` — user conventions
12+
3. `.agent/memory/semantic/LESSONS.md` — distilled lessons
13+
4. `.agent/protocols/permissions.md` — hard rules
14+
15+
## Skills
16+
Codex scans `.agents/skills/` for repository-scoped skills (per
17+
[OpenAI Codex docs](https://developers.openai.com/codex/skills)). The
18+
install script symlinks or syncs `.agents/skills` from `.agent/skills`
19+
so the portable brain remains the one source of truth. Load a full
20+
`SKILL.md` only when its triggers match the task (progressive
21+
disclosure). Edit skills in `.agent/skills/``.agents/skills/` is a
22+
mirror and re-running the installer will sync it back.
23+
24+
## Recall before non-trivial tasks
25+
For deploy / ship / migration / schema / timestamp / date / failing test /
26+
debug / refactor, FIRST run:
27+
28+
```bash
29+
python3 .agent/tools/recall.py "<description>"
30+
```
31+
32+
Surface results in a `Consulted lessons before acting:` block and follow
33+
them.
34+
35+
## Memory discipline
36+
- Update `.agent/memory/working/WORKSPACE.md` as you work.
37+
- After significant actions, run
38+
`python3 .agent/tools/memory_reflect.py <skill> <action> <outcome>`.
39+
- Never delete memory entries; archive only.
40+
- Quick state: `python3 .agent/tools/show.py`.
41+
- Teach a rule in one shot:
42+
`python3 .agent/tools/learn.py "<rule>" --rationale "<why>"`.
43+
44+
## Hard rules
45+
- No force push to `main`, `production`, `staging`.
46+
- No modification of `.agent/protocols/permissions.md`.

adapters/codex/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Codex adapter
2+
3+
## Install
4+
```bash
5+
./install.sh codex
6+
```
7+
8+
Or on Windows PowerShell:
9+
```powershell
10+
.\install.ps1 codex C:\path\to\your-project
11+
```
12+
13+
## What it wires up
14+
- `AGENTS.md` — Codex reads this natively as project instructions. If
15+
`AGENTS.md` already exists (for example from the pi, hermes, or
16+
opencode adapters), the installer leaves it in place.
17+
- `.agents/skills/``.agent/skills/` — Codex scans `.agents/skills/`
18+
for repository skills. The installer creates a symlink when possible
19+
and falls back to copying / merging when symlinks are unavailable.
20+
21+
## Verify
22+
Run Codex in the project and ask:
23+
24+
```bash
25+
codex --ask-for-approval never "Summarize the current instructions."
26+
```
27+
28+
It should mention `.agent/AGENTS.md` and the portable memory files.
29+
30+
Then ask:
31+
32+
```bash
33+
codex --ask-for-approval never "What's in my lessons file?"
34+
```
35+
36+
It should read `.agent/memory/semantic/LESSONS.md`.
37+
38+
## Notes
39+
- This adapter does **not** install Codex hooks. Codex hooks are still
40+
experimental, and the official docs note they are currently disabled
41+
on Windows. The adapter therefore relies on manual `recall.py` and
42+
`memory_reflect.py` calls, like the Cursor and Windsurf paths.
43+
- If `.agents/skills/` is a copied directory rather than a symlink,
44+
re-run the installer after editing `.agent/skills/` to sync updates.

docs/architecture.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ Three modules, one principle: the harness is dumb, the knowledge is in files.
3333
## Why the separation matters
3434

3535
You can swap the harness for any of the adapters (Claude Code, Cursor,
36-
Windsurf, OpenCode, OpenClaw, Hermes, standalone Python) and lose
37-
nothing. The brain is portable; only the glue changes.
36+
Windsurf, OpenCode, OpenClaw, Hermes, Pi, Codex, standalone Python,
37+
Antigravity) and lose nothing. The brain is portable; only the glue
38+
changes.
3839

3940
See `diagram.svg` for a visual.

docs/getting-started.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ cp /path/to/agentic-stack/install.sh ./
1616

1717
```bash
1818
./install.sh claude-code # or cursor, windsurf, opencode,
19-
# openclaw, hermes, standalone-python
19+
# openclaw, hermes, pi, codex,
20+
# standalone-python, antigravity
2021
```
2122

2223
Each adapter has its own `README.md` under `adapters/<name>/`.

docs/per-harness/codex.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Codex setup
2+
3+
[Codex](https://developers.openai.com/codex/) reads `AGENTS.md` natively
4+
and scans `.agents/skills/` for repository-scoped skills. Our adapter
5+
layers the portable `.agent/` brain on top so you keep one knowledge
6+
base even if you later swap harnesses.
7+
8+
## What the adapter installs
9+
- `AGENTS.md` at project root. Skipped if one already exists, since
10+
codex, pi, hermes, and opencode can all share the same file.
11+
- `.agents/skills/` symlinked to `.agent/skills/` when possible. Falls
12+
back to copying / merging on platforms without symlink support.
13+
14+
## Install
15+
```bash
16+
npm install -g @openai/codex
17+
./install.sh codex
18+
codex
19+
```
20+
21+
On Windows PowerShell:
22+
```powershell
23+
npm install -g @openai/codex
24+
.\install.ps1 codex C:\path\to\your-project
25+
codex
26+
```
27+
28+
## How it works
29+
- Codex loads `AGENTS.md` before starting work. The adapter file points
30+
it at `.agent/AGENTS.md`, `PREFERENCES.md`, `LESSONS.md`, and
31+
`permissions.md`.
32+
- Codex scans `.agents/skills/` from the current working directory up to
33+
the repository root. The adapter mirrors `.agent/skills/` there so the
34+
portable skills are visible without duplication.
35+
- The adapter intentionally does **not** install Codex hooks. The docs
36+
mark hooks experimental, and Windows support is currently disabled, so
37+
manual `recall.py` and `memory_reflect.py` calls remain the stable
38+
cross-platform path.
39+
40+
## Verify
41+
```bash
42+
codex --ask-for-approval never "Summarize the current instructions."
43+
codex --ask-for-approval never "What's in my lessons file?"
44+
```
45+
46+
Expected:
47+
- the first command mentions `.agent/AGENTS.md`
48+
- the second reads `.agent/memory/semantic/LESSONS.md`
49+
50+
## Troubleshooting
51+
- If Codex does not pick up `AGENTS.md`, restart it from the repository
52+
root and run the `Summarize the current instructions` check again.
53+
- If skills are missing, inspect `.agents/skills/`. On filesystems
54+
without symlink support, the installer copies / merges the directory
55+
instead; re-run the installer after updating `.agent/skills/`.
56+
- On Windows, the native sandbox is the default and works fine for this
57+
adapter. If your workflow needs Linux-native tooling, run Codex inside
58+
WSL2 instead.

install.ps1

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# install.ps1 — Windows PowerShell installer (parallel to install.sh)
22
# Usage: .\install.ps1 <adapter-name> [target-dir] [-Yes] [-Reconfigure] [-Force]
3-
# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
3+
# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
44
# target-dir: where your project lives (default: current dir)
55
# -Yes accept all wizard defaults (safe for CI)
66
# -Reconfigure re-run the wizard on an existing project
@@ -24,7 +24,7 @@ $Here = Split-Path -Parent $MyInvocation.MyCommand.Path
2424

2525
$ValidAdapters = @(
2626
'claude-code', 'cursor', 'windsurf',
27-
'opencode', 'openclaw', 'hermes', 'pi',
27+
'opencode', 'openclaw', 'hermes', 'pi', 'codex',
2828
'standalone-python', 'antigravity'
2929
)
3030
if ($Adapter -notin $ValidAdapters) {
@@ -190,6 +190,73 @@ switch ($Adapter) {
190190
Copy-Item (Join-Path $Here '.agent/harness/hooks/pi_post_tool.py') (Join-Path $hooksDir 'pi_post_tool.py') -Force
191191
Write-Host " + .agent/harness/hooks/pi_post_tool.py (synced for upgrades)"
192192
}
193+
'codex' {
194+
# Mirror install.sh: openclaw-style merge-or-alert on existing AGENTS.md.
195+
$agentsMd = Join-Path $TargetDir 'AGENTS.md'
196+
if (Test-Path $agentsMd -PathType Leaf) {
197+
$existing = Get-Content -Path $agentsMd -Raw -ErrorAction SilentlyContinue
198+
if ($existing -match '\.agent/') {
199+
Write-Host " ~ AGENTS.md already references .agent/ — leaving alone"
200+
} else {
201+
Write-Host " ! AGENTS.md exists but does not reference .agent/; not overwriting."
202+
Write-Host " merge this block into your AGENTS.md to wire the brain:"
203+
Write-Host " ---8<---"
204+
Get-Content -Path (Join-Path $Src 'AGENTS.md') | ForEach-Object { Write-Host " $_" }
205+
Write-Host " --->8---"
206+
}
207+
} else {
208+
Copy-Item (Join-Path $Src 'AGENTS.md') $agentsMd -Force
209+
Write-Host " + AGENTS.md"
210+
}
211+
212+
# Codex scans .agents/skills/ — keep the portable brain authoritative.
213+
$agentsDir = Join-Path $TargetDir '.agents'
214+
New-Item -ItemType Directory -Path $agentsDir -Force | Out-Null
215+
$skillsSrc = Join-Path $TargetAgent 'skills'
216+
$skillsDst = Join-Path $agentsDir 'skills'
217+
218+
# Detect symlink/junction BEFORE Remove-Item: on PowerShell 5.1
219+
# `Remove-Item -Recurse` on a symlink can delete the target's
220+
# contents. Use IsLink detection + .NET Delete (or repoint).
221+
$skillsDstItem = Get-Item -LiteralPath $skillsDst -Force -ErrorAction SilentlyContinue
222+
$isLink = $false
223+
if ($skillsDstItem) {
224+
$isLink = ($skillsDstItem.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -eq [System.IO.FileAttributes]::ReparsePoint
225+
}
226+
227+
if ($skillsDstItem -and $isLink) {
228+
# Existing link: delete the link only (NOT its target), then re-create.
229+
try {
230+
[System.IO.Directory]::Delete($skillsDst, $false)
231+
} catch {
232+
[System.IO.File]::Delete($skillsDst)
233+
}
234+
try {
235+
New-Item -ItemType SymbolicLink -Path $skillsDst -Target $skillsSrc -ErrorAction Stop | Out-Null
236+
Write-Host " + .agents/skills -> $skillsSrc (relinked)"
237+
} catch {
238+
Copy-Item -Path $skillsSrc -Destination $skillsDst -Recurse
239+
Write-Host " + .agents/skills (copy; symlink not supported here)"
240+
}
241+
} elseif ($skillsDstItem) {
242+
Remove-Item -LiteralPath $skillsDst -Recurse -Force
243+
try {
244+
New-Item -ItemType SymbolicLink -Path $skillsDst -Target $skillsSrc -ErrorAction Stop | Out-Null
245+
Write-Host " + .agents/skills -> $skillsSrc (replaced stale copy)"
246+
} catch {
247+
Copy-Item -Path $skillsSrc -Destination $skillsDst -Recurse
248+
Write-Host " ~ replaced .agents/skills with current .agent/skills (no symlink)"
249+
}
250+
} else {
251+
try {
252+
New-Item -ItemType SymbolicLink -Path $skillsDst -Target $skillsSrc -ErrorAction Stop | Out-Null
253+
Write-Host " + .agents/skills -> $skillsSrc"
254+
} catch {
255+
Copy-Item -Path $skillsSrc -Destination $skillsDst -Recurse
256+
Write-Host " + .agents/skills (copy; symlink not supported here)"
257+
}
258+
}
259+
}
193260
'standalone-python' {
194261
Copy-Item (Join-Path $Src 'run.py') (Join-Path $TargetDir 'run.py') -Force
195262
}

install.sh

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22
# install.sh — copy an adapter into the consuming project, then run the onboarding wizard
33
# Usage: ./install.sh <adapter-name> [target-dir] [--yes] [--reconfigure]
4-
# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | standalone-python | antigravity
4+
# adapter-name: claude-code | cursor | windsurf | opencode | openclaw | hermes | pi | codex | standalone-python | antigravity
55
# target-dir: where your project lives (default: current dir)
66
# --yes accept all wizard defaults without prompting (safe for CI)
77
# --reconfigure re-run the wizard even if PREFERENCES.md is already filled
@@ -13,7 +13,7 @@ HERE="$(cd "$(dirname "$0")" && pwd)"
1313

1414
if [[ -z "$ADAPTER" ]]; then
1515
echo "usage: $0 <adapter-name> [target-dir]" >&2
16-
echo "adapters: claude-code cursor windsurf opencode openclaw hermes pi standalone-python antigravity" >&2
16+
echo "adapters: claude-code cursor windsurf opencode openclaw hermes pi codex standalone-python antigravity" >&2
1717
exit 2
1818
fi
1919

@@ -171,6 +171,55 @@ case "$ADAPTER" in
171171
cp "$HERE/.agent/harness/hooks/pi_post_tool.py" "$TARGET/.agent/harness/hooks/pi_post_tool.py"
172172
echo " + .agent/harness/hooks/pi_post_tool.py (synced for upgrades)"
173173
;;
174+
codex)
175+
# codex reads AGENTS.md (like pi, hermes, opencode). Many other tools
176+
# also write AGENTS.md (aider, amp, cline, existing codex setups), so
177+
# we follow the openclaw pattern: merge-or-alert, never blind overwrite,
178+
# never blind skip.
179+
if [[ -f "$TARGET/AGENTS.md" ]]; then
180+
if grep -q '\.agent/' "$TARGET/AGENTS.md" 2>/dev/null; then
181+
echo " ~ AGENTS.md already references .agent/ — leaving alone"
182+
else
183+
echo " ! AGENTS.md exists but does not reference .agent/; not overwriting."
184+
echo " merge this block into your AGENTS.md to wire the brain:"
185+
echo " ---8<---"
186+
sed 's/^/ /' "$SRC/AGENTS.md"
187+
echo " --->8---"
188+
fi
189+
else
190+
cp "$SRC/AGENTS.md" "$TARGET/AGENTS.md"
191+
echo " + AGENTS.md"
192+
fi
193+
194+
# Codex scans .agents/skills/ (plural) for repo-scoped skills — per
195+
# OpenAI docs https://developers.openai.com/codex/skills. Keep the
196+
# portable brain authoritative: .agents/skills mirrors .agent/skills.
197+
mkdir -p "$TARGET/.agents"
198+
SKILLS_SRC="$(cd "$TARGET/.agent/skills" && pwd)"
199+
SKILLS_DEST="$TARGET/.agents/skills"
200+
if [[ -L "$SKILLS_DEST" ]]; then
201+
# Existing symlink: repoint at current .agent/skills (cheap, safe)
202+
ln -sfn "$SKILLS_SRC" "$SKILLS_DEST"
203+
echo " + .agents/skills -> $SKILLS_SRC"
204+
elif [[ -d "$SKILLS_DEST" ]]; then
205+
# Real directory from a prior copy-fallback install: sync with
206+
# delete-orphans so removed/renamed skills don't linger. Use rsync
207+
# if available, otherwise rm+cp as a safe-but-blunt replacement.
208+
if command -v rsync >/dev/null 2>&1; then
209+
rsync -a --delete "$SKILLS_SRC/" "$SKILLS_DEST/"
210+
echo " ~ synced .agent/skills → .agents/skills (rsync --delete)"
211+
else
212+
rm -rf "$SKILLS_DEST"
213+
cp -R "$SKILLS_SRC" "$SKILLS_DEST"
214+
echo " ~ replaced .agents/skills with current .agent/skills (no rsync)"
215+
fi
216+
elif ln -sfn "$SKILLS_SRC" "$SKILLS_DEST" 2>/dev/null; then
217+
echo " + .agents/skills -> $SKILLS_SRC"
218+
else
219+
cp -R "$SKILLS_SRC" "$SKILLS_DEST"
220+
echo " + .agents/skills (copy; symlink not supported here)"
221+
fi
222+
;;
174223
standalone-python)
175224
cp "$SRC/run.py" "$TARGET/run.py"
176225
;;

0 commit comments

Comments
 (0)