import type { TreeChangeBatch, TreeChangeKind } from "../watcher.js"; export type WatchRoute = { kind: "company"; slug: string; } | { kind: "personal"; }; /** * The sync target selected for a watcher run. Watcher events must be rejected * at ingress when they cannot belong to this target; deferring this decision * until the pass planner would still queue a needless guarded pass. */ export interface WatchRouteSelection { companies: boolean; company: boolean; /** * The company this run was scoped to by `--company `, carried from the * launch argv. A single-company run owns exactly one tenant, so every other * routed slug is rejected here — at watcher ingress, before any pass is * queued and therefore before any namespace resolution can turn the foreign * slug into a syncable company. */ companySlug?: string; personal: boolean; skipPersonal: boolean; } /** * Route a changed relative path to the push target that owns it. * * - `companies//...` -> a single-company route for ``. * - `companies/_template/...` -> ignored (release-owned scaffold). * - anything else under hqRoot -> the personal route. */ export declare function routeChangeToTarget(relPath: string, kind?: TreeChangeKind): WatchRoute | null; /** * Whether a routed watcher change belongs to the command's selected sync * target. This is deliberately evaluated before watcher work is queued, so a * disabled personal scope cannot create a pass or event-sync publication. * * A `--company ` run is scoped to exactly ONE tenant. It used to accept * any company route, so a watcher or receiver event under another tenant's * directory built a targeted `--company ` pass, and the runner's * caller-namespace lookup resolved that slug and synced a company the operator * never selected. The routed slug is therefore compared against the selected * one here, before the route can reach any resolution. A run that carried no * slug fails closed: its cadence pass still syncs the selected target, but * event ingress refuses to guess which tenant it owns. */ export declare function isWatchRouteSelected(route: WatchRoute, selection: WatchRouteSelection): boolean; /** * Build the argv for a targeted push pass from a routed change. */ export declare function buildTargetedPushArgv(route: WatchRoute, baseArgv: string[]): string[]; export declare function buildScopedPushArgv(route: WatchRoute, relPaths: readonly string[], baseArgv: string[], deleteScopeRoots?: readonly string[]): string[]; export declare function buildFullFanoutPushArgv(baseArgv: string[]): string[]; export declare function buildScopedDrainPullArgv(baseArgv: string[]): string[]; /** * Build the argv for a whole-route pull pass (no path scoping). Unlike * `buildTargetedPullArgv` called WITHOUT paths, the personal route maps to * `--personal` rather than a full `--companies` fanout — used by the overflow * drain, whose whole point is to avoid collapsing to every company. */ export declare function buildRoutePullArgv(route: WatchRoute, baseArgv: string[]): string[]; /** * Build the argv for a targeted pull pass from a routed change. * * When `relPaths` (hqRoot-relative changed paths) are provided, each one that * belongs to the route is forwarded as a `--scope-path` so the pull leg lists * and plans ONLY those subtrees (SyncOptions.pullPrefixes) instead of the * route's whole vault — the pull-side counterpart of `buildScopedPushArgv`. * Deletion detection and scope-shrink stay safe by the engine's pullPrefixes * contract (the sweep only trusts the listed scope; shrink keeps the durable * scope). */ export declare function buildTargetedPullArgv(route: WatchRoute, baseArgv: string[], relPaths?: readonly string[]): string[]; export declare function routeKey(route: WatchRoute): string; export declare function routesForBatch(batch: TreeChangeBatch): Map; //# sourceMappingURL=sync-runner-watch-routes.d.ts.map