/** * Asset discovery over a virtual file tree (no real filesystem access). * * `discoverAssetsInTreeEntries()` is the server-side counterpart to * `discoverAssetsInTree()` — same kind resolution, manifest parsing, * publisher/name derivation, requires extraction, and SHA256 hashing — but * driven by a flat list of {@link TreeEntry} (the shape returned by GitHub's * Git Trees API: `GET /repos/:owner/:repo/git/trees/:tree_sha?recursive=1`). * * Used by the public Catalog backend (`@postxl/skaile-store-api`) so that * Source ingestion never touches the local filesystem and never runs * `git clone` (per spec § Phase 2: "no client-side cloning, ever"). * * The function is async because manifest parsing and content hashing both * require fetching blob bytes from the remote host (e.g. GitHub Blobs API). * * Per-kind file-filter logic is mirrored from `builtin-providers.ts` — the * provider implementations there read `fs.readdirSync` / `fs.existsSync`, * which doesn't translate to a virtual tree, so this module reimplements * the same patterns against the supplied {@link TreeEntry} list. The * resulting `fileFilter.files` set is identical to what * `discoverAssetsInTree()` would produce for the same content laid out on * disk. * * @module */ import type { IAssetKindRegistry } from "@skaile/workspaces/plugins"; import type { AtomizationPolicy, DiscoveryResult } from "./discover.js"; import type { SourceConfig } from "./source-config.js"; /** * A single entry in a virtual file tree (the shape returned by GitHub's * Git Trees API). * * Only the four fields used by discovery are required; consumers may pass * Octokit's full `GitTreeResponse[]` directly because TypeScript structural * typing accepts the superset. * * @docLink packages/discovery/concepts#tree-entry */ export interface TreeEntry { /** Repo-relative path (forward slashes), e.g. `domain/skills/review/SKILL.md`. */ path: string; /** `"blob"` for files, `"tree"` for directories, `"commit"` for submodules. */ type: "blob" | "tree" | "commit" | string; /** Git object SHA used to fetch blob contents via {@link DiscoverAssetsInTreeEntriesOptions.fetchBlob}. */ sha: string; /** Optional file mode (`"100644"` etc.). When `"100755"`, indicates an executable. */ mode?: string; /** Optional blob size in bytes. */ size?: number; } /** * Options for {@link discoverAssetsInTreeEntries}. * * @docLink packages/discovery/concepts#discover-assets-in-tree-entries-options */ export interface DiscoverAssetsInTreeEntriesOptions { /** * Async resolver that returns the bytes of a blob given its Git SHA. * * The store backend wires this to Octokit's * `repos.getContent` / `git.getBlob` API; tests can pass a synchronous * map-backed implementation. Returning `null` is treated identically to a * fetch error (the file is skipped during hashing). */ fetchBlob: (sha: string) => Promise; /** Optional source config (adapted from `skaile.manifest.yaml`). */ sourceConfig?: SourceConfig; /** * Optional sidecar overlay config (loaded out-of-band from * `~/.skaile/sources//skaile.manifest.yaml`). When provided, the * `sourceConfig` resolved from the tree (or passed explicitly) is merged * with this overlay via {@link mergeSourceConfigs} before dispatch. * * @docLink packages/discovery/concepts#sidecar-overlay */ sidecarSourceConfig?: SourceConfig; /** * Explicit `DOMAIN.md` descriptors (repo-relative path + raw content), * fetched out-of-band from a sidecar repo. When provided, these are the * authoritative domain source and the in-tree `DOMAIN.md` scan is skipped. * Paths resolve against the upstream tree. * * @docLink packages/discovery/concepts#domains */ domainFiles?: Array<{ path: string; content: string; }>; /** Optional kind registry. Defaults to {@link createDefaultRegistry}. */ registry?: IAssetKindRegistry; /** * Atomization policy. Defaults to {@link DEFAULT_ATOMIZATION_POLICY}. * `closure` / `full-dir` are honored on the virtual tree at full parity with * the local-FS path (text blobs are fetched on demand to resolve references). * * @docLink packages/discovery/concepts#atomization */ atomization?: AtomizationPolicy; /** * Include assets under the source config's `dev_paths` prefixes. Defaults to * `false`. Mirrors the local-FS {@link discoverAssetsInTree} option. * * @docLink packages/discovery/concepts#dev-paths */ includeDev?: boolean; } /** * Discover assets in a virtual tree (Octokit `TreeEntry[]`). * * Mirrors {@link discoverAssetsInTree} but operates on a remote tree * snapshot — no `node:fs` access. Manifest content and per-asset file * bytes are fetched on demand via `options.fetchBlob`. * * @param entries - Flat list of tree entries (paths + blob SHAs). Tree * entries with `type: "tree"` are ignored (directories are reconstructed * from blob paths). * @param options - Blob fetcher + optional source config and registry. * @returns A {@link DiscoveryResult} identical in shape to * {@link discoverAssetsInTree}'s output, including `assets`, `graph`, * and `errors`. * @docLink packages/discovery/concepts#discover-assets-in-tree-entries */ export declare function discoverAssetsInTreeEntries(entries: TreeEntry[], options: DiscoverAssetsInTreeEntriesOptions): Promise; //# sourceMappingURL=tree-entries.d.ts.map