/**
 * Filesystem layout and persistent state for agents-cli.
 *
 * Single root at ~/.agents/ with three internal buckets:
 *
 *   ~/.agents/           — user repo: user-authored resources + agents.yaml
 *                          (git-tracked via `agents repo push`).
 *   ~/.agents/.system/   — system repo: npm-shipped resources, regenerable.
 *                          Don't hand-edit; maintained by npm install /
 *                          `agents repo pull system`.
 *   ~/.agents/.history/  — durable runtime data (sessions, versions, runs,
 *                          teams/agents, trash, backups). Backed up by
 *                          `agents repo push`.
 *   ~/.agents/.cache/    — regenerable runtime data (shims, packages, helpers
 *                          for daemon/pty, terminals, cloud, drive, browser
 *                          chrome-data, logs, companion). Gitignored.
 *
 * Resolution precedence for resources: project > user > system.
 * Every module that needs a path or reads/writes agents.yaml goes through here.
 *
 * Legacy layout (pre-fold): system repo lived at ~/.agents-system/ as a peer
 * of ~/.agents/. runMigration() folds it into ~/.agents/.system/ on first run
 * and leaves a back-compat symlink at the old path.
 */
import type { Meta } from './types.js';
/** Return the absolute path to the humans.yaml file. */
export declare function getHumansFilePath(): string;
/**
 * Header prepended to every agents.yaml the CLI writes (central and per-device
 * docs). Carries the yaml-language-server schema hint so editors validate the
 * file against `schema/agents-yaml.schema.json`. Exported so
 * `lib/devices/config-migration.ts` rewrites a device doc with the same header.
 */
export declare const META_HEADER = "# agents-cli metadata\n# Auto-generated - do not edit manually\n# https://github.com/phnx-labs/agi-cli\n# yaml-language-server: $schema=https://raw.githubusercontent.com/phnx-labs/agi-cli/main/cli/schema/agents-yaml.schema.json\n\n";
/** Root of the system data directory (~/.agents/.system/). */
export declare function getAgentsDir(): string;
/** Root of the system data directory (~/.agents/.system/). */
export declare function getSystemAgentsDir(): string;
/** Legacy system-repo location (~/.agents-system/). Exported for migration only. */
export declare function getLegacySystemAgentsDir(): string;
/** Root of the user repo (~/.agents/). Always present after ensureAgentsDir(). */
export declare function getUserAgentsDir(): string;
/**
 * Backward-compat shim. Returns null when ~/.agents/ is a symlink to the
 * system dir; otherwise returns USER_AGENTS_DIR.
 *
 * @deprecated Use getUserAgentsDir() directly.
 */
export declare function getOptionalUserAgentsDir(): string | null;
/**
 * True when `agentsPath` is a reserved `.agents` root that must never be
 * treated as a project layer: the user repo (~/.agents), the system repo
 * (~/.agents/.system), or a git checkout of either canonical DotAgents repo.
 * `getProjectAgentsDir` skips these while walking up; direct-cwd callers
 * (`compileRulesForProject`) consult the same predicate so `$HOME` — whose
 * `.agents/rules` is the user layer itself — can never compile as a
 * "project" (RUSH-2725).
 */
export declare function isReservedAgentsDir(agentsPath: string): boolean;
/** Walk up from startPath to find a project-scoped .agents/ directory (skipping both roots). */
export declare function getProjectAgentsDir(startPath?: string): string | null;
/** Return all .agents/ directories in scope: project, user, then system. */
export declare function getScopedAgentsDirs(startPath?: string): Array<{
    scope: 'project' | 'user' | 'system';
    path: string;
}>;
/** Path to slash command markdown files — system repo. */
export declare function getCommandsDir(): string;
/** Path to hook script directories — system repo. */
export declare function getHooksDir(): string;
/** Path to skill bundles — system repo. */
export declare function getSkillsDir(): string;
/** Path to the canonical rules directory — system repo. */
export declare function getRulesDir(): string;
/** Read-side resolution for the canonical rules dir — system repo. */
export declare function getResolvedRulesDir(): string;
/** Path to MCP server YAML configs — system repo. */
export declare function getMcpDir(): string;
/** Path to permission group YAML files — system repo. */
export declare function getPermissionsDir(): string;
/** Path to subagent definition directories — system repo. */
export declare function getSubagentsDir(): string;
/** Path to ~/.agents/.system/hooks/promptcuts.yaml (system defaults). */
export declare function getPromptcutsPath(): string;
/**
 * Resolve the effective promptcuts file: user file if it exists, otherwise
 * the system file. Use this for callers that need a single path (doctor
 * diff, displaying which file is in play). Callers that need the merged
 * shortcut set should use readMergedPromptcuts() instead.
 */
