fix(scripts): add os.homedir() fallback for Windows compatibility

On Windows (native cmd/PowerShell), process.env.HOME is undefined.
Seven CLI entry points and two library files pass process.env.HOME
directly as homeDir without a cross-platform fallback, causing all
path resolutions to silently fail (resolving to "undefined/.claude/...").

Node.js os.homedir() correctly handles all platforms (HOME on Unix,
USERPROFILE on Windows, OS-level fallback). The project already uses
this pattern in scripts/lib/state-store/index.js and has a getHomeDir()
utility in scripts/lib/utils.js, but it was not applied consistently.

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

Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
This commit is contained in:
Lidang-Jiang
2026-03-28 11:28:12 +08:00
parent 8b6140dedc
commit ae21a8df85
9 changed files with 20 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
const os = require('os');
const { buildDoctorReport } = require('./lib/install-lifecycle'); const { buildDoctorReport } = require('./lib/install-lifecycle');
const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests'); const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests');
@@ -88,7 +89,7 @@ function main() {
const report = buildDoctorReport({ const report = buildDoctorReport({
repoRoot: require('path').join(__dirname, '..'), repoRoot: require('path').join(__dirname, '..'),
homeDir: process.env.HOME, homeDir: process.env.HOME || os.homedir(),
projectRoot: process.cwd(), projectRoot: process.cwd(),
targets: options.targets, targets: options.targets,
}); });

View File

@@ -6,6 +6,7 @@
* target-specific mutation logic into testable Node code. * target-specific mutation logic into testable Node code.
*/ */
const os = require('os');
const { const {
SUPPORTED_INSTALL_TARGETS, SUPPORTED_INSTALL_TARGETS,
listLegacyCompatibilityLanguages, listLegacyCompatibilityLanguages,
@@ -118,7 +119,7 @@ function main() {
}); });
const plan = createInstallPlanFromRequest(request, { const plan = createInstallPlanFromRequest(request, {
projectRoot: process.cwd(), projectRoot: process.cwd(),
homeDir: process.env.HOME, homeDir: process.env.HOME || os.homedir(),
claudeRulesDir: process.env.CLAUDE_RULES_DIR || null, claudeRulesDir: process.env.CLAUDE_RULES_DIR || null,
}); });

View File

