Skip to content

fix: respect XDG_DATA_HOME for auth sync paths#233

Open
exiast wants to merge 1 commit into
griffinmartin:mainfrom
exiast:fix/xdg-data-home-auth-path
Open

fix: respect XDG_DATA_HOME for auth sync paths#233
exiast wants to merge 1 commit into
griffinmartin:mainfrom
exiast:fix/xdg-data-home-auth-path

Conversation

@exiast

@exiast exiast commented May 28, 2026

Copy link
Copy Markdown

Summary

  • use XDG_DATA_HOME (when set) for OpenCode data dir on non-Windows
  • keep existing fallback to ~/.local/share/opencode
  • apply this to both auth.json sync path and claude-account-source.txt

Why

OpenCode can run with custom XDG paths. The plugin currently hardcodes ~/.local/share/opencode, so Anthropic creds are synced to a different location than the one OpenCode reads.

Verification

  • built with npm run build
  • verified behavior against custom XDG_DATA_HOME environment locally

Fixes #232.

@griffinmartin

Copy link
Copy Markdown
Owner

@greptileai

@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces a getOpencodeDataDir() helper that honours XDG_DATA_HOME on non-Windows platforms, fixing a mismatch where the plugin always wrote credentials to ~/.local/share/opencode while OpenCode itself could be configured to use a different XDG base directory.

  • New helper getOpencodeDataDir() centralises the data-directory resolution: on Windows it returns the existing hardcoded path; on other platforms it checks XDG_DATA_HOME before falling back to ~/.local/share/opencode.
  • Both sync targets updated: getAccountStateFile() (for claude-account-source.txt) and getAuthJsonPaths() (for auth.json) now call getOpencodeDataDir() instead of duplicating the hardcoded path.
  • Minor trim inconsistency: XDG_DATA_HOME is checked via .trim() for the guard but the original (potentially whitespace-padded) string is passed to join() — trimming the stored variable would make this safer.

Confidence Score: 4/5

Safe to merge; the change correctly wires XDG_DATA_HOME into both sync paths and preserves all existing fallbacks.

The refactor is small and the logic is straightforward. The only real wrinkle is that XDG_DATA_HOME is trimmed for the guard condition but used untrimmed when constructing the path — an edge case that would only bite a user whose environment variable contains surrounding whitespace, which is extremely rare in practice.

Files Needing Attention: src/credentials.ts — specifically the getOpencodeDataDir() function and whether the untrimmed value being passed to join() is intentional.

Important Files Changed

Filename Overview
src/credentials.ts Extracts a new getOpencodeDataDir() helper that respects XDG_DATA_HOME on non-Windows; both getAccountStateFile() and getAuthJsonPaths() now use it. Minor: the trim is applied only to the guard check, not to the value passed to join().

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[getOpencodeDataDir] --> B{process.platform === 'win32'?}
    B -- Yes --> C["~/.local/share/opencode (hardcoded)"]
    B -- No --> D{XDG_DATA_HOME set\nand non-blank?}
    D -- Yes --> E["join(XDG_DATA_HOME, 'opencode')"]
    D -- No --> F["~/.local/share/opencode (fallback)"]
    C --> G[getAccountStateFile]
    E --> G
    F --> G
    C --> H[getAuthJsonPaths]
    E --> H
    F --> H
    G --> I["claude-account-source.txt"]
    H --> J["auth.json (XDG path)"]
    H --> K{win32?}
    K -- Yes --> L["auth.json (LOCALAPPDATA path)"]
    K -- No --> M[return single path]
Loading

Fix All in Cursor Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
src/credentials.ts:73-76
The variable `xdgDataHome` is trimmed only for the length check but the **original untrimmed value** is passed to `join()`. If `XDG_DATA_HOME` contains leading or trailing whitespace (e.g. set via a shell script with a trailing space), `join(xdgDataHome, "opencode")` produces a path with embedded spaces that the OS will likely reject or silently misdirect — bypassing the fallback to `~/.local/share/opencode`.

```suggestion
  const xdgDataHome = process.env.XDG_DATA_HOME?.trim()
  if (xdgDataHome) {
    return join(xdgDataHome, "opencode")
  }
```

