# Path Resolution API\n\nThis document describes the path resolution system used throughout the provisioning infrastructure for discovering configurations, extensions, and\nresolving workspace paths.\n\n## Overview\n\nThe path resolution system provides a hierarchical and configurable mechanism for:\n\n- Configuration file discovery and loading\n- Extension discovery (providers, task services, clusters)\n- Workspace and project path management\n- Environment variable interpolation\n- Cross-platform path handling\n\n## Configuration Resolution Hierarchy\n\nThe system follows a specific hierarchy for loading configuration files:\n\n```\n1. System defaults (config.defaults.toml)\n2. User configuration (config.user.toml)\n3. Project configuration (config.project.toml)\n4. Infrastructure config (infra/config.toml)\n5. Environment config (config.{env}.toml)\n6. Runtime overrides (CLI arguments, ENV vars)\n```\n\n### Configuration Search Paths\n\nThe system searches for configuration files in these locations:\n\n```\n# Default search paths (in order)\n/usr/local/provisioning/config.defaults.toml\n$HOME/.config/provisioning/config.user.toml\n$PWD/config.project.toml\n$PROVISIONING_KLOUD_PATH/config.infra.toml\n$PWD/config.{PROVISIONING_ENV}.toml\n```\n\n## Path Resolution API\n\n### Core Functions\n\n#### `resolve-config-path(pattern: string, search_paths: list) -> string`\n\nResolves configuration file paths using the search hierarchy.\n\n**Parameters:**\n\n- `pattern`: File pattern to search for (for example, "config.*.toml")\n- `search_paths`: Additional paths to search (optional)\n\n**Returns:**\n\n- Full path to the first matching configuration file\n- Empty string if no file found\n\n**Example:**\n\n```\nuse path-resolution.nu *\nlet config_path = (resolve-config-path "config.user.toml" [])\n# Returns: "/home/user/.config/provisioning/config.user.toml"\n```\n\n#### `resolve-extension-path(type: string, name: string) -> record`\n\nDiscovers extension paths (providers, taskservs, clusters).\n\n**Parameters:**\n\n- `type`: Extension type ("provider", "taskserv", "cluster")\n- `name`: Extension name (for example, "upcloud", "kubernetes", "buildkit")\n\n**Returns:**\n\n```\n{\n base_path: "/usr/local/provisioning/providers/upcloud",\n schemas_path: "/usr/local/provisioning/providers/upcloud/schemas",\n nulib_path: "/usr/local/provisioning/providers/upcloud/nulib",\n templates_path: "/usr/local/provisioning/providers/upcloud/templates",\n exists: true\n}\n```\n\n#### `resolve-workspace-paths() -> record`\n\nGets current workspace path configuration.\n\n**Returns:**\n\n```\n{\n base: "/usr/local/provisioning",\n current_infra: "/workspace/infra/production",\n kloud_path: "/workspace/kloud",\n providers: "/usr/local/provisioning/providers",\n taskservs: "/usr/local/provisioning/taskservs",\n clusters: "/usr/local/provisioning/cluster",\n extensions: "/workspace/extensions"\n}\n```\n\n### Path Interpolation\n\nThe system supports variable interpolation in configuration paths:\n\n#### Supported Variables\n\n- `{{paths.base}}` - Base provisioning path\n- `{{paths.kloud}}` - Current kloud path\n- `{{env.HOME}}` - User home directory\n- `{{env.PWD}}` - Current working directory\n- `{{now.date}}` - Current date (YYYY-MM-DD)\n- `{{now.time}}` - Current time (HH:MM:SS)\n- `{{git.branch}}` - Current git branch\n- `{{git.commit}}` - Current git commit hash\n\n#### `interpolate-path(template: string, context: record) -> string`\n\nInterpolates variables in path templates.\n\n**Parameters:**\n\n- `template`: Path template with variables\n- `context`: Variable context record\n\n**Example:**\n\n```\nlet template = "{{paths.base}}/infra/{{env.USER}}/{{git.branch}}"\nlet result = (interpolate-path $template {\n paths: { base: "/usr/local/provisioning" },\n env: { USER: "admin" },\n git: { branch: "main" }\n})\n# Returns: "/usr/local/provisioning/infra/admin/main"\n```\n\n## Extension Discovery API\n\n### Provider Discovery\n\n#### `discover-providers() -> list`\n\nDiscovers all available providers.\n\n**Returns:**\n\n```\n[\n {\n name: "upcloud",\n path: "/usr/local/provisioning/providers/upcloud",\n type: "provider",\n version: "1.2.0",\n enabled: true,\n has_schemas: true,\n has_nulib: true,\n has_templates: true\n },\n {\n name: "aws",\n path: "/usr/local/provisioning/providers/aws",\n type: "provider",\n version: "2.1.0",\n enabled: true,\n has_schemas: true,\n has_nulib: true,\n has_templates: true\n }\n]\n```\n\n#### `get-provider-config(name: string) -> record`\n\nGets provider-specific configuration and paths.\n\n**Parameters:**\n\n- `name`: Provider name\n\n**Returns:**\n\n```\n{\n name: "upcloud",\n base_path: "/usr/local/provisioning/providers/upcloud",\n config: {\n api_url: "https://api.upcloud.com/1.3",\n auth_method: "basic",\n interface: "API"\n },\n paths: {\n schemas: "/usr/local/provisioning/providers/upcloud/schemas",\n nulib: "/usr/local/provisioning/providers/upcloud/nulib",\n templates: "/usr/local/provisioning/providers/upcloud/templates"\n },\n metadata: {\n version: "1.2.0",\n description: "UpCloud provider for server provisioning"\n }\n}\n```\n\n### Task Service Discovery\n\n#### `discover-taskservs() -> list`\n\nDiscovers all available task services.\n\n**Returns:**\n\n```\n[\n {\n name: "kubernetes",\n path: "/usr/local/provisioning/taskservs/kubernetes",\n type: "taskserv",\n category: "orchestration",\n version: "1.28.0",\n enabled: true\n },\n {\n name: "cilium",\n path: "/usr/local/provisioning/taskservs/cilium",\n type: "taskserv",\n category: "networking",\n version: "1.14.0",\n enabled: true\n }\n]\n```\n\n#### `get-taskserv-config(name: string) -> record`\n\nGets task service configuration and version information.\n\n**Parameters:**\n\n- `name`: Task service name\n\n**Returns:**\n\n```\n{\n name: "kubernetes",\n path: "/usr/local/provisioning/taskservs/kubernetes",\n version: {\n current: "1.28.0",\n available: "1.28.2",\n update_available: true,\n source: "github",\n release_url: "https://github.com/kubernetes/kubernetes/releases"\n },\n config: {\n category: "orchestration",\n dependencies: ["containerd"],\n supports_versions: ["1.26.x", "1.27.x", "1.28.x"]\n }\n}\n```\n\n### Cluster Discovery\n\n#### `discover-clusters() -> list`\n\nDiscovers all available cluster configurations.\n\n**Returns:**\n\n```\n[\n {\n name: "buildkit",\n path: "/usr/local/provisioning/cluster/buildkit",\n type: "cluster",\n category: "build",\n components: ["buildkit", "registry", "storage"],\n enabled: true\n }\n]\n```\n\n## Environment Management API\n\n### Environment Detection\n\n#### `detect-environment() -> string`\n\nAutomatically detects the current environment based on:\n\n1. `PROVISIONING_ENV` environment variable\n2. Git branch patterns (main → prod, develop → dev, etc.)\n3. Directory structure analysis\n4. Configuration file presence\n\n**Returns:**\n\n- Environment name string (dev, test, prod, etc.)\n\n#### `get-environment-config(env: string) -> record`\n\nGets environment-specific configuration.\n\n**Parameters:**\n\n- `env`: Environment name\n\n**Returns:**\n\n```\n{\n name: "production",\n paths: {\n base: "/opt/provisioning",\n kloud: "/data/kloud",\n logs: "/var/log/provisioning"\n },\n providers: {\n default: "upcloud",\n allowed: ["upcloud", "aws"]\n },\n features: {\n debug: false,\n telemetry: true,\n rollback: true\n }\n}\n```\n\n### Environment Switching\n\n#### `switch-environment(env: string, validate: bool = true) -> null`\n\nSwitches to a different environment and updates path resolution.\n\n**Parameters:**\n\n- `env`: Target environment name\n- `validate`: Whether to validate environment configuration\n\n**Effects:**\n\n- Updates `PROVISIONING_ENV` environment variable\n- Reconfigures path resolution for new environment\n- Validates environment configuration if requested\n\n## Workspace Management API\n\n### Workspace Discovery\n\n#### `discover-workspaces() -> list`\n\nDiscovers available workspaces and infrastructure directories.\n\n**Returns:**\n\n```\n[\n {\n name: "production",\n path: "/workspace/infra/production",\n type: "infrastructure",\n provider: "upcloud",\n settings: "settings.ncl",\n valid: true\n },\n {\n name: "development",\n path: "/workspace/infra/development",\n type: "infrastructure",\n provider: "local",\n settings: "dev-settings.ncl",\n valid: true\n }\n]\n```\n\n#### `set-current-workspace(path: string) -> null`\n\nSets the current workspace for path resolution.\n\n**Parameters:**\n\n- `path`: Workspace directory path\n\n**Effects:**\n\n- Updates `CURRENT_INFRA_PATH` environment variable\n- Reconfigures workspace-relative path resolution\n\n### Project Structure Analysis\n\n#### `analyze-project-structure(path: string = $PWD) -> record`\n\nAnalyzes project structure and identifies components.\n\n**Parameters:**\n\n- `path`: Project root path (defaults to current directory)\n\n**Returns:**\n\n```\n{\n root: "/workspace/project",\n type: "provisioning_workspace",\n components: {\n providers: [\n { name: "upcloud", path: "providers/upcloud" },\n { name: "aws", path: "providers/aws" }\n ],\n taskservs: [\n { name: "kubernetes", path: "taskservs/kubernetes" },\n { name: "cilium", path: "taskservs/cilium" }\n ],\n clusters: [\n { name: "buildkit", path: "cluster/buildkit" }\n ],\n infrastructure: [\n { name: "production", path: "infra/production" },\n { name: "staging", path: "infra/staging" }\n ]\n },\n config_files: [\n "config.defaults.toml",\n "config.user.toml",\n "config.prod.toml"\n ]\n}\n```\n\n## Caching and Performance\n\n### Path Caching\n\nThe path resolution system includes intelligent caching:\n\n#### `cache-paths(duration: duration = 5 min) -> null`\n\nEnables path caching for the specified duration.\n\n**Parameters:**\n\n- `duration`: Cache validity duration\n\n#### `invalidate-path-cache() -> null`\n\nInvalidates the path resolution cache.\n\n#### `get-cache-stats() -> record`\n\nGets path resolution cache statistics.\n\n**Returns:**\n\n```\n{\n enabled: true,\n size: 150,\n hit_rate: 0.85,\n last_invalidated: "2025-09-26T10:00:00Z"\n}\n```\n\n## Cross-Platform Compatibility\n\n### Path Normalization\n\n#### `normalize-path(path: string) -> string`\n\nNormalizes paths for cross-platform compatibility.\n\n**Parameters:**\n\n- `path`: Input path (may contain mixed separators)\n\n**Returns:**\n\n- Normalized path using platform-appropriate separators\n\n**Example:**\n\n```\n# On Windows\nnormalize-path "path/to/file" # Returns: "path\to\file"\n\n# On Unix\nnormalize-path "path\to\file" # Returns: "path/to/file"\n```\n\n#### `join-paths(segments: list) -> string`\n\nSafely joins path segments using platform separators.\n\n**Parameters:**\n\n- `segments`: List of path segments\n\n**Returns:**\n\n- Joined path string\n\n## Configuration Validation API\n\n### Path Validation\n\n#### `validate-paths(config: record) -> record`\n\nValidates all paths in configuration.\n\n**Parameters:**\n\n- `config`: Configuration record\n\n**Returns:**\n\n```\n{\n valid: true,\n errors: [],\n warnings: [\n { path: "paths.extensions", message: "Path does not exist" }\n ],\n checks_performed: 15\n}\n```\n\n#### `validate-extension-structure(type: string, path: string) -> record`\n\nValidates extension directory structure.\n\n**Parameters:**\n\n- `type`: Extension type (provider, taskserv, cluster)\n- `path`: Extension base path\n\n**Returns:**\n\n```\n{\n valid: true,\n required_files: [\n { file: "manifest.toml", exists: true },\n { file: "schemas/main.ncl", exists: true },\n { file: "nulib/mod.nu", exists: true }\n ],\n optional_files: [\n { file: "templates/server.j2", exists: false }\n ]\n}\n```\n\n## Command-Line Interface\n\n### Path Resolution Commands\n\nThe path resolution API is exposed via Nushell commands:\n\n```\n# Show current path configuration\nprovisioning show paths\n\n# Discover available extensions\nprovisioning discover providers\nprovisioning discover taskservs\nprovisioning discover clusters\n\n# Validate path configuration\nprovisioning validate paths\n\n# Switch environments\nprovisioning env switch prod\n\n# Set workspace\nprovisioning workspace set /path/to/infra\n```\n\n## Integration Examples\n\n### Python Integration\n\n```\nimport subprocess\nimport json\n\nclass PathResolver:\n def __init__(self, provisioning_path="/usr/local/bin/provisioning"):\n self.cmd = provisioning_path\n\n def get_paths(self):\n result = subprocess.run([\n "nu", "-c", f"use {self.cmd} *; show-config --section=paths --format=json"\n ], capture_output=True, text=True)\n return json.loads(result.stdout)\n\n def discover_providers(self):\n result = subprocess.run([\n "nu", "-c", f"use {self.cmd} *; discover providers --format=json"\n ], capture_output=True, text=True)\n return json.loads(result.stdout)\n\n# Usage\nresolver = PathResolver()\npaths = resolver.get_paths()\nproviders = resolver.discover_providers()\n```\n\n### JavaScript/Node.js Integration\n\n```\nconst { exec } = require('child_process');\nconst util = require('util');\nconst execAsync = util.promisify(exec);\n\nclass PathResolver {\n constructor(provisioningPath = '/usr/local/bin/provisioning') {\n this.cmd = provisioningPath;\n }\n\n async getPaths() {\n const { stdout } = await execAsync(\n `nu -c "use ${this.cmd} *; show-config --section=paths --format=json"`\n );\n return JSON.parse(stdout);\n }\n\n async discoverExtensions(type) {\n const { stdout } = await execAsync(\n `nu -c "use ${this.cmd} *; discover ${type} --format=json"`\n );\n return JSON.parse(stdout);\n }\n}\n\n// Usage\nconst resolver = new PathResolver();\nconst paths = await resolver.getPaths();\nconst providers = await resolver.discoverExtensions('providers');\n```\n\n## Error Handling\n\n### Common Error Scenarios\n\n1. **Configuration File Not Found**\n\n ```nushell\n Error: Configuration file not found in search paths\n Searched: ["/usr/local/provisioning/config.defaults.toml", ...]\n ```\n\n1. **Extension Not Found**\n\n ```nushell\n Error: Provider 'missing-provider' not found\n Available providers: ["upcloud", "aws", "local"]\n ```\n\n2. **Invalid Path Template**\n\n ```nushell\n Error: Invalid template variable: {{invalid.var}}\n Valid variables: ["paths.*", "env.*", "now.*", "git.*"]\n ```\n\n3. **Environment Not Found**\n\n ```nushell\n Error: Environment 'staging' not configured\n Available environments: ["dev", "test", "prod"]\n ```\n\n### Error Recovery\n\nThe system provides graceful fallbacks:\n\n- Missing configuration files use system defaults\n- Invalid paths fall back to safe defaults\n- Extension discovery continues if some paths are inaccessible\n- Environment detection falls back to 'local' if detection fails\n\n## Performance Considerations\n\n### Best Practices\n\n1. **Use Path Caching**: Enable caching for frequently accessed paths\n2. **Batch Discovery**: Discover all extensions at once rather than individually\n3. **Lazy Loading**: Load extension configurations only when needed\n4. **Environment Detection**: Cache environment detection results\n\n### Monitoring\n\nMonitor path resolution performance:\n\n```\n# Get resolution statistics\nprovisioning debug path-stats\n\n# Monitor cache performance\nprovisioning debug cache-stats\n\n# Profile path resolution\nprovisioning debug profile-paths\n```\n\n## Security Considerations\n\n### Path Traversal Protection\n\nThe system includes protections against path traversal attacks:\n\n- All paths are normalized and validated\n- Relative paths are resolved within safe boundaries\n- Symlinks are validated before following\n\n### Access Control\n\nPath resolution respects file system permissions:\n\n- Configuration files require read access\n- Extension directories require read/execute access\n- Workspace directories may require write access for operations\n\nThis path resolution API provides a comprehensive and flexible system for managing the complex path requirements of multi-provider, multi-environment\ninfrastructure provisioning.