fix(review): codex discovery honors CODEX_HOME (Bugbot finding) · Entire

fix(review): codex discovery honors CODEX_HOME (Bugbot finding)

bf34f40main·

peyton-alt·1w ago·2 files·+23 added/-4 removed

Discovery walked ~/.codex via UserHomeDir while every other codex-agent path resolves through resolveCodexHome, which honors CODEX_HOME — so skills installed under a custom codex home were invisible to discovery and spawn-time validation rejected saved $skills as 'not installed' even though codex itself finds and runs them. Discovery now uses the canonical resolution; the fake-home test helper also pins CODEX_HOME empty so a dev shell's value can't leak into the hermetic tests.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

Sessions

01KX0Y35F2WQNBG14701C9WNWFView transcript

[?
test(review): pin that codex $name skills survive the legacy repair + native invocationClaude Code·33 steps](/content/gh/entireio/cli/session/99f0d90a-6e31-4c60-ba62-aa2dccd29033#timeline-01KX0Y35F2WQNBG14701C9WNWF/index.html)

Changes

2

3 4 5 6 6 7 8 19 unmodified lines

28 29 30 32 31 32 33 34 34 35 36 37 37 38 39 40

2 unmodified lines

import ( "context" "log/slog" "os" "path/filepath"

"github.com/entireio/cli/cmd/entire/cli/agent" 19 unmodified lines

// //nolint:unparam // error return is part of SkillDiscoverer contract; future implementations may report hard failures func (c *CodexAgent) DiscoverReviewSkills(ctx context.Context) ([]agent.DiscoveredSkill, error) { home, err := os.UserHomeDir() // resolveCodexHome is the agent's canonical config-tree resolution // (honors CODEX_HOME) — discovery must see the same skills codex runs. codexHome, err := resolveCodexHome() if err != nil { logging.Debug(ctx, "codex discovery: UserHomeDir failed", slog.String("error", err.Error())) logging.Debug(ctx, "codex discovery: resolve codex home failed", slog.String("error", err.Error())) return nil, nil } codexHome := filepath.Join(home, ".codex")

form := skilldiscovery.DollarForm var found []agent.DiscoveredSkill


Mcmd/entire/cli/agent/codex/discovery.go+4/-4

18 unmodified lines

19 20 21 22 23 24 25 87 unmodified lines

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

18 unmodified lines

t.Helper() home := t.TempDir() t.Setenv("HOME", home) t.Setenv("CODEX_HOME", "") // hermetic: a dev shell's CODEX_HOME must not leak in return home }

87 unmodified lines

t.Errorf("want only $code-reviewer; got %+v", skills) }

// TestCodexAgent_DiscoverReviewSkills_HonorsCodexHome pins discovery to the // agent's canonical home resolution: the rest of the codex agent resolves its // config tree through resolveCodexHome (which honors CODEX_HOME), so skills // installed under a custom codex home must be discoverable too — otherwise // saved $skills fail spawn-time validation as "not installed" even though // codex itself finds and runs them. func TestCodexAgent_DiscoverReviewSkills_HonorsCodexHome(t *testing.T) { // Cannot t.Parallel — uses t.Setenv. withFakeHome(t) // HOME points at an empty dir; the skill lives elsewhere codexHome := t.TempDir() t.Setenv("CODEX_HOME", codexHome) writeSkill(t, codexHome, "skills/code-review", "code-review", "Reviews code.")

if !nameOf(discover(t), "$code-review") { t.Fatal("skill under CODEX_HOME not discovered — discovery must use resolveCodexHome, not ~/.codex") } }


Mcmd/entire/cli/agent/codex/discovery_test.go+19