export declare function getEffectivePromptcutsPath(): string;
/**
 * Read promptcuts from system + user with user precedence. Returns the
 * merged `shortcuts` map. Same layering model as parseHookManifest().
 * Returns an empty object when neither file exists or both fail to parse.
 */
export declare function readMergedPromptcuts(): Record<string, unknown>;
/** Path to the legacy MCP config JSON. */
export declare function getMcpConfigPath(): string;
/** Path to the global instructions file. */
export declare function getInstructionsPath(): string;
export declare function getSystemCommandsDir(): string;
export declare function getSystemHooksDir(): string;
export declare function getSystemSkillsDir(): string;
export declare function getSystemRulesDir(): string;
export declare function getSystemMcpDir(): string;
export declare function getSystemPermissionsDir(): string;
export declare function getSystemSubagentsDir(): string;
export declare function getSystemPromptcutsPath(): string;
export declare function getUserCommandsDir(): string;
export declare function getUserHooksDir(): string;
export declare function getUserSkillsDir(): string;
export declare function getUserRulesDir(): string;
export declare function getUserMcpDir(): string;
export declare function getUserPermissionsDir(): string;
export declare function getUserSubagentsDir(): string;
export declare function getSystemWorkflowsDir(): string;
export declare function getUserWorkflowsDir(): string;
export declare function getUserSecretsDir(): string;
/**
 * Path to the secrets usage read-model database (~/.agents/secrets/secrets.db).
 * Read at CALL time so a test can redirect it to a temp file via
 * AGENTS_SECRETS_DB without racing the module-load capture of USER_SECRETS_DIR —
 * mirrors the AGENTS_EVENTS_PATH / AGENTS_DEVICES_DIR escape hatches. Holds only
 * value-free usage telemetry (which bundle was created/imported/exported/viewed/
 * accessed/unlocked, when, by whom), never a secret value. It is a derived index
 * fed FROM the emitSecretAudit chokepoint alongside the append-only
 * ~/.agents/.history/events/YYYY-MM-DD audit log — the same way sessions.db indexes session
 * metadata off the real session flow — not a second write path.
 */
export declare function getSecretsDbPath(): string;
/**
 * Path to the durable resource-usage warehouse (~/.agents/.history/analytics/usage.db).
 * Value-free frequency/lifecycle events (secrets, agents, browser, …). Read at CALL
 * time so AGENTS_USAGE_DB can redirect tests. Sync shards may also appear as
 * usage.<machine-id>.db beside this default file.
 */
export declare function getAnalyticsDir(): string;
export declare function getUsageDbPath(): string;
export declare function getUserPromptcutsPath(): string;
/** Canonical home anchor (HOME env override or os.homedir()). */
export declare function getHomeDir(): string;
/** Bucket root for durable runtime data (~/.agents/.history/). */
export declare function getHistoryDir(): string;
/** Bucket root for regenerable runtime data (~/.agents/.cache/). */
export declare function getCacheDir(): string;
/** Path to cloned packages (~/.agents/.cache/packages/). */
export declare function getPackagesDir(): string;
/** Path to routine YAML definitions (~/.agents/routines/). */
export declare function getRoutinesDir(): string;
/** Path to named project definitions (~/.agents/projects/). */
export declare function getProjectsDir(): string;
/** Path to daemon config directory (~/.agents/daemon/). Holds service toggles. */
export declare function getDaemonConfigDir(): string;
/**
 * Path to webhook handler YAML definitions (~/.agents/webhooks/). Handlers are
 * one-off triggers for agents/workflows/commands/routines, layered the same way
 * as routines (project > user > system).
 */
export declare function getWebhooksDir(): string;
/**
 * Path to built-in routine definitions shipped in the system repo
 * (`~/.agents/.system/routines/`). Unioned under the user routines dir by
 * listJobs()/readJob(): a routine shipped here fires for every install, and a
 * user routine of the same name overrides it (a user copy with `enabled: false`
 * disables the built-in). The daemon fires these; the directory need not exist.
 */
