fix(web): honor XDG_CONFIG_HOME for OpenCode paths (#3305)

Closes #3304. Thanks for consolidating the global OpenCode paths. VS Code path parity and effective-path display follow-ups are maintainer-owned.
This commit is contained in:
tdoherty
2026-09-05 02:14:26 +03:00
committed by GitHub
parent 64f9f3aba7
commit 0543b954c3
11 changed files with 130 additions and 17 deletions
@@ -58,7 +58,7 @@ The following functions are internal helpers used by exported functions:
- `safeRm(dir)`: Safely remove directory recursively (ignores errors).
- `ensureDir(dirPath)`: Ensure directory exists with recursive creation.
- `copyDirectoryNoSymlinks(srcDir, dstDir)`: Copy directory contents without symlinks, with path traversal protection.
- `normalizeUserSkillDir(userSkillDir)`: Normalize user skill directory path (handles legacy `~/.config/opencode/skill` → `~/.config/opencode/skills` migration).
- `normalizeUserSkillDir(userSkillDir)`: Normalize the user skill directory path (handles the legacy `skill` directory in the XDG config location, or `~/.config/opencode/skill` when XDG is unset, by selecting the plural `skills` directory when appropriate).
### Git Clone Helpers (`install.js`, `scan.js`)
- `cloneRepo({ cloneUrl, identity, tempDir })`: Clone git repository with preferred partial clone (`--filter=blob:none`) and fallback. Uses non-interactive mode.
@@ -4,13 +4,14 @@ import path from 'path';
import { assertGitAvailable, looksLikeAuthError, runGit } from './git.js';
import { parseSkillRepoSource } from './source.js';
import { OPENCODE_CONFIG_DIR } from '../opencode/shared.js';
const SKILL_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/;
function normalizeUserSkillDir(userSkillDir) {
if (!userSkillDir) return null;
const legacySkillDir = path.join(os.homedir(), '.config', 'opencode', 'skill');
const pluralSkillDir = path.join(os.homedir(), '.config', 'opencode', 'skills');
const legacySkillDir = path.join(OPENCODE_CONFIG_DIR, 'skill');
const pluralSkillDir = path.join(OPENCODE_CONFIG_DIR, 'skills');
if (userSkillDir === legacySkillDir) {
if (fs.existsSync(legacySkillDir) && !fs.existsSync(pluralSkillDir)) return legacySkillDir;
return pluralSkillDir;