@@ -1,4 +1,5 @@
const fs = require('fs'); const fs = require('fs');
const os = require('os');
const path = require('path'); const path = require('path');
const { execFileSync } = require('child_process'); const { execFileSync } = require('child_process');
@@ -442,7 +443,7 @@ function planAntigravityLegacyInstall(context) {
function createLegacyInstallPlan(options = {}) { function createLegacyInstallPlan(options = {}) {
const sourceRoot = options.sourceRoot || getSourceRoot(); const sourceRoot = options.sourceRoot || getSourceRoot();
const projectRoot = options.projectRoot || process.cwd(); const projectRoot = options.projectRoot || process.cwd();
const homeDir = options.homeDir || process.env.HOME; const homeDir = options.homeDir || process.env.HOME || os.homedir();
const target = options.target || 'claude'; const target = options.target || 'claude';
validateLegacyTarget(target); validateLegacyTarget(target);

View File

@@ -1,4 +1,5 @@
const fs = require('fs'); const fs = require('fs');
const os = require('os');
const path = require('path'); const path = require('path');
const { resolveInstallPlan, loadInstallManifests } = require('./install-manifests'); const { resolveInstallPlan, loadInstallManifests } = require('./install-manifests');
@@ -696,7 +697,7 @@ function buildDiscoveryRecord(adapter, context) {
function discoverInstalledStates(options = {}) { function discoverInstalledStates(options = {}) {
const context = { const context = {
homeDir: options.homeDir || process.env.HOME, homeDir: options.homeDir || process.env.HOME || os.homedir(),
projectRoot: options.projectRoot || process.cwd(), projectRoot: options.projectRoot || process.cwd(),
}; };
const targets = normalizeTargets(options.targets); const targets = normalizeTargets(options.targets);
@@ -904,7 +905,7 @@ function buildDoctorReport(options = {}) {
}).filter(record => record.exists); }).filter(record => record.exists);
const context = { const context = {
repoRoot, repoRoot,
homeDir: options.homeDir || process.env.HOME, homeDir: options.homeDir || process.env.HOME || os.homedir(),
projectRoot: options.projectRoot || process.cwd(), projectRoot: options.projectRoot || process.cwd(),
manifestVersion: manifests.modulesVersion, manifestVersion: manifests.modulesVersion,
packageVersion: readPackageVersion(repoRoot), packageVersion: readPackageVersion(repoRoot),
@@ -988,7 +989,7 @@ function repairInstalledStates(options = {}) {
const manifests = loadInstallManifests({ repoRoot }); const manifests = loadInstallManifests({ repoRoot });
const context = { const context = {
repoRoot, repoRoot,
homeDir: options.homeDir || process.env.HOME, homeDir: options.homeDir || process.env.HOME || os.homedir(),
projectRoot: options.projectRoot || process.cwd(), projectRoot: options.projectRoot || process.cwd(),
manifestVersion: manifests.modulesVersion, manifestVersion: manifests.modulesVersion,
packageVersion: readPackageVersion(repoRoot), packageVersion: readPackageVersion(repoRoot),

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
const os = require('os');
const { discoverInstalledStates } = require('./lib/install-lifecycle'); const { discoverInstalledStates } = require('./lib/install-lifecycle');
const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests'); const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests');
@@ -70,7 +71,7 @@ function main() {
} }
const records = discoverInstalledStates({ const records = discoverInstalledStates({
homeDir: process.env.HOME, homeDir: process.env.HOME || os.homedir(),
projectRoot: process.cwd(), projectRoot: process.cwd(),
targets: options.targets, targets: options.targets,
}).filter(record => record.exists); }).filter(record => record.exists);

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
const os = require('os');
const { repairInstalledStates } = require('./lib/install-lifecycle'); const { repairInstalledStates } = require('./lib/install-lifecycle');
const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests'); const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests');
@@ -74,7 +75,7 @@ function main() {
const result = repairInstalledStates({ const result = repairInstalledStates({
repoRoot: require('path').join(__dirname, '..'), repoRoot: require('path').join(__dirname, '..'),
homeDir: process.env.HOME, homeDir: process.env.HOME || os.homedir(),
projectRoot: process.cwd(), projectRoot: process.cwd(),
targets: options.targets, targets: options.targets,
dryRun: options.dryRun, dryRun: options.dryRun,

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
'use strict'; 'use strict';
const os = require('os');
const { createStateStore } = require('./lib/state-store'); const { createStateStore } = require('./lib/state-store');
function showHelp(exitCode = 0) { function showHelp(exitCode = 0) {
@@ -134,7 +135,7 @@ async function main() {
store = await createStateStore({ store = await createStateStore({
dbPath: options.dbPath, dbPath: options.dbPath,
homeDir: process.env.HOME, homeDir: process.env.HOME || os.homedir(),
}); });
if (!options.sessionId) { if (!options.sessionId) {

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
'use strict'; 'use strict';
const os = require('os');
const { createStateStore } = require('./lib/state-store'); const { createStateStore } = require('./lib/state-store');
function showHelp(exitCode = 0) { function showHelp(exitCode = 0) {
@@ -139,7 +140,7 @@ async function main() {
store = await createStateStore({ store = await createStateStore({
dbPath: options.dbPath, dbPath: options.dbPath,
homeDir: process.env.HOME, homeDir: process.env.HOME || os.homedir(),
}); });
const payload = { const payload = {

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
const os = require('os');
const { uninstallInstalledStates } = require('./lib/install-lifecycle'); const { uninstallInstalledStates } = require('./lib/install-lifecycle');
const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests'); const { SUPPORTED_INSTALL_TARGETS } = require('./lib/install-manifests');
@@ -73,7 +74,7 @@ function main() {
} }
const result = uninstallInstalledStates({ const result = uninstallInstalledStates({
homeDir: process.env.HOME, homeDir: process.env.HOME || os.homedir(),
projectRoot: process.cwd(), projectRoot: process.cwd(),
targets: options.targets, targets: options.targets,
dryRun: options.dryRun, dryRun: options.dryRun,