fix(isolation): add getCcsDir/getCcsHome to more files

Fix test isolation in symlink managers and checkers to prevent tests
from touching user's real ~/.ccs/ and ~/.claude/ directories.

Files fixed:
- src/api/services/profile-writer.ts - use getCcsDir()
- src/management/checks/symlink-check.ts - use functions instead of
  module-level constants
- src/utils/claude-dir-installer.ts - use getCcsDir() for CCS paths
- src/utils/claude-symlink-manager.ts - use getCcsHome()/getCcsDir()
This commit is contained in:
kaitranntt
2026-01-25 21:42:17 -05:00
parent 9b61f5318e
commit 6a2c82917d
4 changed files with 25 additions and 12 deletions
+1 -2
View File
@@ -3,7 +3,6 @@
* Supports both unified YAML config and legacy JSON config.
*/
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { getCcsDir, getConfigPath, loadConfigSafe } from '../../utils/config-manager';
import { expandPath } from '../../utils/helpers';
@@ -83,7 +82,7 @@ function createApiProfileUnified(
apiKey: string,
models: ModelMapping
): void {
const ccsDir = path.join(os.homedir(), '.ccs');
const ccsDir = getCcsDir();
const settingsFile = `${name}.settings.json`;
const settingsPath = path.join(ccsDir, settingsFile);
+17 -4
View File
@@ -7,11 +7,22 @@ import * as path from 'path';
import * as os from 'os';
import { ok, fail, warn } from '../../utils/ui';
import { HealthCheck, IHealthChecker, createSpinner } from './types';
import { getCcsDir } from '../../utils/config-manager';
const ora = createSpinner();
const homedir = os.homedir();
const ccsDir = path.join(homedir, '.ccs');
const claudeDir = path.join(homedir, '.claude');
// Get paths at runtime to respect CCS_HOME for test isolation
function getHomedir(): string {
return os.homedir();
}
function getCcsDirPath(): string {
return getCcsDir();
}
function getClaudeDir(): string {
return path.join(getHomedir(), '.claude');
}
/**
* Check file permissions on ~/.ccs/
@@ -21,7 +32,7 @@ export class PermissionsChecker implements IHealthChecker {
run(results: HealthCheck): void {
const spinner = ora('Checking permissions').start();
const testFile = path.join(ccsDir, '.permission-test');
const testFile = path.join(getCcsDirPath(), '.permission-test');
try {
fs.writeFileSync(testFile, 'test', 'utf8');
@@ -113,6 +124,8 @@ export class SettingsSymlinksChecker implements IHealthChecker {
run(results: HealthCheck): void {
const spinner = ora('Checking settings.json symlinks').start();
const label = 'settings.json';
const ccsDir = getCcsDirPath();
const claudeDir = getClaudeDir();
const sharedSettings = path.join(ccsDir, 'shared', 'settings.json');
const claudeSettings = path.join(claudeDir, 'settings.json');
+3 -3
View File
@@ -5,8 +5,8 @@
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import { ok, fail, warn, info } from './ui';
import { getCcsDir } from './config-manager';
// Ora fallback type for when ora is not available
interface OraSpinner {
@@ -60,8 +60,8 @@ export class ClaudeDirInstaller {
private ccsClaudeDir: string;
constructor() {
this.homeDir = os.homedir();
this.ccsClaudeDir = path.join(this.homeDir, '.ccs', '.claude');
this.homeDir = getCcsDir().replace(/\.ccs$/, ''); // Get home dir from CCS dir
this.ccsClaudeDir = path.join(getCcsDir(), '.claude');
}
/**
+4 -3
View File
@@ -14,8 +14,8 @@
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import { ok, fail, warn, info, color } from './ui';
import { getCcsDir, getCcsHome } from './config-manager';
// Ora fallback type for when ora is not available
interface OraSpinner {
@@ -71,8 +71,9 @@ export class ClaudeSymlinkManager {
private ccsItems: CcsItem[];
constructor() {
this.homeDir = os.homedir();
this.ccsClaudeDir = path.join(this.homeDir, '.ccs', '.claude');
// Use getCcsHome() for test isolation - respects CCS_HOME env var
this.homeDir = getCcsHome();
this.ccsClaudeDir = path.join(getCcsDir(), '.claude');
this.userClaudeDir = path.join(this.homeDir, '.claude');
// CCS items to symlink (selective, item-level)