/** * Skills app-home resolution through the @hasna/paths resolver. * * Skills keeps its global config (`config.json`), auth (`auth.json`), the * default SQLite database (`server.db`), the corpus cache (`skills/`), and the * portable-skill tree (`installed/`, `custom/`) under one data root. * Historically that root was `~/.hasna/skills`. This module resolves the root * through `@hasna/paths` (XDG / macOS home layout) with a gated legacy * adoption: the legacy `~/.hasna/skills` stays the effective data root until * the store is physically migrated to the XDG data home (`server.db` or * `config.json` present there) or the operator sets the data-kind override * `HASNA_DATA_HOME`. An existing live store never becomes invisible on * upgrade. The exact-app overrides win unconditionally, in this order: * `HASNA_SKILLS_DIR` (the shipped override), then the wave-convention aliases * `HASNA_SKILLS_HOME` and `SKILLS_HOME`. * * Nothing moves on disk in this phase — the package just resolves the new * paths. */ export interface PathsResolverOptions { app: string; internal?: boolean; platform?: string; home?: string; env?: Record; } export declare function dataDir(options: PathsResolverOptions): string; /** Env var that relocates the skills data directory (the shipped override). */ export declare const DATA_DIR_ENV = "HASNA_SKILLS_DIR"; /** Wave-convention exact-app home aliases, honoured after HASNA_SKILLS_DIR. */ export declare const HASNA_SKILLS_HOME_ENV = "HASNA_SKILLS_HOME"; export declare const SKILLS_HOME_ENV = "SKILLS_HOME"; /** Filename of the default SQLite database inside the skills data directory. */ export declare const DEFAULT_SQLITE_FILENAME = "server.db"; /** Filename of the global config file inside the skills data directory. */ export declare const GLOBAL_CONFIG_FILENAME = "config.json"; /** * The effective user home, mirroring the pre-existing skills resolution * (`HOME` || `USERPROFILE` || `os.homedir()`). Read at call time so a runtime * `HOME` reassignment (e.g. a test temp home) is honoured — `os.homedir()` * snapshots `HOME` at process start and, under Bun, ignores later changes. */ export declare function effectiveHome(): string; /** The legacy (pre-XDG) data root: `~/.hasna/skills`. */ export declare function legacyDataRoot(): string; /** * The @hasna/paths-resolved (XDG / macOS home layout) data root for skills: * `~/.local/share/hasna/skills` on Linux, `~/Library/Application * Support/Hasna/skills` on macOS. The home override mirrors the pre-existing * `$HOME`-first resolution so the resolver follows the same home the legacy * path does. * * `env` is forwarded to the resolver: an injected env (e.g. `{}` for a * staged home mirror) suppresses the process-level `HASNA_*_HOME` overrides, * which describe THIS machine's live store and must not relocate a mirror. * `@hasna/paths` applies env overrides before the injected home, so without * this the resolver would ignore the mirror home whenever `HASNA_DATA_HOME` * is set. */ export declare function resolverDataRoot(home?: string, env?: Record): string; /** * Whether the resolver (XDG) data root should be adopted as the effective * data root. The resolver root is adopted only when the operator has set * `HASNA_DATA_HOME` (the data-kind override — a deliberate opt-in to the XDG * layout) or the store has already been physically migrated there (`server.db` * — the default SQLite store — or `config.json` exists). A machine that only * redirects another kind (e.g. cache to tmpfs) must NOT have its data home * moved, and a live store at the legacy home must never become invisible on * upgrade. */ export declare function adoptResolverDataRoot(resolved: string, env?: NodeJS.ProcessEnv): boolean; /** * The exact-app override root, when set: the shipped `HASNA_SKILLS_DIR` wins, * then the wave-convention aliases `HASNA_SKILLS_HOME` and `SKILLS_HOME`. * First non-blank override wins; a blank or whitespace-only primary must not * shadow a valid secondary (nullish `??` does not fall through on `""`). */ export declare function exactDataRoot(): string | undefined; /** Whether an exact-app override root is set (used to skip legacy migration). */ export declare function hasExactOverride(env?: NodeJS.ProcessEnv): boolean; /** * Whether the operator named a data root at all — an exact-app override or the * data-kind `HASNA_DATA_HOME`. Used to decide when the legacy `~/.skills` / * `~/.skillsrc` migration must be skipped: copying a stray legacy tree into an * operator-chosen directory would be a surprising write. */ export declare function hasOperatorOverride(env?: NodeJS.ProcessEnv): boolean; /** * The effective data root: an exact-app override (`HASNA_SKILLS_DIR`, then * `HASNA_SKILLS_HOME` / `SKILLS_HOME`) wins unconditionally; otherwise the * resolver (XDG) data root once adopted; otherwise the legacy `~/.hasna/skills` * default. Write-free: callers that need the directory to exist create it. */ export declare function getDataRoot(): string; /** * The skills app data root for an explicit home root, mirroring getDataRoot() * with the home injected. Used by the sync-home snapshot mapping to enumerate * the skills corpus under a staged home mirror (`homesRoot`) or the real home. * * Process-level overrides (`HASNA_SKILLS_DIR` / `HASNA_SKILLS_HOME` / * `SKILLS_HOME`, and the data-kind `HASNA_DATA_HOME`) describe THIS machine's * live store. They apply only when the requested home IS the process's own * effective home; a staged mirror (a different home, e.g. an rsync'd * remote-station `homesRoot`) must resolve its own layout — the mirror's XDG * data root once the mirror itself carries a migrated store there, else the * mirror's legacy `~/.hasna/skills` — never the local process's live data * root. Snapshotting a staged home with the local `HASNA_DATA_HOME` set would * otherwise read live local data instead of the supplied mirror. */ export declare function skillsDataRootForHome(home: string): string;