#!/usr/bin/env node // CANONICAL — twin of scripts/analytics/src/utils/storage.ts:getDataRoot. // MUST STAY IN SYNC: identical default (~/.claude/linkedin-studio) + identical // LINKEDIN_STUDIO_DATA override semantics. A twin exists (not a shared import) // because the runtimes differ: hooks are plain .mjs run by Node with zero npm // deps and cannot import the TypeScript module (which needs tsx). Change one → // change the other; the twin-consistency test in __tests__/data-root.test.mjs // guards the contract behaviorally. import { join } from 'node:path'; import { homedir } from 'node:os'; import { fileURLToPath } from 'node:url'; // HOME with the codebase idiom (state-updater.mjs:11), but NEVER fall through to // '' — that would turn the absolute data path into a CWD-relative one. os.homedir() // is the floor (risk-assessor Low #2). function resolveHome() { return process.env.HOME || process.env.USERPROFILE || homedir(); } // Canonical per-user data root: ~/.claude/linkedin-studio (mirrors the state-file // location), overridable via LINKEDIN_STUDIO_DATA (test + power-user seam). // No-arg / '' returns the root itself; a subdir returns root/subdir. export function getDataRoot(subdir = '') { const dataBase = process.env.LINKEDIN_STUDIO_DATA || join(resolveHome(), '.claude', 'linkedin-studio'); return subdir ? join(dataBase, subdir) : dataBase; } // State file lives beside the data dir (mirrors state-updater.mjs:12). export function getStateFile() { return process.env.STATE_FILE || join(resolveHome(), '.claude', 'linkedin-studio.local.md'); } // Standalone: print the resolved paths for debugging (pattern: personalization-score.mjs:120). if (process.argv[1] === fileURLToPath(import.meta.url)) { console.log('data root:', getDataRoot()); console.log('analytics:', getDataRoot('analytics')); console.log('state file:', getStateFile()); }