export declare function getSystemRoutinesDir(): string;
/**
 * Path to built-in webhook handler definitions shipped in the system repo
 * (`~/.agents/.system/webhooks/`). Layered under user handlers by `listHandlers()`.
 */
export declare function getSystemWebhooksDir(): string;
/**
 * Path to a project-scoped routines directory (`<project>/.agents/routines/`),
 * or null when no project `.agents/` is found by walking up from cwd.
 *
 * Project routines participate in `list`/`view` for inspection always. Daemon
 * firing requires `agents routines enable <name>`, which materialises the
 * routine into the user layer with `source:` provenance (so the daemon, which
 * loads user + system only, can see it) and turns on the device flag in one
 * step. Enablement lives solely in `meta.deviceRoutines`; a project YAML's own
 * `enabled:` field never turns firing on, so a cloned repo cannot auto-run.
 * See `lib/routines-project.ts`.
 */
export declare function getProjectRoutinesDir(cwd?: string): string | null;
/**
 * Path to a project-scoped webhook handlers directory
 * (`<project>/.agents/webhooks/`), or null when no project `.agents/` is found
 * by walking up from cwd.
 */
export declare function getProjectWebhooksDir(cwd?: string): string | null;
/** Path to routine execution logs (~/.agents/.history/runs/). */
export declare function getRunsDir(): string;
/** Path to monitor YAML definitions (~/.agents/monitors/). */
export declare function getMonitorsDir(): string;
/**
 * Path to built-in monitor definitions shipped in the system repo
 * (`~/.agents/.system/monitors/`). Unioned under the user monitors dir by
 * listMonitors()/readMonitor(): a monitor shipped here is available on every
 * install, and a user monitor of the same name overrides it. A built-in is
 * enabled by default like every other system-layer resource — it runs on every
 * install unless the user shadows it with `enabled: false` (via `agents monitors
 * pause`, which materializes a user copy; writes never touch this pull-only
 * mirror). A shared-input built-in still carries its own `device:` owner pin in
 * the shipped YAML so exactly one box fires it (SING-9). The directory need not
 * exist.
 */
export declare function getSystemMonitorsDir(): string;
/** Path to the durable per-monitor state-diff store + fire history
 * (~/.agents/.history/monitors/). */
export declare function getMonitorsHistoryDir(): string;
/** Root for per-agent mailboxes (~/.agents/.history/mailbox/). */
export declare function getMailboxRootDir(): string;
/** Root for open-block feed records (~/.agents/.history/feed/). */
export declare function getFeedDir(): string;
/** Append-only per-session agent-activity event logs (~/.agents/.history/activity/). */
export declare function getActivityDir(): string;
/** Path to installed agent CLI binaries (~/.agents/.history/versions/). */
export declare function getVersionsDir(): string;
/** Path to version-switching shim scripts (~/.agents/.cache/shims/). */
export declare function getShimsDir(): string;
/**
 * Path to generated per-hook caching/timing shims (~/.agents/.cache/shims/hooks/).
 * Read at CALL time — since every hook now resolves through a shim (RUSH-2xxx,
 * pass-through timing for matcher-only hooks), a test that registers hooks
 * in-process (no subprocess HOME override) would otherwise write real shim
 * files into the user's actual ~/.agents/.cache. AGENTS_HOOK_SHIMS_DIR mirrors
 * the AGENTS_EVENTS_PATH / AGENTS_DEVICES_DIR test-isolation escape hatches;
 * never set in production code.
 */
export declare function getHookShimsDir(): string;
/**
 * Path to per-hook stdout cache files (~/.agents/.cache/state/hooks/). Read at
 * CALL time for the same reason as {@link getHookShimsDir} — see its doc.
 */
