import { type SkPublishManifest } from "@skaile/workspaces/core/publish-manifest"; import * as z from "zod"; /** * Semver regex matching `MAJOR.MINOR.PATCH` with optional `-` and * `+` segments. Author-shipped inventory entries must declare a version * that matches this regex. * * @docLink packages/discovery/concepts#author-manifest-semver */ export declare const SEMVER_RE: RegExp; declare const PublisherOverrideSchema: z.ZodObject<{ path: z.ZodString; publisher: z.ZodString; }, z.core.$strip>; declare const SyncConfigSchema: z.ZodObject<{ trigger: z.ZodDefault>; poll_interval: z.ZodOptional; }, z.core.$strip>; /** * Single entry in the author-shipped inventory (the `assets:` block of a * `version: 2` source config — adapted from `skaile.manifest.yaml` via * {@link manifestToSourceConfig}). * * When the `assets:` block is present, discovery uses these entries as the * source of truth (`discoverFromManifest`) instead of running glob walk + * publisher resolution. * * @docLink packages/discovery/concepts#author-manifest-asset-entry */ declare const AssetEntrySchema: z.ZodObject<{ path: z.ZodString; root: z.ZodOptional; kind: z.ZodString; publisher: z.ZodString; name: z.ZodString; version: z.ZodString; sha256: z.ZodOptional; files: z.ZodOptional>; requires: z.ZodDefault>; metadata: z.ZodOptional>; }, z.core.$strip>; /** * Root schema for discovery's **internal** source config — the IR the pipeline * consumes. On disk a repo declares its inventory in `skaile.manifest.yaml`, * which {@link manifestToSourceConfig} adapts into this shape; the raw schema is * also accepted directly (tests, programmatic callers). * * Declares how a repo maps to Catalog publisher namespaces. * Template variable `` in publisher_default is replaced at discovery * time with the first-level directory name containing the asset. * * Schema version `1` is the original glob-discovery surface. Version `2` * extends the schema with an optional `assets:` block — when present, * discovery uses the author-shipped inventory as authoritative and skips * glob walk + publisher resolution + AI enrichment. * * @docLink packages/discovery/concepts#source-config-schema */ export declare const SourceConfigSchema: z.ZodObject<{ version: z.ZodUnion, z.ZodLiteral<2>]>; publisher_default: z.ZodString; default_ref: z.ZodDefault; publisher_overrides: z.ZodDefault>>; dev_paths: z.ZodDefault>; sync: z.ZodOptional>; poll_interval: z.ZodOptional; }, z.core.$strip>>; assets: z.ZodOptional; kind: z.ZodString; publisher: z.ZodString; name: z.ZodString; version: z.ZodString; sha256: z.ZodOptional; files: z.ZodOptional>; requires: z.ZodDefault>; metadata: z.ZodOptional>; }, z.core.$strip>>>; }, z.core.$strip>; /** * Validated internal source config (adapted from `skaile.manifest.yaml`). * * @docLink packages/discovery/concepts#source-config */ export type SourceConfig = z.infer; /** * A `SourceConfig` known to be `version: 2` with the `assets:` block populated. * Returned from {@link isManifestMode} after a successful narrow. * * @docLink packages/discovery/concepts#source-config-v2 */ export type SourceConfigV2 = SourceConfig & { version: 2; assets: AssetEntry[]; }; /** * A single entry in the author-shipped inventory. * * @docLink packages/discovery/concepts#author-manifest-asset-entry */ export type AssetEntry = z.infer; /** * A single per-path publisher namespace override entry. * * The first matching override (by path prefix) wins during publisher resolution. * * @docLink packages/discovery/concepts#publisher-override */ export type PublisherOverride = z.infer; /** * Sync configuration that controls how the catalog backend learns about repo changes. * * @docLink packages/discovery/concepts#sync-config */ export type SyncConfig = z.infer; /** * Successful result from {@link validateSourceConfig} or {@link loadSourceConfig}. * * `warnings` lists non-fatal anomalies (e.g. `assets:` present alongside * `publisher_overrides:` — the latter is ignored in manifest mode). * * @docLink packages/discovery/concepts#validation-success */ export interface ValidationSuccess { ok: true; config: SourceConfig; warnings?: string[]; } /** * Failed result from {@link validateSourceConfig} or {@link loadSourceConfig}, * carrying a list of per-field validation errors. * * @docLink packages/discovery/concepts#validation-failure */ export interface ValidationFailure { ok: false; errors: Array<{ path: string; message: string; }>; } /** * Discriminated union returned by {@link validateSourceConfig} and {@link loadSourceConfig}. * * Use `result.ok` to narrow to {@link ValidationSuccess} or {@link ValidationFailure}. * * @docLink packages/discovery/concepts#validation-result */ export type ValidationResult = ValidationSuccess | ValidationFailure; /** * Parse raw YAML text into a plain object. * * Throws if the YAML is syntactically invalid. Pass the result to * {@link validateSourceConfig} to apply schema validation. * * @param yamlText - Raw YAML content of an internal source config * @returns The parsed object (unvalidated) * @docLink packages/discovery/concepts#parse-source-config */ export declare function parseSourceConfig(yamlText: string): unknown; /** * Validate a parsed object against the {@link SourceConfigSchema}. * * @param parsed - Plain object produced by {@link parseSourceConfig} or any other YAML parser * @returns A {@link ValidationSuccess} with the typed config, or a {@link ValidationFailure} with field errors * @docLink packages/discovery/concepts#validate-source-config */ export declare function validateSourceConfig(parsed: unknown): ValidationResult; /** * Convenience wrapper that parses YAML and validates in a single call. * * Equivalent to calling {@link parseSourceConfig} followed by {@link validateSourceConfig}. * * @param yamlText - Raw YAML content of an internal source config * @returns A {@link ValidationResult} (success or failure) * @docLink packages/discovery/concepts#load-source-config */ export declare function loadSourceConfig(yamlText: string): ValidationResult; /** * Narrow a {@link SourceConfig} to {@link SourceConfigV2} when it carries an * author-shipped inventory. * * @param config - Validated source config * @returns `true` when `version === 2` and `assets:` is present (and non-empty * array — empty arrays still trigger manifest mode and yield an empty * discovery result, which matches an empty repo). * @docLink packages/discovery/concepts#is-manifest-mode */ export declare function isManifestMode(config: SourceConfig): config is SourceConfigV2; /** * Test whether a repo-relative path falls under one of the configured * `dev_paths` prefixes. * * Matching is whole-segment: a `dev_paths` entry of `ai-assets-dev` matches * `ai-assets-dev` itself and anything under `ai-assets-dev/…`, but not a * sibling like `ai-assets-development`. Trailing slashes on either side are * normalized away. * * @param relativePath - Path relative to the source root (POSIX separators) * @param devPaths - The `dev_paths` list from a {@link SourceConfig} * @returns `true` when discovery should exclude the path in a normal run * @docLink packages/discovery/concepts#dev-paths */ export declare function isExcludedDevPath(relativePath: string, devPaths: readonly string[]): boolean; /** * Strip a single leading `@` scope sigil from a publisher namespace. * * The internal {@link SourceConfig} carries `@`-prefixed publishers * (`publisher_default`, `publisher_overrides[].publisher`) — that is correct at * the config layer. But `DiscoveredAsset.publisher` (and every downstream ref) * must be **bare** (`core/src/ref.ts`: "publisher never carries a leading `@`"); * the scope sigil is re-added by the ref formatter. Emitting `@acme` here yields * `@@acme` in display and un-addable refs. Shared by both discovery entry points * (`discover.ts` glob walk and `tree-entries.ts` virtual tree). */ export declare function barePublisher(publisher: string): string; /** * Adapt a decoded `skaile.manifest.yaml` ({@link SkPublishManifest}) into the * internal {@link SourceConfig} the discovery pipeline consumes. * * - An inventory (`assets:`) maps to a `version: 2` manifest-mode config, one * {@link AssetEntry} per manifest asset (publisher/version inherited from the * repo-level manifest when the entry omits them; `dependencies` → `requires`; * store-listing fields → `metadata`). * - No inventory maps to a `version: 1` glob-mode config carrying the derived * `publisher_default` (`@` when declared, else `@`). * * The manifest carries no `publisher_default` template / `publisher_overrides` / * `sync` — those were `.skaile-source.yaml`-only and are synthesised/defaulted. * * @docLink packages/discovery/concepts#manifest-to-source-config */ export declare function manifestToSourceConfig(manifest: SkPublishManifest): SourceConfig; /** * Decode `skaile.manifest.yaml` text and adapt it to an internal * {@link SourceConfig}. Fatal decode diagnostics (YAML syntax / non-object * root) surface as a {@link ValidationFailure}; otherwise an adapted * {@link SourceConfig} is returned. * * @docLink packages/discovery/concepts#decode-manifest-source-config */ export declare function decodeManifestSourceConfig(text: string): ValidationResult; /** * Read `/skaile.manifest.yaml` (if present) and adapt it to a * {@link SourceConfig}. Returns `undefined` when the file is absent or * unparseable — the same tolerant contract the glob path expects. * * @docLink packages/discovery/concepts#read-manifest-source-config */ export declare function readManifestSourceConfig(dir: string): SourceConfig | undefined; /** * A {@link SourceConfig} produced by merging a base in-repo config with a * local sidecar overlay. Always shaped like a regular `SourceConfig` — * downstream consumers treat it identically. * * @docLink packages/discovery/concepts#merged-source-config */ export type MergedSourceConfig = SourceConfig; /** * Merge a base in-repo source config with a local sidecar overlay (both * adapted from their respective `skaile.manifest.yaml`). * * Merge rules (per PR-3 §D.3): * * | Field | Resolution | * |-----------------------|-----------------------------------------------------| * | `version` | sidecar wins (sidecar is always v2) | * | `publisher_default` | sidecar wins if set, else base | * | `publisher_overrides` | sidecar wins if non-empty, else base | * | `default_ref` | sidecar wins if set, else base | * | `sync` | sidecar wins if set, else base | * | `assets:` | sidecar fully **replaces** base (no partial merge) | * * Pure function — no I/O. Callers responsible for loading both configs. * * @param base - The in-repo source config (or `undefined` if absent) * @param overlay - The sidecar source config (or `undefined` for identity) * @returns The merged config, or `undefined` if both inputs are missing * @docLink packages/discovery/concepts#merge-source-configs */ export declare function mergeSourceConfigs(base: SourceConfig | undefined, overlay: SourceConfig | undefined): MergedSourceConfig | undefined; /** * Load and merge a base `skaile.manifest.yaml` (at `/skaile.manifest.yaml`) * with an optional sidecar manifest at `/skaile.manifest.yaml`. * * Either side may be absent. The result is wrapped in a {@link ValidationResult} * so the discovery dispatcher can surface per-side parse errors uniformly. * * Field merge follows {@link mergeSourceConfigs}. The sidecar's * `skaile.manifest.yaml` is the only sidecar artifact this helper touches; the * README + lock file under `` are consumer concerns. * * @param rootPath - Absolute path to the upstream repo root * @param sidecarPath - Optional absolute path to the sidecar directory * (e.g. `~/.skaile/sources//`) * @returns A {@link ValidationResult} carrying the merged config. Returns * `{ ok: true, config: }` when at least one side parses; returns * `{ ok: false, errors: [...] }` only when a present file is structurally * invalid. Missing files on both sides yield a typed success with an * empty/default v2 config. * @docLink packages/discovery/concepts#load-merged-source-config */ export declare function loadMergedSourceConfig(rootPath: string, sidecarPath?: string): ValidationResult; /** * File-based twin of {@link loadMergedSourceConfig}: merge the base * `/skaile.manifest.yaml` with an overlay read from an EXPLICIT file * path rather than a `/skaile.manifest.yaml` convention. * * The local store keeps curated overlays as a flat `.yaml` (not a * `/skaile.manifest.yaml`), so `source add`/`sync` route through this * variant, pointing `overlayManifestFile` straight at * `~/.skaile/store/manifests/.yaml`. * * @param rootPath - Absolute path to the upstream repo root * @param overlayManifestFile - Optional absolute path to the overlay manifest file * @returns Same {@link ValidationResult} contract as {@link loadMergedSourceConfig} * @docLink packages/discovery/concepts#load-merged-source-config */ export declare function loadMergedSourceConfigFromFile(rootPath: string, overlayManifestFile?: string): ValidationResult; export {}; //# sourceMappingURL=source-config.d.ts.map