diff --git a/hosts/codex.ts b/hosts/codex.ts
index 7dc80ea87..0ea9ea61a 100644
--- a/hosts/codex.ts
+++ b/hosts/codex.ts
@@ -29,6 +29,7 @@ const codex: HostConfig = {
{ from: '.claude/skills/gstack', to: '.agents/skills/gstack' },
{ from: '.claude/skills/review', to: '.agents/skills/gstack/review' },
{ from: '.claude/skills', to: '.agents/skills' },
+ { from: 'CLAUDE.md', to: 'AGENTS.md' },
],
suppressedResolvers: [
diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md
index d99630c4b..957e2d784 100644
--- a/test/fixtures/golden/codex-ship-SKILL.md
+++ b/test/fixtures/golden/codex-ship-SKILL.md
@@ -96,7 +96,7 @@ else
fi
$GSTACK_BIN/gstack-timeline-log '{"skill":"ship","event":"started","branch":"'"$_BRANCH"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null &
_HAS_ROUTING="no"
-if [ -f CLAUDE.md ] && grep -q "## Skill routing" CLAUDE.md 2>/dev/null; then
+if [ -f AGENTS.md ] && grep -q "## Skill routing" AGENTS.md 2>/dev/null; then
_HAS_ROUTING="yes"
fi
_ROUTING_DECLINED=$($GSTACK_BIN/gstack-config get routing_declined 2>/dev/null || echo "false")
@@ -245,17 +245,17 @@ Then run `touch ~/.gstack/.first-loop-tip-shown 2>/dev/null || true`.
Skip this section if `ACTIVATED` and `FIRST_LOOP_SHOWN` are both `yes`.
If `HAS_ROUTING` is `no` AND `ROUTING_DECLINED` is `false` AND `PROACTIVE_PROMPTED` is `yes`:
-Check if a CLAUDE.md file exists in the project root. If it does not exist, create it.
+Check if a AGENTS.md file exists in the project root. If it does not exist, create it.
Use AskUserQuestion:
-> gstack works best when your project's CLAUDE.md includes skill routing rules.
+> gstack works best when your project's AGENTS.md includes skill routing rules.
Options:
-- A) Add routing rules to CLAUDE.md (recommended)
+- A) Add routing rules to AGENTS.md (recommended)
- B) No thanks, I'll invoke skills manually
-If A: Append this section to the end of CLAUDE.md:
+If A: Append this section to the end of AGENTS.md:
```markdown
@@ -279,7 +279,7 @@ Key routing rules:
- Author a backlog-ready spec/issue → invoke /spec
```
-Then commit the change: `git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"`
+Then commit the change: `git add AGENTS.md && git commit -m "chore: add gstack skill routing rules to AGENTS.md"`
If B: run `$GSTACK_BIN/gstack-config set routing_declined true` and say they can re-enable with `gstack-config set routing_declined false`.
@@ -298,7 +298,7 @@ If A:
1. Run `git rm -r .agents/skills/gstack/`
2. Run `echo '.agents/skills/gstack/' >> .gitignore`
3. Run `$GSTACK_BIN/gstack-team-init required` (or `optional`)
-4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"`
+4. Run `git add .claude/ .gitignore AGENTS.md && git commit -m "chore: migrate gstack from vendored to team mode"`
5. Tell the user: "Done. Each developer now runs: `cd $GSTACK_ROOT && ./setup --team`"
If B: say "OK, you're on your own to keep the vendored copy up to date."
@@ -475,7 +475,7 @@ if [ -f "$_GBRAIN_CONFIG" ] && command -v gbrain >/dev/null 2>&1; then
if [ -n "$_GBRAIN_PIN_PATH" ]; then
echo "GBrain configured. Prefer \`gbrain search\`/\`gbrain query\` over Grep for"
echo "semantic questions; use \`gbrain code-def\`/\`code-refs\`/\`code-callers\` for"
- echo "symbol-aware code lookup. See \"## GBrain Search Guidance\" in CLAUDE.md."
+ echo "symbol-aware code lookup. See \"## GBrain Search Guidance\" in AGENTS.md."
echo "Run /sync-gbrain to refresh."
else
echo "GBrain configured but this worktree isn't pinned yet. Run \`/sync-gbrain --full\`"
@@ -1117,9 +1117,9 @@ Write TESTING.md with:
- Test layers: Unit tests (what, where, when), Integration tests, Smoke tests, E2E tests
- Conventions: file naming, assertion style, setup/teardown patterns
-### B7. Update CLAUDE.md
+### B7. Update AGENTS.md
-First check: If CLAUDE.md already has a `## Testing` section → skip. Don't duplicate.
+First check: If AGENTS.md already has a `## Testing` section → skip. Don't duplicate.
Append a `## Testing` section:
- Run command and test directory
@@ -1138,7 +1138,7 @@ Append a `## Testing` section:
git status --porcelain
```
-Only commit if there are changes. Stage all bootstrap files (config, test directory, TESTING.md, CLAUDE.md, .github/workflows/test.yml if created):
+Only commit if there are changes. Stage all bootstrap files (config, test directory, TESTING.md, AGENTS.md, .github/workflows/test.yml if created):
`git commit -m "chore: bootstrap test framework ({framework name})"`
---
@@ -1283,7 +1283,7 @@ Evals are mandatory when prompt-related files change. Skip this step entirely if
git diff origin/ --name-only
```
-Match against these patterns (from CLAUDE.md):
+Match against these patterns (from AGENTS.md):
- `app/services/*_prompt_builder.rb`
- `app/services/*_generation_service.rb`, `*_writer_service.rb`, `*_designer_service.rb`
- `app/services/*_evaluator.rb`, `*_scorer.rb`, `*_classifier_service.rb`, `*_analyzer.rb`
@@ -1365,8 +1365,8 @@ poller is reaped.
Before analyzing coverage, detect the project's test framework:
-1. **Read CLAUDE.md** — look for a `## Testing` section with test command and framework name. If found, use that as the authoritative source.
-2. **If CLAUDE.md has no testing section, auto-detect:**
+1. **Read AGENTS.md** — look for a `## Testing` section with test command and framework name. If found, use that as the authoritative source.
+2. **If AGENTS.md has no testing section, auto-detect:**
```bash
setopt +o nomatch 2>/dev/null || true # zsh compat
@@ -1533,7 +1533,7 @@ Coverage line: `Test Coverage Audit: N new code paths. M covered (X%). K tests g
**7. Coverage gate:**
-Before proceeding, check CLAUDE.md for a `## Test Coverage` section with `Minimum:` and `Target:` fields. If found, use those percentages. Otherwise use defaults: Minimum = 60%, Target = 80%.
+Before proceeding, check AGENTS.md for a `## Test Coverage` section with `Minimum:` and `Target:` fields. If found, use those percentages. Otherwise use defaults: Minimum = 60%, Target = 80%.
Using the coverage percentage from the diagram in substep 4 (the `COVERAGE: X/Y (Z%)` line):
@@ -2533,7 +2533,7 @@ git push -u origin
> You are executing the /document-release workflow after a code push. Read the full skill file `${HOME}/.agents/skills/gstack/document-release/SKILL.md` and execute its complete workflow end-to-end, including CHANGELOG clobber protection, doc exclusions, risky-change gates, and named staging. Do NOT attempt to edit the PR body — no PR exists yet. Branch: ``, base: ``.
>
> After completing the workflow, output a single JSON object on the LAST LINE of your response (no other text after it):
-> `{"files_updated":["README.md","CLAUDE.md",...],"commit_sha":"abc1234","pushed":true,"documentation_section":""}`
+> `{"files_updated":["README.md","AGENTS.md",...],"commit_sha":"abc1234","pushed":true,"documentation_section":""}`
>
> If no documentation files needed updating, output:
> `{"files_updated":[],"commit_sha":null,"pushed":false,"documentation_section":null}`
diff --git a/test/host-config.test.ts b/test/host-config.test.ts
index 1c939d7be..dabaa83cb 100644
--- a/test/host-config.test.ts
+++ b/test/host-config.test.ts
@@ -481,6 +481,10 @@ describe('host config correctness', () => {
expect(codex.generation.metadataFormat).toBe('openai.yaml');
});
+ test('codex rewrites CLAUDE.md to AGENTS.md', () => {
+ expect(codex.pathRewrites).toContainEqual({ from: 'CLAUDE.md', to: 'AGENTS.md' });
+ });
+
test('codex has sidecar config', () => {
expect(codex.sidecar).toBeDefined();
expect(codex.sidecar!.path).toBe('.agents/skills/gstack');