export declare function getHookCacheDir(): string;
/** Path to per-agent installed CLI binaries (~/.agents/.cache/bin/). */
export declare function getBinDir(): string;
/** Path to config backups (~/.agents/.history/backups/). */
export declare function getBackupsDir(): string;
/** Path to plugin bundles (~/.agents/plugins/) — user-authored resource. */
export declare function getPluginsDir(): string;
/** Path to system plugin bundles (~/.agents/.system/plugins/) — npm-shipped, read-only defaults. */
export declare function getSystemPluginsDir(): string;
/** Path to an extra repo's plugin bundles (~/.agents-<alias>/plugins/). */
export declare function getExtraPluginsDir(alias: string): string;
/** Path to a project-scoped plugins directory (<project>/.agents/plugins/), or null when none. */
export declare function getProjectPluginsDir(cwd?: string): string | null;
/** Path to soft-deleted resources (~/.agents/.history/trash/). */
export declare function getTrashDir(): string;
/** Path to local session indexer storage (~/.agents/.history/sessions/). */
export declare function getSessionsDir(): string;
/** Path to the session index database (~/.agents/.history/sessions/sessions.db). */
export declare function getSessionsDbPath(): string;
/** Path to teams config + registry (~/.agents/teams/). */
export declare function getTeamsDir(): string;
/** Path to teams execution history (~/.agents/.history/teams/agents/). */
export declare function getTeamsAgentsDir(): string;
/** Path to the team registry — list of named teams with timestamps. Durable runtime, per-machine. */
export declare function getTeamsRegistryPath(): string;
/** Path to the device registry — SSH device profiles with platform/auth metadata. Durable runtime, per-machine (host list + addresses are NOT pulled by `agents repo push`). */
export declare function getDevicesRegistryPath(): string;
/** Path to the LEGACY per-machine device ignore-list — superseded by the tracked `fleet.ignored` list in central agents.yaml (RUSH-3062); only lib/devices/config-migration.ts still reads it (to fold + remove it). */
export declare function getDevicesIgnoredPath(): string;
/** Path to the LEGACY device auto-launch preference file — which registered devices are eligible/preferred for the ext's auto-host selection. Superseded by the per-device doc `config:` block; only lib/devices/config-migration.ts still reads it (to fold + remove it). */
export declare function getDevicesAutoLaunchPath(): string;
/** Path to THIS machine's agent pins — the `agents:` global defaults and
 * `isolatedAgents:` pointers. Each pin names a version installed on THIS
 * machine, so it is machine-local runtime state and lives beside the device
 * registry under `.history/devices/` (untracked) — NOT in the tracked
 * per-device doc, where auto-written pins caused commit churn on every
 * `agents use` / install. Read at call time like the other devices-dir paths. */
export declare function getDevicePinsPath(): string;
/** Dir of "pending device" sentinels (~/.agents/.cache/state/devices-pending/) — one empty-ish file per newly-discovered, not-yet-approved tailnet node. Written by the daemon probe, read by the menu-bar helper (mirrors the attention sentinel dir). */
export declare function getDevicesPendingDir(): string;
/** Path to cloud dispatch cache (~/.agents/.cache/cloud/). */
export declare function getCloudDir(): string;
/** Path to terminal session metadata (~/.agents/.cache/terminals/). */
export declare function getTerminalsDir(): string;
/**
 * Path to runtime logs (~/.agents/.cache/logs/). Read at CALL time so
 * AGENTS_LOGS_DIR can redirect it in tests — same test-isolation escape hatch
 * as {@link getHookShimsDir}; never set in production code.
 */
export declare function getLogsDir(): string;
/**
 * Path to disposable performance samples (~/.agents/.cache/perf/).
 * Holds `perf.db` + a hook-shim spool. Loss is acceptable — wipe freely.
 * Read at CALL time: AGENTS_PERF_DIR (the same override perf/db.ts and
 * perf/spool.ts already honor for their own internal resolution) redirects
 * this canonical getter too, so a caller that goes through it directly
 * (hooks/cache.ts's shim generator, the OpenCode timeout sample writer in
 * hooks.ts) doesn't leak samples into the user's real perf warehouse either.
 */
