/** * CLEO-bound platform path helpers. * * Pre-binds {@link createPlatformPathsResolver} to `(appName='cleo', homeEnvVar='CLEO_HOME')` * and exposes the cleo-specific helpers every other CLEO package needs: * `getCleoHome`, `getCleoPlatformPaths`, `getCleoSystemInfo`, and * `getCleoTemplatesTildePath`. * * @task T1883 */ import { type PlatformPaths, type SystemInfo } from './platform-paths.js'; /** * Get OS-appropriate paths for CLEO's global directories. * * Linux: `~/.local/share/cleo` | macOS: `~/Library/Application Support/cleo` * Windows: `%LOCALAPPDATA%\cleo\Data` * * The `CLEO_HOME` env var overrides the `data` field. Read fresh on every call. * * @public */ export declare function getCleoPlatformPaths(): PlatformPaths; /** * Get the absolute path to CLEO's global data directory. * * Equivalent to `getCleoPlatformPaths().data` — exposed as a stable named * helper because `getCleoHome()` is the most common consumer call. * * @public */ export declare function getCleoHome(): string; /** * Get a cached system information snapshot scoped to CLEO. * * Includes platform, architecture, hostname, Node version, and resolved * CLEO paths. Captured once per process and reused — invalidate via * {@link _resetCleoPlatformPathsCache} in tests if needed. * * @public */ export declare function getCleoSystemInfo(): SystemInfo; /** * Get the CLEO templates directory as a tilde-prefixed path for use in * `@`-references (AGENTS.md, CLAUDE.md, etc.). Cross-platform: replaces * the user's home directory with `~` so the reference resolves consistently * when an LLM provider expands `~` at runtime. * * @returns Tilde-prefixed path like `"~/.local/share/cleo/templates"` on Linux * * @example * ```typescript * const ref = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`; * // "@~/.local/share/cleo/templates/CLEO-INJECTION.md" (Linux) * ``` * * @public */ export declare function getCleoTemplatesTildePath(): string; /** * Get the CLEO templates directory as a stable tilde-prefixed path for use in * `@`-references written into shared files (e.g. `~/.agents/AGENTS.md`). * * Unlike {@link getCleoTemplatesTildePath}, this function is **immune to * `CLEO_HOME` overrides**. It derives the reference from `homedir()` alone * via the canonical `~/.cleo` symlink path, which is always stable regardless * of the current `CLEO_HOME` env var value. * * This is the correct function to use when writing a template reference into * a file that persists across sessions (e.g. the global `~/.agents/AGENTS.md` * hub). Using {@link getCleoTemplatesTildePath} there causes test environments * — which override `CLEO_HOME` to a temp directory — to write stale temp-path * blocks into the real AGENTS.md on every test run (T9020 / T1929). * * @returns `"~/.cleo/templates"` on all platforms — resolves via the `~/.cleo` * symlink to the OS-appropriate canonical data directory at runtime. * * @example * ```typescript * const ref = `@${getCanonicalTemplatesTildePath()}/CLEO-INJECTION.md`; * // "@~/.cleo/templates/CLEO-INJECTION.md" * ``` * * @public */ export declare function getCanonicalTemplatesTildePath(): string; /** * Resolve the legacy `~/.cleo` directory, with optional explicit override. * * On a fully-bootstrapped install `~/.cleo` is a symlink to {@link getCleoHome} * (see `ensureCleoSymlink` in `@cleocode/core/bootstrap`), so writes through * this path land in the canonical OS-appropriate location. The override * argument takes precedence and is the standard wiring for CLI commands that * accept a `--cleo-dir` flag (`cleo daemon`, `cleo gc`, …). * * This helper centralizes the `args['--cleo-dir'] ?? join(homedir(), '.cleo')` * pattern that was previously duplicated across the CLI surface. Prefer * {@link getCleoHome} when you need the canonical (post-XDG) data directory * and there is no legacy-path or `--cleo-dir` override semantic. * * @param override - Explicit override (typically the `--cleo-dir` CLI arg) * @returns Absolute path to the resolved `.cleo` directory * * @example * ```typescript * // CLI handler * const cleoDir = resolveLegacyCleoDir(args['cleo-dir'] as string | undefined); * // Bootstrap migration probe * const legacyPath = resolveLegacyCleoDir(); * ``` * * @public */ export declare function resolveLegacyCleoDir(override?: string): string; /** * Result of {@link resolveProjectByCwd} — the project identity resolved * from walking up from a working directory. * * @public */ export interface ResolvedProject { /** Canonical runtime project ID (12-hex-char SHA-256 of git-root|name|remote). */ projectId: string; /** Absolute realpath to the project root directory. */ projectRoot: string; /** The legacy UUID from project-info.json, if present. */ legacyUUID?: string; } /** * Canonicalize a filesystem path across operating systems — resolve symlinks * and mount/alias divergence (macOS `/var` → `/private/var`, Windows * drive-letter case + 8.3 short names, Linux bind-mounts) via * {@link realpathSync}. * * Falls back to the lexically-resolved absolute path when the target does not * exist on disk, so identity/root computations never throw for a moved, * deleted, or not-yet-created project path. * * **SSoT:** this is the single path-canonicalization entry point for the CLEO * SDK. Never call `realpathSync` ad-hoc for path identity — route through here * so the OS-specific normalization stays consistent across every consumer and * test (notably the macOS `/var` vs `/private/var` split). * * @param p - A relative or absolute filesystem path. * @returns The realpath-canonicalized absolute path, or the lexically-resolved * absolute path when the target does not exist. * * @public * @task T11023 */ export declare function canonicalizePath(p: string): string; /** * Compute the canonical project ID for a given repository path (T9149/T11023). * * Algorithm: * 1. Resolve `repoPath` to its `realpath` (resolves symlinks, normalises mounts). * 2. Detect the git root via `git rev-parse --show-toplevel` (falls back to realpath). * 3. Read `.cleo/project-info.json` name (optional). * 4. Read `git remote get-url origin` (optional). * 5. SHA-256 of `||`, first 12 hex chars. * * This ensures `/mnt/projects/X` and `/workspace/X` (same git root, * same remote) produce the same ID. * * @param repoPath - Absolute path to the project root. * @returns The 12-hex-char canonical project ID. * * @task T11023 * @task T9149 */ export declare function computeCanonicalProjectId(repoPath: string): string; /** * Compute the legacy base64url(path) ID for a given path. * * **Canonical source** for this function. `@cleocode/core` re-exports * from here via `nexus/identity.ts`. This is the old algorithm used * before T9149 W5: `Buffer.from(path).toString('base64url').slice(0, 32)`. */ export declare function legacyProjectId(repoPath: string): string; /** * Walk up from `cwd` (or `process.cwd()`) looking for `.cleo/project-info.json` * and return the project identity if found. * * The project-info file acts as the local sentinel and supplies `legacyUUID`. * The returned `projectId` is the derived canonical runtime ID, not the raw * project-local UUID stored in the file. * * **Cross-mount divergence (T11023):** Uses `realpathSync` to normalize * bind-mounts and symlinks so the same repo at `/mnt/projects/X` and * `/workspace/X` resolves to the same `projectRoot`. The `projectId` is * the T9149 canonical 12-hex-char SHA-256 fingerprint of git-root + name * + remote URL, which is also mount-invariant. * * @param cwd - Optional working directory to start the ancestor walk from. * Defaults to `process.cwd()`. * @returns The resolved project identity, or `null` if no CLEO project is * found anywhere in the ancestor chain. * * @example * ```typescript * const project = resolveProjectByCwd('/repo/packages/core'); * // { projectId: 'a1b2c3d4e5f6', projectRoot: '/repo' } * * const notFound = resolveProjectByCwd('/tmp/empty'); * // null * ``` * * @public * @task T11008 * @task T11023 */ export declare function resolveProjectByCwd(cwd?: string): ResolvedProject | null; /** * Resolve the canonical `.cleo` directory for a project given its `projectId`. * * Looks up the project in the consolidated GLOBAL `cleo.db` registry * (`nexus_project_registry` table) to find the project's root path, then returns * the `.cleo/` directory under that root. * * **Post-E6 consolidation (T11569):** The cross-project registry moved from the * standalone `/nexus.db` into the consolidated dual-scope * `/cleo.db` (SG-DB-SUBSTRATE-V2 · E6-L4, T11524). On a fresh post-E6 * install `nexus.db` is never created, so opening it here returned `null` and * the core wrapper threw `E_PROJECT_NOT_FOUND` even for registered projects (the * read path had diverged from the write path — same class as #909/T11562). This * resolver opens `cleo.db`. * * **COMPLETE-CUTOVER (T11578 · AC3):** The live runtime registry table is now the * PREFIXED consolidated `nexus_project_registry` (the consolidated cleo-global * migration owns it; the bare `project_registry` runtime shape is retired). The * runtime writers and this read path both target the prefixed table — the read * path no longer diverges from the write path. * * **Legacy ID support (T11023 AC4):** If the `projectId` is not found in * `nexus_project_registry`, also checks the `nexus_project_id_aliases` table for a * legacy→canonical mapping before returning `null`. The path-derived canonical * 12-hex id is recorded as an alias of the immutable registry id (T11281), so a * canonical id supplied by `resolveProjectByCwd` resolves through this fallback. * * This enables cross-project lookups: given a stable project ID, resolve where * that project lives on disk without walking from a working directory. * * @param projectId - The project ID to look up. Can be a canonical 12-hex-char * ID, a legacy UUID, or a legacy base64url(path) ID. * @returns Absolute path to the `.cleo/` directory, or `null` if the * projectId is not found in the consolidated registry (or its alias table). * * @task T11008 * @task T11023 * @task T11569 */ export declare function resolveCanonicalCleoDir(projectId: string): string | null; /** * Invalidate the cached CLEO system info snapshot. Use in tests after * mutating `CLEO_HOME` or related env vars. * * @internal */ export declare function _resetCleoPlatformPathsCache(): void; //# sourceMappingURL=cleo-paths.d.ts.map