Support CODEX_HOME environment variable (#1755)

* fix: run gh pr create from repo directory for old CLI compatibility

Older versions of the GitHub CLI (e.g., v2.4.0 on Ubuntu 22.04) require
running inside a git repository even when --repo is specified. This
change adds a repo_path parameter to create_pr that sets the working
directory when invoking gh, ensuring compatibility with older versions.

Changes:
- Add run_in_dir helper to GhCli for running commands in a specific directory
- Update create_pr to accept optional repo_path parameter
- Pass repo_path from the PR creation route where it's already available

Fixes #1665

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address review comments

- Remove redundant repo_path clone (use repo_path.clone() directly in closure)
- Use worktree_path instead of repo_path for gh pr create (consistent with git push)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Support CODEX_HOME environment variable for custom config location

Add a `codex_home()` helper function that checks the CODEX_HOME
environment variable first, then falls back to ~/.codex. This allows
users who have configured a custom Codex home directory to use
vibe-kanban without issues.

Fixes:
- Follow-up sessions not finding rollout files when CODEX_HOME is set
- MCP config not being detected from custom location
- Auth and installation detection checking wrong paths

Includes unit tests and documentation for the new feature.

Closes #1648

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Revert "fix: address review comments"

This reverts commit 44986bc6818f946834e5d4fe2196e1e06397c424.

* Revert "fix: run gh pr create from repo directory for old CLI compatibility"

This reverts commit b9e54e3c09b1ca86bc3624961c36880f58a8943f.

* address review feedback

* remove tests

---------

Co-authored-by: T Savo <tsavo@nightfall.ai>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Solomon <abcpro11051@disroot.org>
This commit is contained in:
T Savo
2026-01-13 04:15:28 -08:00
committed by GitHub
parent a3cdca742a
commit 34e1b688b1
3 changed files with 40 additions and 8 deletions

View File

@@ -5,10 +5,24 @@ pub mod review;
pub mod session;
use std::{
collections::HashMap,
env,
path::{Path, PathBuf},
sync::Arc,
};
/// Returns the Codex home directory.
///
/// Checks the `CODEX_HOME` environment variable first, then falls back to `~/.codex`.
/// This allows users to configure a custom location for Codex configuration and state.
pub fn codex_home() -> Option<PathBuf> {
if let Ok(codex_home) = env::var("CODEX_HOME")
&& !codex_home.trim().is_empty()
{
return Some(PathBuf::from(codex_home));
}
dirs::home_dir().map(|home| home.join(".codex"))
}
use async_trait::async_trait;
use codex_app_server_protocol::{NewConversationParams, ReviewTarget};
use codex_protocol::{
@@ -190,12 +204,12 @@ impl StandardCodingAgentExecutor for Codex {
}
fn default_mcp_config_path(&self) -> Option<PathBuf> {
dirs::home_dir().map(|home| home.join(".codex").join("config.toml"))
codex_home().map(|home| home.join("config.toml"))
}
fn get_availability_info(&self) -> AvailabilityInfo {
if let Some(timestamp) = dirs::home_dir()
.and_then(|home| std::fs::metadata(home.join(".codex").join("auth.json")).ok())
if let Some(timestamp) = codex_home()
.and_then(|home| std::fs::metadata(home.join("auth.json")).ok())
.and_then(|m| m.modified().ok())
.and_then(|modified| modified.duration_since(std::time::UNIX_EPOCH).ok())
.map(|d| d.as_secs() as i64)
@@ -210,8 +224,8 @@ impl StandardCodingAgentExecutor for Codex {
.map(|p| p.exists())
.unwrap_or(false);
let installation_indicator_found = dirs::home_dir()
.map(|home| home.join(".codex").join("version.json").exists())
let installation_indicator_found = codex_home()
.map(|home| home.join("version.json").exists())
.unwrap_or(false);
if mcp_config_found || installation_indicator_found {

View File

@@ -10,6 +10,8 @@ use regex::Regex;
use serde_json::{Map, Value};
use thiserror::Error;
use super::codex_home;
const FILENAME_TIMESTAMP_FORMAT: &str = "%Y-%m-%dT%H-%M-%S";
#[derive(Debug, Error)]
@@ -172,9 +174,10 @@ impl SessionHandler {
}
fn sessions_root() -> Result<PathBuf, SessionError> {
let home_dir = dirs::home_dir()
.ok_or_else(|| SessionError::Io("Could not determine home directory".to_string()))?;
Ok(home_dir.join(".codex").join("sessions"))
let codex_dir = codex_home().ok_or_else(|| {
SessionError::Io("Could not determine Codex home directory".to_string())
})?;
Ok(codex_dir.join("sessions"))
}
fn scan_directory(dir: &Path, session_id: &str) -> Result<PathBuf, SessionError> {

View File

@@ -27,3 +27,18 @@ icon: https://www.vibekanban.com/images/logos/openai-logo.svg
You can now select OpenAI Codex when creating task attempts.
</Step>
</Steps>
## Custom Configuration Directory
By default, Codex stores its configuration and session data in `~/.codex`. If you have configured a custom location using the `CODEX_HOME` environment variable, Vibe Kanban will automatically detect and use that location.
```bash
# Example: Using a project-specific Codex configuration
export CODEX_HOME=/path/to/custom/codex
npx vibe-kanban
```
This is useful for:
- Project-specific Codex profiles
- Separating work and personal configurations
- Custom automation setups