export declare function getPerfDir(): string;
/** Path to the perf SQLite warehouse (~/.agents/.cache/perf/perf.db). */
export declare function getPerfDbPath(): string;
/** Path to the hook-shim NDJSON spool drained into perf.db on open. */
export declare function getPerfSpoolPath(): string;
/**
 * Path to per-process runtime state (~/.agents/.cache/state/).
 *
 * `AGENTS_STATE_DIR` redirects it in tests — the same test-isolation escape
 * hatch as `AGENTS_DEVICES_DIR` / `AGENTS_LOGS_DIR`, and resolved at call time
 * for the same reason (a suite pins it after this module is imported).
 *
 * Without it the suite writes into the operator's LIVE state. Concretely: the
 * device registry and ignore-list already redirect via `AGENTS_DEVICES_DIR`, so
 * under test both read empty — and any code path reaching
 * `reconcilePendingSentinels` then computed "every tailnet node is new" and
 * wrote those sentinels into the real `devices-pending/`, which is exactly what
 * the menu bar renders. Running the suite on a dev machine surfaced all 20
 * tailnet nodes as NEW DEVICES, including registered and explicitly ignored
 * ones, and looked like the operator's ignore list had been lost.
 */
export declare function getRuntimeStateDir(): string;
/** Path to companion-extension scratch (~/.agents/.cache/companion/). */
export declare function getCompanionDir(): string;
/** Path to browser runtime data — chrome-data, pids (~/.agents/.cache/browser/). */
export declare function getBrowserRuntimeDir(): string;
/**
 * Path to DURABLE browser-profile data (~/.agents/.history/browser-profiles/).
 *
 * This is the persistent home for an attach-only profile's `--user-data-dir` —
 * where a one-time browser sign-in lives. It sits under `.history` (durable),
 * NOT `.cache` (regenerable), for two reasons the ticket (PHNX-3967) named:
 *  - `agents browser profiles remove` sweeps `~/.agents/.cache/browser/<name>*`;
 *    a durable dir here survives that so logins are not wiped by a routine cleanup.
 *  - A cache wipe or the daemon reaper never touches it, so a signed-in Comet
 *    survives quit+relaunch.
 * The user's canonical Comet is launched with this as `--user-data-dir`, and the
 * ownership guard in the local driver compares the running instance's
 * `--user-data-dir` against it to reject a foreign port-squatter.
 */
export declare function getBrowserDurableDir(): string;
/** Path to helper subprocess scratch (~/.agents/.cache/helpers/). */
export declare function getHelpersDir(): string;
/**
 * Path to scheduler daemon scratch (~/.agents/.cache/helpers/daemon/) — holds
 * the daemon pid file, heartbeat, start lock, and log. AGENTS_DAEMON_DIR
 * redirects it to a fork-private temp so daemon tests (which write pid/heartbeat
 * files and acquire the real start lock) can never clobber a live daemon's state
 * on a dev machine — the surgical mirror of AGENTS_DEVICES_DIR /
 * AGENTS_HOOK_SHIMS_DIR, leaving HOME untouched. Read at CALL time (daemon.ts
 * resolves every path helper through this), so tests/setup.ts can set it before
 * the daemon module is exercised. Never set in production code.
 */
export declare function getDaemonDir(): string;
/** Path to PTY server scratch (~/.agents/.cache/helpers/pty/). */
export declare function getPtyDir(): string;
/** Path to tmux scratch (~/.agents/.cache/helpers/tmux/) — shared server socket + per-session meta JSONs. */
export declare function getTmuxDir(): string;
/** Path to remote-resource auto-pull cache (~/.agents/.cache/.fetch/). */
export declare function getFetchCacheDir(): string;
/** Path to the CLI version cache file (~/.agents/.cache/.cli-version-cache.json). */
export declare function getCliVersionCachePath(): string;
/** Path to the models cache file (~/.agents/.cache/.models-cache.json). */
export declare function getModelsCachePath(): string;
/** Path to the daily update-check sentinel (~/.agents/.cache/.update-check). */
export declare function getUpdateCheckPath(): string;
/** Path to the migration sentinel (~/.agents/.cache/.migrated). */
export declare function getMigratedSentinelPath(): string;
/** Path to soft-deleted version dirs (~/.agents/trash/versions/). */
export declare function getTrashVersionsDir(): string;
/** Path to soft-deleted skills (~/.agents/trash/skills/). */
export declare function getTrashSkillsDir(): string;
/** Path to soft-deleted commands (~/.agents/trash/commands/). */
export declare function getTrashCommandsDir(): string;
/** Path to soft-deleted hooks (~/.agents/trash/hooks/). */
export declare function getTrashHooksDir(): string;
/** Path to soft-deleted plugins (~/.agents/trash/plugins/). */
export declare function getTrashPluginsDir(): string;
/** Path to soft-deleted subagents (~/.agents/trash/subagents/). */
export declare function getTrashSubagentsDir(): string;
export declare function getTrashWorkflowsDir(): string;
/**
 * Path to a single user-level extra DotAgent repo clone (~/.agents-<alias>/).
 *
 * Extra repos are user-defined config — they live as peer dirs to ~/.agents/,
 * not under the system repo. `agents repo add` clones here by default.
 */
