NAME
Developer::Dashboard::PathRegistry - logical directory registry
SYNOPSIS
my $paths = Developer::Dashboard::PathRegistry->new(home => $ENV{HOME});
my $root = $paths->current_project_root;
DESCRIPTION
This module provides the central logical directory registry used across the dashboard runtime, shell helpers, and background services.
METHODS
new
Construct the path registry.
resolve_dir, resolve_any, locate_projects, locate_dirs_under, current_project_root, project_root_for
Resolve and discover project-related directories.
resolve_dir() (DD-1005) additionally creates a registered alias's target directory (with parents) on first resolution when that alias was saved with create => 1 (see Developer::Dashboard::Config's save_global_path_alias()/save_skill_path_alias() %opts), chmod'ing it to the alias's stored octal mode when one was given. named_paths() collapses such an alias back to a bare path string for display consumers (dashboard path list, prefix completion) that have no use for the metadata; resolve_dir() itself always reads the raw internal registration, so the create/mode metadata is never lost between the two.
current_working_directory, cwd
Report the effective working directory: the explicit constructor cwd when one was supplied, otherwise a live in-process getcwd lookup that follows later chdir calls without forking an external pwd process (undef when the directory is unavailable). cwd is the public compatibility alias consumed by the file registry.
validated_path_segments
Package function that splits one untrusted relative path into its separator-delimited segments and rejects any shape able to escape the directory it will be joined onto: missing or empty paths, NUL or other control bytes, backslash separators, absolute paths, Windows drive prefixes, and empty, current-directory, or parent-directory segments. Returns the validated segment list (segment count in scalar context) or an empty list (undef in scalar context) on rejection. skill_layers requires exactly one validated segment for a skill name, and the skill dispatcher and web layer reuse this guard for every skill-namespaced route, ajax, and static asset path.
runtime_root, cache_root, home_runtime_root, home_cache_root
Report the layered runtime directories. runtime_root and cache_root follow the deepest discovered layer, which is the write target for layered runtime state. At each depth, both existing .d2/ and .developer-dashboard/ roots are independently discoverable; .developer-dashboard/ wins same-depth lookup precedence and remains the write target when both exist. home_runtime_root and home_cache_root stay pinned to the selected home write root, for per-user artifacts that a fixed external consumer reads from one well-known path.
alias_cache_key
Build the cache key that tells configured-alias consumers whether the runtime layout they cached against is still the current one. Called as a plain function rather than a method, because it must return an empty key for a missing or unblessed argument instead of dying on a method call. Developer::Dashboard::File and Developer::Dashboard::Folder both delegate to it; each previously carried its own identical copy of the computation.
PURPOSE
This module is the authoritative path model for the runtime. It discovers both supported runtime directory names from home to the current project, resolves standard runtime directories, manages named path aliases, and performs project and directory searches such as the regex-based narrowing used by cdr.
WHY IT EXISTS
It exists because DD-OOP-LAYERS is a cross-runtime contract, not a convenience helper. One path registry has to own how home and project runtimes participate, how parallel .d2/ and .developer-dashboard/ roots are ordered, which layer is writable, and how named paths and directory searches behave on top of that model.
WHEN TO USE
Use this file when changing layered runtime discovery, the writable runtime root, named alias behavior, project lookup, or directory-search semantics used by shell navigation helpers.
HOW TO USE
Construct it with the current home and cwd context, then ask it for runtime roots, named paths, or search results. Avoid rebuilding runtime path math elsewhere; other modules should consume this registry instead.
WHAT USES IT
It is used throughout the runtime by file, config, page, collector, prompt, shell-bootstrap, and CLI path logic, plus the tests that verify layered runtime behavior.
EXAMPLES
Example 1:
perl -Ilib -MDeveloper::Dashboard::PathRegistry -e 1
Do a direct compile-and-load check against the module from a source checkout.
Example 2:
prove -lv t/07-core-units.t t/21-refactor-coverage.t
Run the focused regression tests that most directly exercise this module's behavior.
Example 3:
HARNESS_PERL_SWITCHES=-MDevel::Cover prove -lr t
Recheck the module under the repository coverage gate rather than relying on a load-only probe.
Example 4:
prove -lr t
Put any module-level change back through the entire repository suite before release.