/** * Domains — navigational grouping of assets, declared by `DOMAIN.md` files * supplied by a sidecar (never the upstream repo). * * Pure logic only — zero I/O. A `DOMAIN.md` claims the directory it lives in * plus everything below it (whole-segment containment). Domains are strictly * non-nested, so every asset has at most one claiming domain. The slug is * display-only metadata: it never participates in asset identity * (`/@`) or the flat install layout. * * @module */ /** How members of a domain relate to one another (navigational hint, never install-all). */ export type DomainRelation = "additions" | "alternatives" | "sequence"; /** A single member-overlay entry from a `DOMAIN.md` `members:` list. */ export interface DomainMember { /** Canonical or bare asset ref the entry refers to. */ ref: string; /** Display order within the domain (required for `sequence`). */ order?: number; /** Marks the default pick within an `alternatives` domain. Never auto-installed. */ recommended?: boolean; } /** * A parsed `DOMAIN.md` descriptor. `domainRoot` is the repo-relative directory * the file lives in (its claimed subtree root); `''` means the repo root. */ export interface DomainMd { /** `dirname` of the DOMAIN.md path; `''` = repo root (claims the whole repo). */ domainRoot: string; slug: string; title: string; description: string; relation: DomainRelation; order?: number; members?: DomainMember[]; } /** A resolved domain plus its ordered member set, ready for display/persistence. */ export interface DomainIndexEntry { slug: string; title: string; description: string; relation: DomainRelation; order?: number; /** Asset refs in this domain, ordered by member `order` then discovery order. */ members: string[]; /** Asset refs flagged `recommended` by the member overlay. */ recommended: string[]; } /** Hard validation errors. Any of these fails the sidecar build (proposal §4). */ export type DomainValidationError = { code: "DomainNesting"; outer: string; inner: string; } | { code: "DuplicateDomainSlug"; slug: string; roots: string[]; } | { code: "InvalidRelation"; root: string; value: string; } | { code: "InvalidSlug"; root: string; value: string; }; /** Minimal asset shape the domain resolver needs (a `DiscoveredAsset` satisfies it). */ export interface DomainAssignable { ref: string; relativePath: string; } /** The filename that marks a domain descriptor. */ export declare const DOMAIN_MD_FILENAME = "DOMAIN.md"; /** True when a repo-relative path is a `DOMAIN.md` descriptor file. */ export declare function isDomainMdPath(relativePath: string): boolean; /** * Build a {@link DomainMd} from a `DOMAIN.md` path and its parsed frontmatter. * * Tolerant: missing/invalid fields are carried through as-is so * {@link validateDomains} can report them as hard errors rather than throwing. * `title` falls back to `slug`; `description` to the empty string; * `relation` to `additions`. * * @param domainMdPath - repo-relative path to the `DOMAIN.md` file * @param frontmatter - parsed YAML frontmatter object */ export declare function parseDomainMd(domainMdPath: string, frontmatter: Record): DomainMd; /** * Validate a set of `DOMAIN.md` descriptors. Returns the list of hard errors; * an empty list means the set is valid. Never throws. * * Checks (proposal §4): * - `InvalidSlug` — slug missing or not GitHub-shaped (≤39, `[a-z0-9-]`). * - `InvalidRelation` — relation not one of additions|alternatives|sequence. * - `DuplicateDomainSlug` — same slug on ≥2 domains. * - `DomainNesting` — one domain's root is inside another's claimed subtree. */ export declare function validateDomains(domains: readonly DomainMd[]): DomainValidationError[]; /** * Assign an asset (by its repo-relative manifest path) to a domain slug, or * `null` when no domain claims it. Assumes {@link validateDomains} passed, so * at most one domain claims any path; when several match (defensive, e.g. * validation skipped) the deepest root wins. */ export declare function assignDomain(relativePath: string, domains: readonly DomainMd[]): string | null; /** * Build the flat display index: every asset assigned to its domain, members * ordered by member `order` (asc) then discovery order, plus the `unclaimed` * list. Assets are consumed in their given order (callers pass discovery * order) so the output is deterministic. * * Member overlay semantics: a `members[]` entry only reorders / flags assets * already in the claimed subtree. A member ref outside the subtree is ignored * in v1 (warnings deferred). */ export declare function buildDomainIndex(assets: readonly DomainAssignable[], domains: readonly DomainMd[]): { index: Record; unclaimed: string[]; }; /** Render a {@link DomainValidationError} as a `{ path, error }` discovery error. */ export declare function describeDomainError(e: DomainValidationError): { path: string; error: string; }; /** * Apply a set of parsed `DOMAIN.md` descriptors to a discovered asset set: * validate, stamp each asset's `domainSlug` in place, and return the ordered * domain index plus any hard validation errors (as discovery `{ path, error }`). * * Hard errors are reported but never abort the run — invalid domains are simply * not assigned (proposal §4: surface, don't crash). The returned `domains` are * sorted by `order` (asc) then slug for stable display. */ export declare function applyDomains(assets: Array, domains: readonly DomainMd[]): { domains: DomainIndexEntry[]; errors: Array<{ path: string; error: string; }>; }; //# sourceMappingURL=domains.d.ts.map