export declare function getExtraRepoDir(alias: string): string;
/** Resolve the on-disk path for an extra repo, whether managed or user-owned. */
export declare function resolveExtraRepoDir(alias: string, config?: {
    path?: string;
}): string;
/**
 * Return enabled extra repos that exist on disk, in insertion order.
 */
export declare function getEnabledExtraRepos(): Array<{
    alias: string;
    dir: string;
    url: string;
}>;
/** Create both the system and user directory trees if any subdirectories are missing. */
export declare function ensureAgentsDir(): void;
/** Return an empty Meta object used when no agents.yaml exists yet. */
export declare function createDefaultMeta(): Meta;
/**
 * Per-device machine-local version pins — `~/.agents/devices/<machine>/agents.yaml`.
 * Committed and synced, but each machine only ever writes its OWN folder, so
 * pulls never conflict. `<machine>` = machineId() (Tailscale-aligned short name).
 */
export declare function getDeviceMetaPath(): string;
/**
 * Machine-local per-version resource tracking — `~/.agents/.history/version-resources.json`.
 * Gitignored (under .history/) and regenerable; never synced.
 */
export declare function getVersionResourcesPath(): string;
export declare function withMetaLock<T>(fn: () => T): T;
/**
 * Commit the central `agents.yaml` in the user repo, synchronously, so a CLI
 * config mutation never leaves the working tree dirty on that one shared-line
 * file at rest.
 *
 * Why this exists: CLI config commands rewrite the fleet-shared central
 * agents.yaml as a plain file write. Left uncommitted, the tree is dirty on
 * agents.yaml between the write and the daemon's next 15-min publish tick — and
 * a peer's incoming publish commit (which also touches agents.yaml) then trips
 * `dirtyTreeRefusal` ("incoming changes touch uncommitted paths: agents.yaml"),
 * wedging `agents repo pull` fleet-wide (PHNX-3968). Committing the central edit
 * in the same command that made it closes that window: agents.yaml is clean at
 * rest, so nothing incoming can collide with it. Called AFTER the meta lock
 * releases (see {@link commitCentralConfigAfterWrite}) so the git subprocesses
 * never run inside the short, non-heartbeated lockfile window; the user repo
 * already pushes.
 *
 * Scoped tightly: only called when the central bytes actually changed, and never
 * from the daemon (see {@link isDaemonProcess}). A commit failure fails open —
 * a concurrent daemon holding `index.lock`, a mid-rebase repo — leaving
 * agents.yaml dirty; the next successful central write commits it, and until
 * then a pull that would collide refuses rather than losing data. A config
 * command must never fail because git hiccuped.
 *
 * Returns whether a commit was created. Exported for the real-repo tests.
 */
export declare function commitCentralConfig(userDir: string): boolean;
/**
 * True when the top-level `~/.agents/agents.yaml` carries a metadata header that
 * is NOT the canonical {@link META_HEADER} — the P1 frozen-header case a box only
 * heals on its next central write (serializeCentral). An absent or headerless
 * file is NOT stale (a headerless central file is deliberately left alone).
 * Surfaced as config drift by `agents sync status` (PHNX-3315).
 */
export declare function hasStaleMetaHeader(): boolean;
/**
 * Parse the top-level user `agents.yaml` (this box's synced central file) WITHOUT
 * the system-repo merge, machine-local overlay, or cache — the raw on-disk central
 * map, or null when the file is absent/unparseable. Used by config-drift detection
 * to see the central blocks that should have folded into the device doc, without
 * mis-attributing a system-repo default as this box's own leak (PHNX-3315).
 */