### Issue 2 of 2
src/credentials.ts:70-72
**Windows branch ignores XDG_DATA_HOME**

On Windows, `getOpencodeDataDir()` unconditionally returns `~/.local/share/opencode` without consulting `XDG_DATA_HOME`. This mirrors the pre-existing behaviour and keeps Windows handling consistent with `getAuthJsonPaths()`, which adds the proper `LOCALAPPDATA` path on top. However, if a Windows user sets `XDG_DATA_HOME` (e.g. running under WSL-inspired tooling), the variable is silently ignored for `claude-account-source.txt` while `getAuthJsonPaths()` still only checks it via `getOpencodeDataDir()` — so the behaviour is at least symmetric. Worth confirming this is intentional if Windows XDG support is ever planned.

Reviews (1): Last reviewed commit: "fix: respect XDG_DATA_HOME for auth path..." | Re-trigger Greptile

Comment thread src/credentials.ts
Comment on lines +73 to +76
const xdgDataHome = process.env.XDG_DATA_HOME
if (xdgDataHome && xdgDataHome.trim().length > 0) {
return join(xdgDataHome, "opencode")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The variable xdgDataHome is trimmed only for the length check but the original untrimmed value is passed to join(). If XDG_DATA_HOME contains leading or trailing whitespace (e.g. set via a shell script with a trailing space), join(xdgDataHome, "opencode") produces a path with embedded spaces that the OS will likely reject or silently misdirect — bypassing the fallback to ~/.local/share/opencode.

Suggested change
const xdgDataHome = process.env.XDG_DATA_HOME
if (xdgDataHome && xdgDataHome.trim().length > 0) {
return join(xdgDataHome, "opencode")
}
const xdgDataHome = process.env.XDG_DATA_HOME?.trim()
if (xdgDataHome) {
return join(xdgDataHome, "opencode")
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/credentials.ts
Line: 73-76

Comment:
The variable `xdgDataHome` is trimmed only for the length check but the **original untrimmed value** is passed to `join()`. If `XDG_DATA_HOME` contains leading or trailing whitespace (e.g. set via a shell script with a trailing space), `join(xdgDataHome, "opencode")` produces a path with embedded spaces that the OS will likely reject or silently misdirect — bypassing the fallback to `~/.local/share/opencode`.

```suggestion
  const xdgDataHome = process.env.XDG_DATA_HOME?.trim()
  if (xdgDataHome) {
    return join(xdgDataHome, "opencode")
  }
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Cursor Fix in Claude Code Fix in Codex

Comment thread src/credentials.ts
Comment on lines +70 to +72
if (process.platform === "win32") {
return join(homedir(), ".local", "share", "opencode")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Windows branch ignores XDG_DATA_HOME

On Windows, getOpencodeDataDir() unconditionally returns ~/.local/share/opencode without consulting XDG_DATA_HOME. This mirrors the pre-existing behaviour and keeps Windows handling consistent with getAuthJsonPaths(), which adds the proper LOCALAPPDATA path on top. However, if a Windows user sets XDG_DATA_HOME (e.g. running under WSL-inspired tooling), the variable is silently ignored for claude-account-source.txt while getAuthJsonPaths() still only checks it via getOpencodeDataDir() — so the behaviour is at least symmetric. Worth confirming this is intentional if Windows XDG support is ever planned.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/credentials.ts
Line: 70-72

Comment:
**Windows branch ignores XDG_DATA_HOME**

On Windows, `getOpencodeDataDir()` unconditionally returns `~/.local/share/opencode` without consulting `XDG_DATA_HOME`. This mirrors the pre-existing behaviour and keeps Windows handling consistent with `getAuthJsonPaths()`, which adds the proper `LOCALAPPDATA` path on top. However, if a Windows user sets `XDG_DATA_HOME` (e.g. running under WSL-inspired tooling), the variable is silently ignored for `claude-account-source.txt` while `getAuthJsonPaths()` still only checks it via `getOpencodeDataDir()` — so the behaviour is at least symmetric. Worth confirming this is intentional if Windows XDG support is ever planned.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Cursor Fix in Claude Code Fix in Codex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Respect XDG_DATA_HOME when syncing auth.json

2 participants