/** * daemon-home.ts * * Resolves and manages the daemon's identity home directory (`daemon.homeDir`). * * The daemon home holds immutable-after-startup identity state: * - auth-users.json * - auth-bootstrap.txt * - daemon-settings.json * - operator-tokens.json * * Resolution order (first match wins): * 1. --daemon-home= CLI arg (passed as daemonHomeArg) * 2. GOODVIBES_DAEMON_HOME environment variable * 3. /.goodvibes/daemon/, the tree root being what * `GOODVIBES_HOME` names, falling back to the login home. * * That third step used to call `homedir()` directly, which is the defect this * header now records. `GOODVIBES_HOME` relocates the tree root for every other * part of the platform (settings, workspace state, every secret tier, see * config/goodvibes-home.ts), so a daemon started under a redirected root kept * its identity files, auth users, operator tokens, daemon settings, in the * REAL `~/.goodvibes/daemon`. A relocation one resolver ignores is not a * relocation; the tree root is resolved in exactly one place now and this * module derives from it rather than recomputing a home of its own. * * The daemon home is canonical. Startup creates it when absent, but does not * import identity state from other surfaces or workspace-scoped paths. */ export interface DaemonHomeDirs { /** Absolute path to the daemon home directory (immutable identity state). */ readonly daemonHomeDir: string; /** True if this startup created the daemon home directory. */ readonly freshInstall: boolean; } export interface DaemonHomeOptions { /** Value of --daemon-home CLI flag, if provided. */ readonly daemonHomeArg?: string | undefined; /** Override process.env for testing. */ readonly env?: NodeJS.ProcessEnv | undefined; } /** * Resolve the daemon home directory from CLI flag, environment variable, or the * tree root. * * The explicit `--daemon-home` argument wins outright because it names THIS * process's identity directory and nothing else. Everything below it is the * platform's one home resolution: `GOODVIBES_DAEMON_HOME` names the identity * directory specifically, and absent that the directory falls under the tree * root `GOODVIBES_HOME` names, so a redirected tree takes its daemon identity * with it instead of reaching back into the login home. */ export declare function resolveDaemonHomeDir(options?: DaemonHomeOptions): string; /** * Returns the single canonical path for operator tokens. * All reads and writes MUST use this path. No workspace-scoped fallback exists. */ export declare function resolveOperatorTokenPath(daemonHomeDir: string): string; /** * Create the daemon home directory if it does not already exist. * * Returns `freshInstall: true` when the directory was created, `false` when it * already existed. */ export declare function ensureDaemonHome(daemonHomeDir: string): DaemonHomeDirs; /** * Write operator tokens to the global daemon-home path with mode 0600. * All token provisioning MUST go through this function. * * Uses a write-to-tmp-then-rename pattern for atomicity. * Applies chmod 0600 after rename so the file is never world-readable. */ export declare function writeOperatorTokenFile(daemonHomeDir: string, content: string): void; /** * Read operator tokens from the global daemon-home path. * Returns undefined when the file does not exist or cannot be parsed. */ export declare function readOperatorTokenFile(daemonHomeDir: string): string | undefined; /** * Read a single key from daemon-settings.json, or return undefined if missing. */ export declare function readDaemonSetting(daemonHomeDir: string, key: string): string | undefined; /** * Write a single key into daemon-settings.json (merge, not replace). * * Uses a write-to-tmp-then-rename pattern for atomicity: * a crash between write and rename leaves a .tmp file, never a corrupt target. */ export declare function writeDaemonSetting(daemonHomeDir: string, key: string, value: string): void; //# sourceMappingURL=daemon-home.d.ts.map