export declare function readTopLevelUserMeta(): Record<string, unknown> | null;
/**
 * Write `meta` to disk (central + device docs + pins) WITHOUT taking the meta
 * lock — the caller must already hold it via {@link withMetaLock}. Exported so a
 * writer that needs to read fresh state, decide, and commit within a SINGLE lock
 * acquisition (e.g. browser tombstone eviction) can do so without the
 * read-snapshot-then-separately-lock race that {@link updateMeta} would impose.
 *
 * Returns whether the central `agents.yaml` bytes actually changed, so the
 * caller can commit it once — {@link commitCentralConfig} — AFTER releasing the
 * meta lock (the git subprocesses must not run inside the short, non-heartbeated
 * lockfile window). This function never commits.
 */
export declare function writeMetaUnlocked(meta: Meta): boolean;
/**
 * Read and cache ~/.agents/agents.yaml, migrating from legacy locations if needed.
 *
 * Cache invariants:
 * - Cache key is the mtime of the user agents.yaml.
 * - `writeMetaUnlocked` clears the cache; in-process callers always see fresh state.
 * - If the file is mutated by ANOTHER process while we hold a stale cache, the
 *   mtime check below catches it on the next read (assuming the mtime advanced).
 * - The cache stores the merged system+user meta; both files' mtimes contribute.
 */
export declare function readMeta(): Meta;
/** Serialize and write agents.yaml to the user repo, invalidating the in-memory cache. */
export declare function writeMeta(meta: Meta): void;
/** Update agents.yaml under lock and return the new state. */
export declare function updateMeta(updates: Partial<Meta> | ((meta: Meta) => Meta)): Meta;
/**
 * Commit-on-write, invoked AFTER {@link withMetaLock} releases so the git
 * subprocesses never run inside the short, non-heartbeated meta-lock window.
 * A CLI command that actually moved the fleet-shared central agents.yaml commits
 * it so the tree is never left dirty on that file at rest — the window that
 * trips `dirtyTreeRefusal` and wedges pulls fleet-wide (PHNX-3968). Gated on a
 * real byte change and never run in the daemon, whose publish tick owns central
 * commits. See {@link commitCentralConfig}.
 */
export declare function commitCentralConfigAfterWrite(centralChanged: boolean): void;
/** Derive a filesystem-safe local clone path for a package source URL. */
export declare function getPackageLocalPath(source: string): string;
import type { AgentId, ResourceType, VersionResources, ResourcePattern } from './types.js';
/**
 * @deprecated No-op. Use ensureVersionResourcePatterns instead.
 * Kept for backward compat with command files that still call it.
 */
export declare function recordVersionResources(_agent: AgentId, _version: string, _resourceType: ResourceType, _resources: string[]): void;
/**
 * Write default resource selection patterns for an agent@version.
 * Only writes each field when it is not already set, preserving user customization.
 * Pass all resource types you want to initialize in one call to batch the write.
 */
export declare function ensureVersionResourcePatterns(agent: AgentId, version: string, updates: Partial<Record<Exclude<keyof VersionResources, 'rulesPreset'>, ResourcePattern[]>>): void;
/**
 * Insert `<alias>:*` at the canonical position (after the system/user/other-extra
 * includes, before `project:*`), unless the alias is already referenced — as an
 * include (`alias:...`) or an exclude (`!alias:...`). Returns a new array when it
 * changes, otherwise the same reference (so callers can detect no-ops cheaply).
 */
export declare function withAlias(list: ResourcePattern[], alias: string): ResourcePattern[];
/** Strip every reference to `<alias>:...` / `!<alias>:...` from a selector list. */
export declare function withoutAlias(list: ResourcePattern[], alias: string): ResourcePattern[];
/**
 * Backfill (add=true) or strip (add=false) an extra-repo alias across every
 * already-installed version's selectors. New versions get the alias via
 * `defaultPatterns()` at scaffold time; this keeps existing versions in sync
 * when an extra repo is registered/enabled or removed. Only touches selector
 * lists that are already set — an unset list is left for `defaultPatterns()`.
 * Returns the number of (agent, version) pairs changed.
 */
export declare function applyExtraAliasToVersions(alias: string, add: boolean): number;
export declare function getVersionResources(agent: AgentId, version: string): VersionResources | null;
/** Active rules preset for an agent@version. Defaults to "default" when unset. */
export declare function getActiveRulesPreset(agent: AgentId, version: string): string;
/** Persist the active rules preset for an agent@version. */
export declare function setActiveRulesPreset(agent: AgentId, version: string, preset: string): void;
