MCPcopy
hub / github.com/codeaashu/claude-code / getProjectDirsUpToHome

Function getProjectDirsUpToHome

src/utils/markdownConfigLoader.ts:234–289  ·  view source on GitHub ↗
(
  subdir: ClaudeConfigDirectory,
  cwd: string,
)

Source from the content-addressed store, hash-verified

232 * @returns Array of directory paths containing .claude/subdir, from most specific (cwd) to least specific
233 */
234export function getProjectDirsUpToHome(
235 subdir: ClaudeConfigDirectory,
236 cwd: string,
237): string[] {
238 const home = resolve(homedir()).normalize('NFC')
239 const gitRoot = resolveStopBoundary(cwd)
240 let current = resolve(cwd)
241 const dirs: string[] = []
242
243 // Traverse from current directory up to git root (or home if not in a git repo)
244 while (true) {
245 // Stop if we've reached the home directory (don't check it, as it's loaded separately as userDir)
246 // Use normalized comparison to handle Windows drive letter casing (C:\ vs c:\)
247 if (
248 normalizePathForComparison(current) === normalizePathForComparison(home)
249 ) {
250 break
251 }
252
253 const claudeSubdir = join(current, '.claude', subdir)
254 // Filter to existing dirs. This is a perf filter (avoids spawning
255 // ripgrep on non-existent dirs downstream) and the worktree fallback
256 // in loadMarkdownFilesForSubdir relies on it. statSync + explicit error
257 // handling instead of existsSync — re-throws unexpected errors rather
258 // than silently swallowing them. Downstream loadMarkdownFiles handles
259 // the TOCTOU window (dir disappearing before read) gracefully.
260 try {
261 statSync(claudeSubdir)
262 dirs.push(claudeSubdir)
263 } catch (e: unknown) {
264 if (!isFsInaccessible(e)) throw e
265 }
266
267 // Stop after processing the git root directory - this prevents commands from parent
268 // directories outside the repository from appearing in the project
269 if (
270 gitRoot &&
271 normalizePathForComparison(current) ===
272 normalizePathForComparison(gitRoot)
273 ) {
274 break
275 }
276
277 // Move to parent directory
278 const parent = dirname(current)
279
280 // Safety check: if parent is the same as current, we've reached the root
281 if (parent === current) {
282 break
283 }
284
285 current = parent
286 }
287
288 return dirs
289}
290
291/**

Callers 2

loadSkillsDir.tsFile · 0.85

Calls 6

statSyncFunction · 0.90
resolveStopBoundaryFunction · 0.85
isFsInaccessibleFunction · 0.85
resolveFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected