mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 08:17:11 +00:00
fix(postinstall): handle broken symlinks during npm install
When upgrading from older CCS versions, ~/.ccs/shared/* directories may exist as broken symlinks (dangling symlinks pointing to deleted targets). Problem: - fs.existsSync() returns false for broken symlinks - fs.mkdirSync() fails with ENOENT because path exists as broken symlink Solution: - Added removeIfBrokenSymlink() helper that detects and removes dangling symlinks using lstatSync (doesn't follow symlinks) + statSync (follows) - Applied to shared directory and all subdirectories before mkdir Fixes npm install error: ENOENT: no such file or directory, mkdir
This commit is contained in:
@@ -24,6 +24,35 @@ function getCcsHome() {
|
||||
return process.env.CCS_HOME || os.homedir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if path is a broken symlink and remove it if so
|
||||
* Fixes: ENOENT error when mkdir tries to create over a dangling symlink
|
||||
* @param {string} targetPath - Path to check
|
||||
* @returns {boolean} true if broken symlink was removed
|
||||
*/
|
||||
function removeIfBrokenSymlink(targetPath) {
|
||||
try {
|
||||
// lstatSync doesn't follow symlinks - it checks the link itself
|
||||
const stats = fs.lstatSync(targetPath);
|
||||
if (stats.isSymbolicLink()) {
|
||||
// Check if symlink target exists
|
||||
try {
|
||||
fs.statSync(targetPath); // This follows symlinks
|
||||
return false; // Symlink is valid
|
||||
} catch {
|
||||
// Target doesn't exist - broken symlink
|
||||
fs.unlinkSync(targetPath);
|
||||
console.log(`[!] Removed broken symlink: ${targetPath}`);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch {
|
||||
// Path doesn't exist at all
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate created configuration files
|
||||
* @returns {object} { success: boolean, errors: string[], warnings: string[] }
|
||||
@@ -85,6 +114,8 @@ function createConfigFiles() {
|
||||
|
||||
// Create ~/.ccs/shared/ directory structure (Phase 1)
|
||||
const sharedDir = path.join(ccsDir, 'shared');
|
||||
// Handle broken symlinks (common when upgrading from older versions)
|
||||
removeIfBrokenSymlink(sharedDir);
|
||||
if (!fs.existsSync(sharedDir)) {
|
||||
fs.mkdirSync(sharedDir, { recursive: true, mode: 0o755 });
|
||||
console.log('[OK] Created directory: ~/.ccs/shared/');
|
||||
@@ -94,6 +125,8 @@ function createConfigFiles() {
|
||||
const sharedSubdirs = ['commands', 'skills', 'agents', 'plugins'];
|
||||
for (const subdir of sharedSubdirs) {
|
||||
const subdirPath = path.join(sharedDir, subdir);
|
||||
// Handle broken symlinks before creating directory
|
||||
removeIfBrokenSymlink(subdirPath);
|
||||
if (!fs.existsSync(subdirPath)) {
|
||||
fs.mkdirSync(subdirPath, { recursive: true, mode: 0o755 });
|
||||
console.log(`[OK] Created directory: ~/.ccs/shared/${subdir}/`);
|
||||
|
||||
Reference in New Issue
Block a user